Interesting enough, I found that Meteor is not production ready, in both current implementation (not mature) and some design decisions. I was thinking about writing blog post about it, but no idea when I'll have time to do it, so I decided to stop by.<p>I have experience with Meteor in production and had some serious performance-related problems. Not that they're not solvable, but some solutions kill some core design decisions of Meteor. Just in case - I didn't pick Meteor for the project, I was asked to help with it.<p>Anyway, here's short list:<p>1. Collection synchronization does not really work even for relatively small amounts of data (say 10k records).<p>- It does not make much sense to send few MB of initial data to the client. Paging API was moved to some distant future and you end up writing REST-like API on top of Meteor, which breaks idea of collection synchronization, which contradicts statement on their website - "no need to write REST APIs anymore". I don't say it is not usable at all, you just need to be really-really careful about what you send to client and it is easy to fail at this.<p>- SockJS (transport protocol used by Meteor) does not have rate-limiting built-in. If client connects using one of the polling transports and payload is too large to be received in 30 (? - vanilla SockJS uses 5) seconds, server drops connection thinking that client timed out. Partially, it is SockJS problem and partially it is Meteor problem, as Meteor will just send all outgoing data without caring if client is on slow connection. But because of previous point, generally it is bad idea to send large amount of data anyway.<p>- Server-side subscription API is very limited. Official documentation has following sample: reactively count number of admins in collection. This is done by listening on collection changes and counting admins by incrementing (when admin is added) and decrementing (when admin is removed) single variable. If there are 10k admins in database, increment function will be called 10k times.<p>2. Minimongo is interesting concept, but fails on many levels:<p>- It is MongoDB written in JS, but slow<p>- Does not have indexes ("client won't handle amounts of data for indexes to be viable"), aggregation, map reduce, etc. There's no official API to create index on server-side either.<p>- Its reactive - whenever model is changed, Meteor figures out which fields were changed and broadcasts changes to all listeners. And this is _not_ fast. Inserting 10k items to collection will take around 2 minutes on AWS large instance with node executable using 100% CPU.<p>- Because MongoDB is not "reactive", Meteor just polls collections every 5 seconds to see if they changed by outside application. I really hope it only tracks addition/deletion of records and not scanning through all rows in database during each polling iteration<p>- Meteor API is hiding MongoDB handle, but there's a way to get it (through hack) and use it directly. And it takes 3 seconds to insert same 10k items<p>3. Client-side is not as convenient as current MV* frameworks<p>- Meteor is using non-reactive templating engines and attempts to make them reactive. And this might be performance bottleneck, especially on mobile devices. When single variable changes, Meteor will re-render whole template. If you have some 3rd party plugins (like WYSIWYG editor, which injects own DOM markup), you have to wrap it with special blocks, which prevent Meteor from re-rendering them.<p>- As a result of previous point, DOM is not stable.<p>- Unlike AngularJS/Ember/etc, Meteor does not track individual variables. AngularJS does it by checking if variable changed in digest loop, Ember uses property-like system, etc. Meteor has global, flat namespace called "Meteor.session", where application stores _all_ reactive variables that can be referenced by their name. `Meteor.session.set('mymodule.hello', 10)`. It is hard to structure application, when core reactive part is just a singleton dictionary.<p>- Once you get used to bidirectional data binding between forms and models, it is hard to get away with events. But that's minor.<p>4. Overall architecture (nitpicking):<p>- Meteor API likes singletons. `Meteor.session`, `Meteor.methods`, `Meteor.templates`, etc. Single, flat namespaces everywhere<p>- Even though code can be written in a way it can run on both client and server, there are subtle core API differences. Like it is not possible to use `HTTP.get` on the client without callback, but it works on the server, just blocks the fiber. If you use callback on the server, you need to block the fiber manually (using future or fiber API), etc.<p>- No server-side templates. Yes, there's crawlable package for Meteor, but it is just PhantomJS (WebKit) that runs on the server and renders pages for crawlers. Yikes.<p>This pretty much sums my experience with Meteor.