10 tips to get off the Meteor

A disclaimer before we get into this, in no way do I think the Meteor framework is bad. What I do know is our ambitions of where we want to take our platform are growing faster than the framework’s offering every release. So when it comes to the use case we had when we started this, it’s completely different.

When your company evaluates technology don’t make the same mistake we did. Lock in is real and NOT realizing the efficacy of your tool sooner will lead to more complications down the road. I could have written this blog post several times throughout the last 3 years, and now I’m noticing that my “tips” are increasing the more we lock ourselves further into the framework. The more time we develop, locking us in further, the more ideas you have to make later on to get out.

So the result, a campaign to free us from the lock in. Replace Meteor from the inside out slowly and get to a solution that provides us 100% control of our futures.

1. Replace Meteor Packages with NPM Modules

There are still legacy code bases that use Meteor packages that exist in NPM. This means someone either copied an old repo into a Meteor package or is shallowly just Npm.depends -ing on the module.

  • Any package that exists on NPM, switch to it.
  • Remove your Meteor packages in favor of NPM Modules
  • Refactor any of your organizations Meteor packages either into the imports directory or straight to an @org NPM Module.

2. Get off Iron Router

If you’re still on Iron Router like we are, get up from your desk, get a pillow, and scream at the top of your lungs. Then, mull about the most terrible decisions you have made in your life and realize that Iron Router is one of them.

Problem

Using Iron Router alone locks you into Blaze, Templates, Reactive Routes and unpredictable behavior.

Solution

So there a ton of solutions to this and none of them are FlowRouter.

Here are a couple ideas for you:

  • Embrace another UI Library
  • Embrace a community route solution or the one that comes with the UI Library
  • Ensure you contribute, so in the case you get Iron Router’d you may be able to understand the inner working of both the project’s politics and code.

Getting off Iron Router can be done incrementally. Here’s our on-going plan:

  • Remove all Routing hooks and move them to the UI Layer
  • Remove all Subscriptions, and waitOns and move them to the UI Layer
  • Instrument a Routing interface between your application and a Routing Library
  • Replace Iron Router calls with this Routing Interface
  • Replace your UI Layouts that IronRouter made you have
  • Replace the library and update the interface for legacy code
  • Start writing new Routing code with interface or remove interface all together
  • Replace Iron Router Server side Routing with an Express Server. Explained below.

3. Remove Blaze ASAP

Yes. That’s right, GTFO Blaze. Adopt a Library that embraces Component driven development, that has a lot of mindshare around it, and built by passionate UI engineers.

We adopted React.

Other options:

Angular 2, Angular 1, Vue, Preact, Ember

How we are moving off Blaze:

  • Start with child nodes of your UI Tree. Replace them into small Components and render them back into Blaze. If you’re using React you can use the React Template helper in Blaze
  • Once the child nodes are complete, get the parent node
  • Or you want to start from the top down, use this: https://github.com/gadicc/meteor-blaze-react-component to turn Blaze templates into React Components

4. Replace Minimongo/Tracker/ReactiveVar/Session

Remove your dependencies on Meteor magic. Use tools like Redux, MobX, ngRedux, Vuex to manage your reactive client side state. Get rid of your dependencies on the magical Tracker.autorun. You can achieve this same reactivity in different fashions with modern View Layers.

We use Redux to manage this client side state. Apollo Client does an amazing job of managing both UI State and the Domain State from your various microservices. Speaking of Microservices…

5. Microservice Feature Development

Start building features with Microservices in mind. A good source of knowledge is https://www.datawire.io

Think of any new feature as belonging to a new Microservice OR think of the improvement of an existing system in your stack as an opportunity to convert to a Microservice based architecture.

Once the Microservice is up, pipe the calls to it via your GraphQL Server.

6. Get on Apollo

What does this mean? Stop using Publications and Subscriptions. Stop using Meteor Methods. Get your data sources and business logic funneling to the client side via GraphQL and if you want reactivity use GraphQL Subscriptions.

How we are doing this:

  • Move everything that was an unnecessary reactive cost to Meteor Methods
  • Replace Meteor Methods with GraphQL queries and mutations.
  • Anything that was in a subscription that needed to be, like Users, keep in Meteor but plan for replacing with push based GraphQL Subscriptions.
  • Start incrementally adopting Apollo Client in your application. New features should be architected with Apollo and old features can be refactored during maintenance time or improvement times if you have the luxury.

7. Replace Kadira with another performance Monitoring Tool

On the client side, replace Kadira with another tool that can track Errors. Here are few suggestions:

Instrument New Relic

You are going to need New Relic Insights to evaluate JS performance.

Instrument GraphQL

You can use Apollo Optics, or instrument queries/mutations yourself and display them with a tool like Kibana.

8. Mount an Express Server on your App

This is important in moving off Iron Router. You will need a nice way to instrument Server Side routes, and Meteor’s WebAppConnect Handlers don’t offer the same clean api as Express.

Here’s a really easy way to do this:

const express = require('express');
const compression = require('compression');
const bodyParser = require('body-parser');

const server = express();
// express middleware
server.use(compression());
server.use(bodyParser.json()); // application/json
server.use(bodyParser.urlencoded({extended: false})); // application/x-www-form-urlencoded
// install the express server within meteor webapp connect
WebApp.rawConnectHandlers.use(server);

Now you have an Express Server you can work with and slowly channel everything through.

9. Create a different Entry Point

What is an entry point? Maybe this tip really means: USE WEBPACK.

I think the best way to replace your Meteor app from the inside out is to do the following:

  1. Make a .web or .client folder. This will make Meteor’s build tool unaware of this folder and will not build it in course of normal Meteor builds
  2. Install Webpack 2 and start scaffolding your new Single Page App
  3. If you need code from your main Meteor app that is not dependent on Meteor globals, you can import them just fine in the Webpack App
  4. For Legacy systems that still need DDP, use https://github.com/mondora/asteroid, if you want to share login state between this SPA and your main Meteor app (comment down below I can help you out). With Asteroid you can still hit your Meteor backend for legacy pub/sub and meteor methods. (But you should be using GraphQL right?)
  5. Once you have this new SPA you can build your Webpack bundle into your public directory and scaffold an index.html file using https://github.com/ampedandwired/html-webpack-plugin
  6. Once you have your JS Bundle, Vendor Bundle(if you need), and index.html in your public directory, make sure your app in production mode caches these in a CDN.
  7. For now, render your bundle on the client via an Express Server route. e.g. ‘/jobs’ if thats the starting point for this SPA
  8. Use the client side routing of the SPA to move throughout the app.
  9. While your App is running, load the meteor bundle in the background via an async script tag
  10. If you ever need an escape hatch back into Meteor, just route to that route directly outside of the pushState your SPA has.

If you have an app that loads 10mb, pretty much the whole world of your app on every route, you now can build mini single page apps that load in a matter of seconds.

Over time you can move your client into Webpack bundling and replace Meteor completely on the front end.

10. Peak your head in other communities

Take the time to learn what other communities are doing.

Conclusion

Meteor served us well for the time we were growing users. But now entering a different stage of the product’s growth, we need to take the right steps to take more control. Please, let’s discuss these tips below and see if we can help each other out! You might be going down the same path as us, let’s compare notes!

Ciao!