Meteor Introduces Tighter NPM Integration, Overhauled Package Management
The Meteor Development Group released Meteor 0.6.0 on April 4th as a major overhaul to its package management system as well as growing NPM package support. Since then, version 0.6.2 dropped on April 16th with continued enhancements and bug fixes.
Because it enforces synchronicity in Node.js with the use of Fibers and leverages its own package management system, Meteor has bucked conventional asychronous node development and vanilla NPM package management in favor of its own opinionated approaches, garnering both praise and skepticism along the way. Version 0.6.0 puts both of these issues at the fore, refining its relationship with the node.js ecosystem. Avital Oliver serves as the main impetus behind 0.6.0, with significant contributions from David Glasser and the rest of the Meteor team. InfoQ caught up with Avital to discuss the impact of 0.6.0 on the Meteor and Node.js communities.
INFOQ: One of the criticisms leveled against Meteor has been its 'proprietary packaging system' -- with Meteor 0.6.0, how does that story change?
Avital: Well, I'm not quite sure what makes smart packages more 'proprietary' than NPM, Bower, Component, and the other lesser-known package managers. Smart packages *are* different than NPM modules, for example. One of the unique properties of smart packages are that run on client, server, during build time and even hook into our production environment. This is what makes
meteor add coffeescript,
meteor add appcacheand
meteor add emailjust work. Geoff Schmidt [one of the Meteor core developers] wrote a short essay on these differences.
INFOQ: Given the disparate kinds of NPM packages, which ones are the 'lowest hanging fruit' for Meteor wrapping via
NPM.depends? Does the NPM namespace inside Meteor do any additional wrapping of the NPM functionality (ensuring that async processes are rolled up into Futures, etc), or is that the job of the NPM-Meteor wrapper?
Avital: We will definitely build some sort of generic wrapper, like
Future.wrapbut better. It'll work around some edge cases with Future.wrap, and supply a callback-optional interface, like the ones we have for server-side
Meteor.http.call. In the meanwhile, using
future.resolver()seems to be the easiest way to go (as is done in the XML2JS example).
As for which NPM modules to wrap -- I'd just say wrap whichever ones you want to use! That will help the community use the tools they need within Meteor, and it will help us learn which functionality we should focus our efforts on.
INFOQ: When is documentation coming for the NPM stuff?
Avital: It'll be documented as part of documenting the more final Package API, which is an active work-in-progress (which can be seen on the linker branch on our Github repo.)
INFOQ: What is the Engine package management system that ships with 0.6.0? Why is this different from previous iterations?
Avital: We were tackling two main problems -- (1) apps should be pinned to releases, and ideally you wouldn't have to download every package when switching releases, and (2) Meteor should have native support for third party packages. In order to achieve these goals, we release the Meteor command line tools and packages separately. A release just points to revisions of tools and each package. When you run a new Meteor release, we only fetch the artifacts that have changed, and cache then in a warehouse, which can be found in ~/.meteor.
INFOQ: David Glasser said recently that you guys always wanted to support NPM, but you wanted to do it 'right' -- can you explain what this means?
Avital: We definitely didn't want to ask people to run npm commands directly, just like we don't ask people to run their own instance of MongoDB. So we run
npm installand such behind the scenes for you. We also want to make use of
npm shrinkwrapto ensure that every time you use a smart package you are running the exact same code. In order to achieve all of these in a seamless way, we had to do a certain dance around running NPM. There are a bunch of additional small details, such as the fact that
npm shrinkwrapdoesn't allow you to upgrade the version of only one dependency. Anyway, for those who are curious, the code to implement all of this can be found at here.
INFOQ: How do you justify making tough decisions in the face of convention? (Going with your own package management system versus the status quo [vanilla NPM]).
Avital: There is always one motivating factor: the best experience for our users.
INFOQ: What's next for NPM support?
Avital: We have to do more work to support packages with binary dependencies. We'll build them on all platforms on our servers so that when you use 'meteor deploy' it will work even if your machine runs a different architecture (such as Mac). As described above, we'll also build a general wrapper to make it easier to convert node-style async APIs to ones with optional callbacks.
INFOQ: How close is Meteor 1.0 now?
Avital: It's neither too close nor too far :)
Complete NPM Support
See for more information: meteorhacks.com/complete-npm-integration-for-me...