I’ve been working with Meteor for a while now, and have even written a series of posts on this blog about using Meteor. I think Meteor generally approaches the architecture of reactive web applications in a very sensible way.

Through lots of discussion, I’ve found that people are generally opposed to using Meteor for any sort of professional or production work for a number of reasons. Of course, Meteor is a tool…just like every other framework. It solves a specific set of problems, and only if you have those problems should you consider using Meteor. However, I’ve noticed that most of the people I’ve talked to have decided not to use Meteor for reasons that aren’t really related to Meteor’s usefulness as a tool. In addition to that, I’ve also noticed that there are three specific concerns that are very common:

Meteor is insecure MongoDB is the only DB Meteor supports Meteor encourages monoliths

These are valid concerns! Security and appropriate datastore selection are really important when evaluating the legitimacy of any framework. But, let’s spend some time looking at Meteor more closely in regards to these concerns. Meteor has a little more to offer than what you might find in the comments of Meteor’s Hacker News debut post.

1. “Meteor is insecure”

Security! Incredibly and increasingly important when evaluating a framework. Meteor has a reputation for neglecting to provide security-related tools. This reputation is unfortunate because it is untrue, but the misunderstanding is completely reasonable.

Insecure by default… ?!

Meteor ships with packages called insecure and autopublish . These packages grant all clients the right to access and take any actions on any data. Why is this useful? Rapid prototyping. I’d actually rather these packages be opt-in instead of opt-out, but I do see value in addressing security concerns later on in the development process.

These packages should be removed before an application is publicized in any way:

meteor remove insecure && meteor remove autopublish 1 meteor remove insecure && meteor remove autopublish

I am a fan of shipping Meteor WITHOUT these defaults, but either way, Meteor includes some very solid tools that make it easy to lock down your data.

Allow / deny functions

Each collection object within Meteor has allow() and deny() functions that allow one to specify what a user can and cannot do with data within a collection.

Examples.allow({ // Users can insert Examples if they are authenticated. insert: function (userId, example) { if (userId) { return true; } return false }, // Users can update Examples if they created the example. update: function (userId, example) { if (userId === example.authorId) { return true; } return false; }, // Users can remove Examples if they created the example. remove: function (userId, example) { if (userId === example.authorId) { return true; } return false; } }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 Examples . allow ( { // Users can insert Examples if they are authenticated. insert : function ( userId , example ) { if ( userId ) { return true ; } return false } , // Users can update Examples if they created the example. update : function ( userId , example ) { if ( userId === example . authorId ) { return true ; } return false ; } , // Users can remove Examples if they created the example. remove : function ( userId , example ) { if ( userId === example . authorId ) { return true ; } return false ; } } ) ;

And deny() is simply an inverse of allow() :

Examples.deno({ // Users cannot insert Examples if they are authenticated. insert: function (userId, example) { if (!userId) { return true; } return false }, // Users cannot update Examples if they created the example. update: function (userId, example) { if (userId !== example.authorId) { return true; } return false; }, // Users cannot remove Examples if they created the example. remove: function (userId, example) { if (userId !== example.authorId) { return true; } return false; } }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 Examples . deno ( { // Users cannot insert Examples if they are authenticated. insert : function ( userId , example ) { if ( ! userId ) { return true ; } return false } , // Users cannot update Examples if they created the example. update : function ( userId , example ) { if ( userId !== example . authorId ) { return true ; } return false ; } , // Users cannot remove Examples if they created the example. remove : function ( userId , example ) { if ( userId !== example . authorId ) { return true ; } return false ; } } ) ;

These functions should be published to the server, and will send an error message to the client if a user is denied access to execute a certain action on a document.

Publications

Meteor clients subscribe to publications to get objects of data. You can control what data a user is allowed to access in these publication functions (defined on the server):

Meteor.publish('allExamples', function () { // Only return data if the user is authenticated. if (this.userId) { return Examples.find(); } }); 1 2 3 4 5 6 7 Meteor . publish ( 'allExamples' , function ( ) { // Only return data if the user is authenticated. if ( this . userId ) { return Examples . find ( ) ; } } ) ;

Content Security Policy

As of version 0.6.6, Meteor ships with a package called browser-policy , which is makes it easy to use Content Security Policy in Meteor.

Content Security Policy allows one to define actions that clients are allowed to take, such as what servers an app can connect to and whether or not inline scripts can be executed. This is another layer of security that mitigates cross site scripting and packet sniffing attacks.

2. “Meteor only supports MongoDB”

I’m not a huge MongoDB fan (a discussion for another day), and if Meteor exclusively supported MongoDB, that would be a problem for me. The good news is, the Meteor team is aware of these concerns, and is working towards having first-class support for more DBs. In fact there are some efforts around using other datastores such as redis, mysql, Postgres, Neo4j, and there’s even a project that aims to make it relatively painless to use Meteor with any database.

3. “Meteor encourages monoliths”

Meteor ships with a very well-baked package system that allows you to develop your application in a series of versioned modules. Of course, you are free to create a monolithic application if that’s your preference, but Meteor provides the tools necessary to create a very modular application.

As I mentioned before, Meteor is a tool that is good at solving a specific set of problems. If you’ve considered using Meteor in the past but rejected it due to security or modularity concerns, I hope this post sheds some light on the tools that Meteor provides to mitigate these pain-points. As far as datastore support is concerned, well, I look forward to seeing what the Meteor team cooks up. But for the time being, there are some good efforts towards expanding Meteor’s list of supported DBs.