We have tinkered with Ember and Express.js previously, but Meteor comes out of the box with live updates, which means that changes to data will automatically be pushed to other users or devices displaying that data, eliminating the need to reload the page to see any updates. Many of the use cases we can think of for a web or mobile app require this feature, and going with Meteor means that we don't have to use an external service such as Firebase to provide this.
We have built small Meteor apps before, but we wanted to try something more demanding in order to get a better understanding of how Meteor scales to a larger app. We decided on a long-overdue revamp of our customer management system which was originally hacked together over a couple of days using Podio. Over time it has mutated into something really ugly with important information stored in several different locations, so it was definitely a worthwhile effort. It also had about the right size and complexity for the time we had available.
Meteor is based on MongoDB, a document-oriented database. Given that customer data is highly structured and relational, we first had to consider if MongoDB was an acceptable choice (there are some good arguments against).
At the end of the day it became a tradeoff: We wanted the on-screen live updates more than we disliked having to deal with a de-normalized database. The alternatives meant either using MySQL as an unsupported Meteor backend, or using MySQL with something other than Meteor, none of which held much appeal.
MongoDB is by nature schema-less, but we did want to impose some structure on the database for server-side validation purposes. We ended up using two Meteor packages that allow us to connect a schema definition to a Mongodb collection, SimpleSchema and Collection2. These packages are well supported, widely used and have worked well for us in this project.
We considered hosting the Mongo database ourselves, but ended up using compose.io to avoid spending time on configuring replica sets and such. We chose Digital Ocean's London data center for the database location, and we deployed the app to a droplet in the same data center to minimize latency between server and database.
Blaze Templating Engine
Meteor comes with its own templating engine called Blaze and a templating language called spacebars, a variation on Handlebars. This seemed a good choice initially - it is officially supported, and many third-party Meteor packages assume that this is what you do, and so play nicely with Blaze.
We knew already that our app would have a large number of tables and forms for displaying and editing customer data, and going with Blaze meant that we could use two popular third-party packages, Reactive Table for tables and AutoForm for forms. The latter was of particular interest, since it promised almost automatic insert and update form generation based on the database schema definition.
We also found that working with Blaze and Spacebars wasn't ideal for a larger app. Meteor and Blaze don't enforce or support any particular way to structure your code, which is nice when you are prototyping but can lead to a mess on larger projects. We also found ourselves writing more jQuery than we really felt comfortable with, considering that we will have to support it for at least a couple of years.
Angular is based on the MVC paradigm, where code in a controller lets you create bindings between a data model and a view. Angular provides two-way bindings between model and view, so if the model changes the view is updated, and if data in the view is updated then the underlying model is also updated. This becomes a three-way binding if Meteor is then used to provide a reactive connection between model and database.
Angular has a steep learning curve, and front-end developers tend to either love it or hate it. We happen to like Angular - it is extremely powerful, and we find the resulting markup and code much easier to read and understand than similar Blaze markup and code. Meteor integration is currently supported through a third-party package, but it is scheduled for official support in the upcoming Meteor 1.2 release.
Using Angular with Meteor means that there are fewer third-party packages to choose between since many of these include Blaze templates. On the flip side there are many third-party Angular modules that will also work with Meteor, and most of the packages we wanted to use for this project did not have a template component anyway. (We did want to use the accounts-ui package, but implementing the authentication user interface compoments in Angular turned out to be fairly easy).
We have used the AngularUI router as recommended in the Angular-Meteor documentation. It comes with a warning that it is under active development and the API should be considered unstable, but this far it has been a pleasure to work with because of its great flexibility. There is an addon package that allows you to use ui-router with Blaze templates if you need to use a third-party package that assumes you are using Blaze.
Experiences and Recommendations
All told it took us just under five weeks to implement our new customer management system, with one person working full time and a second person putting in 1-2 weeks worth of effort. We plan to add more features and do a bit of polishing but it is already better than what we had by several orders of magnitude.
In fact, getting a Meteor web app ready that met almost all our requirements took less than a week, using Blaze and the Reactive Table and AutoForm packages mentioned above. The rest of the time has been spent migrating to Angular and refactoring the app multiple times to get it to work just the way we wanted it. But in reality we could have stopped after the first week and still had a workable solution.
If you are new to both Meteor and Angular, our recommendation would be to stick with Blaze initially and see how far you can take it - it may be all you need. On the other hand, if you already know Meteor or Angular well, try using them together.
We think you will like the combination.