Life on the front-end side of the development tracks can be an exercise in patience and learning endurance. When it comes to front-end package managers, there is definitely no lack of choices.
In this article I will be focusing on two of the hottest front-end tools: JSPM and Webpack. With Jspm coming to providence thanks to Angular 2 and Aurelia and Webpack being the preference of a large number of React developers.
I have decided to leave Browserify out of this as I believe it has been covered enough and sadly in my opinion, the future currently doesn’t have a place in its heart for Browserify, at least not for me and many others I know who use other tools.
Preamble: this article will be focusing on the usage of Jspm and Webpack on the client-side only.
What is JSPM?
To quote the JSPM site itself, JSPM is “Frictionless browser package management”
It isn’t just another package manager, it aims to be THE package manager of the front-end. You could argue that Npm is already both the front and back-end package manager and that solutions like Jspm are unnecessary.
It is built on-top of System.js which is an ES6 module loader polyfill (which was created by the same developer) which in itself is based on the es6-module loader and underlying official web specification for client-side module loading.
System.js allows us to load modules/files using a plethora of different syntaxes to accommodate to all preferences; CommonJS (Node.js modules), AMD (RequireJS specification) and ECMAScript modules.
While the package management and System.js functionality is great, Jspm also offers bundling as well.
So not only can we manage all of our front-end dependencies using Jspm regardless of where they came from, we can also bundle them all up a variety of different ways; self executing bundles, single bundles and multiple bundles all management by a mapped tree in the config.js allowing for intelligent code splitting and loading in our applications.
Think of it as Npm on steroids plus a loader and a heap of plugins for transforming different file sources.
What is Webpack?
Webpack is a module loader and bundler akin to solutions like Browserify. It actually offers almost everything that Jspm does except it is not a package manager. All Webpack cares about is working with files and bundles, it does not care if you use Npm or if you don’t. It leaves that part up to you. Feed it files and when it matches a particular loader you have specified, it will convert it, copy it or do whatever you want it to do.
There are numerous plugins out there for Webpack that take it from being just a code bundler to something more. The ability to parse CoffeeScript, parse and base64 encode images, include static assets like CSS and use Node modules on the client side is pretty awesome. While Jspm itself can do some of these things, Webpack is more pure in what it is designed to do.
Webpack is a highly configurable code bundler that can handle pretty much sort of front-end code and asset there is. It requires a little configuration to get things happening and you don’t get that out-of-the-box auto updating of your manifest file (like Jspm does with config.js).
As support for HTTP/2 grows, solutions like Jspm are very appealing. At its core, Jspm is designed with HTTP/2 support in mind and some bundling support thrown in as a stop gap until support is a bit better.
When you strip away the package management exterior of Jspm, what you are left with is an intelligent module loader that requires almost no configuration and puts it in the same court as Webpack, but in my opinion has less complexity.
While Jspm still requires the installation of plugins to work with different file formats (as does Webpack), its straightforward approach to dependency management and bundling definitely bolsters the claim of being frictionless package management.
When deciding to use Jspm you have to assess the tradeoffs. Is the thought of another package manager with its own set of commands, modules folder and separate configuration bloated to you? If you are just wanting to work with the one
node_modules folder and use Npm dependencies, then Jspm might seem a little counterintuitive to you.
Since writing the original comparison, Jspm 0.17 is almost ready for the prime time. In .17, Jspm gets a heap of competing features that Webpack has including tree-shaking and hot module swapping. This definitely closes the gap, although in my experience so far, Jspm has a few performance issues to work out before it is as fast as Webpack.
While Webpack might seem like the new kid on the block and darling of the ReactJS world, it is very much as simple as it gets out-of-the-box and grows in complexity depending on what plugins and loaders you use with it.
If the thought of needing to write a bit of configuration does not scare you, then in my opinion, Webpack is the most powerful choice out there. It has loaders for any file format you can think of, it also works on both the client and server-side. When you work with Webpack, you are working with Node modules most likely and it supports them out-of-the-box.
Then there is hot module swapping. This is the killer feature of Webpack in my opinion and many React developers would be inclined to agree. But as I mentioned above, Jspm 0.17 introduces the same hot module swapping concept, so this isn’t really just a Webpack specific killer feature anymore.
Essentially instead of the page completely reloading (thus losing state) only the portion of the code that is changed is reloaded. This means you get lightning fast development and your changes are instantly reflected without losing any of your temporary state data (great for React in particular, but also for all front-end projects).
Having said that, the power of Webpack is pretty unrivalled. The issue with Jspm is if support for something is not there out of the box and a plugin hasn’t been created, you are in the same boat as Webpack. In the case of Webpack there are plugins to do 99% of tasks you would want to do on the front-end. The configuration aspect is where Webpack lets itself down, so if time is important to you and your needs are basic, Jspm will save you a lot of time (mapping is handled automatically in config.js for example).
While Jspm might not be seen as important now in the face of existing tools, when HTTP/2 and its handy multiplexing is more widely supported, tools like JSPM are going to be at the forefront of package and dependency management in the long run as hacks like minification and bundling soon become unnecessary in an attempt to make our web applications faster.
In my experience System.js has some serious performance issues, as does Jspm itself. Currently Jspm feels too unstable, things are changing quickly and breaking. In comparison, Webpack has been very stable and although Webpack 2 will introduce new support and concepts, it won’t be a massive breaking release.
If I were to choose a tool today, I would pick Webpack because of how configurable it is, the plugin ecosystem and direction it is heading. Jspm is great and all, but Webpack feels like you get true power and control.
As you pointed out jspm makes it really easy to use es6 and modules. A cool feature is that you can import CSS and HTML using the same ES6 modules syntax and the SystemJS css and text plugins:
import template from './test.html!text';
When building large SPA sites it is necessary to have a clean style language that supports functions, variables and nesting.
There is a plugin for LESS support in JSPM, but it is very young and does not yet support ‘@import’, which is essential for modular style definitions.
While I love the clean, zero configuration package management with JSPM, but I need full support for LESS. WebPack has a loader for LESS, and for images.
If I could configure WebPack to pull it’s vendor dependencies from JSPM package management folder I would then have a beautiful marriage of PM and site loading. Until then I will use WEbPAck with manual npm and bower PM.
Awesome comparison—thanks for putting this together. Coming from the bower world, this was helpful in understanding JSPM more.
Great article. Thanks.
I think phrasing that Webpack “is still a decent option” is an understatement. There is no mention of the Webpack dev-server with its hot module replacement, which, in combination with React hotloader is such a bliss for React development. Without that functionality I wouldn’t consider moving to JSPM any time soon.
Also I don’t get why installing from GIT is mentioned as a feature for JSPM. It has been possible with NPM for a long time afaik.
This article really does Webpack a disservice, and seems to have a mistaken idea that . I’d like to correct some things:
“If…you are happy to manage your dependencies yourself, then Webpack is still a decent option”
What do you mean “manage your dependencies yourself?” It doesn’t make any sense. With Webpack you just use `npm install` whatever, and npm manages your dependencies for you, as people have been doing with Node for years, and then you can `require` or `import` from that package using Webpack.
Nor is using GitHub packages a specific advantage of jspm; just try `npm install git+https://email@example.com/visionmedia/express.git` in your console. Is that somehow harder than with jspm? The package management aspect of jspm seems superfluous to me. Does it provide something above and beyond npm you haven’t mentioned?
As other people have mentioned for the minuscule amount of work it takes to get ES6 in Webpack (basically just `npm install babel-loader` and add a few lines to your Webpack config) you also get hot loading, quick rebuilds, and a lot of other very slick features at your disposal. Does jspm provide something like these?
What do you mean “manage your dependencies yourself?”
– My guess would be the mention of short-hand, for example `jspm install lodash` will create an entry in the config file to allow for `import _ from ‘lodash’;` instead of having to do something like `import _ from ‘./node_modules/lodash/index.js’.
Is that somehow harder than with jspm?
– The specific use case I have is that I would need something like `npm install git+https://user:firstname.lastname@example.org/some/tfs/crap/visionmedia/express` where I can configured through jspm-git as a handler to prompt for user auth and build that string for you, the jspm-github even allows for environment variables, so now I’ve got a config block that allows `jspm install company:visionmedia/express` and you just need to copy and past a command that configures the company registry.
hot loading: https://github.com/geelen/jspm-server/issues/1
@Austin import `import _ from ‘lodash’;` works with Webpack. There’s no need to create special entries in any config files to use modules in `node_modules` with Webpack.
It’s been awhile since I’ve checked, but I’m pretty sure npm can prompt for GitHub username and password too if it needs to.
That’s nice to know, the config is auto generated though, so you don’t actually have to update it. Our problem is that it’s not actually GitHub, it’s TFS and from what I’ve found, just like most Microsoft products, they don’t follow your normal conventions, such as shallow cloning of repos doesn’t work, I found out…
@Andrew are you saying TFS-via-git somehow works with jspm but not npm? I’d suspect a flaw in their usage of the git protocol
It’s completely a flaw in TFS, but unfortunately one of the higher ups is a Microsoft fan boy, so that’s what we get to use. As such we either stand-up an internal NPM store and publish to that, or use JSPM with the flexibility of their plugin system to work around that. And since I’m pretty sure I’d be the only one that actually pushed to NPM, we’re stuck with the later. That being said, now that webpack has solid support for es6 module loading (even if through a 3rd party plugin) I’ll probably be switching to npm+webpack for my personal projects.
I’ve been using webpack for my react.js projects and love it.
jspm sounds nice but like the op said, I need support for stylus or sass.
I think competition is good and the shortcomings of them both will be addressed soon. (hopefully)
I plan on looking into switching to webpack (or possibly rollup) in the near future, when I get time and budget allowance on the project, or if I get moved to the team that’s actually supposed to be doing all of this.
I’ve used both and strongly prefer JSPM. That being said, I agree this article undersells Webpack. It’s an amazing and powerful tool.
My affinity for JSPM comes from it’s stated goal of standing up near-future standards early. I believe the next generation of amazing and powerful development tools will be built on these standards, so I’m happy to be getting on-boarded early.
Another future standard that JSPM reaches for is HTTP2. JSPM’s workflow is not based on bundling, and with SystemJS bundling is not even ever required. It is, however, going to give your network a migraine…but once multiple concurrent requests can be made effectively, bundling in general may very well become an anti-pattern.
If an entry is copied from one feed into another feed, then the supply feed‘s metadata
(all little one parts of feed other than the entry elements) ought to be preserved if the supply feed comprises any of
the kid elements author, contributor, rights, or category and
people baby parts aren’t present in the source entry.
Will it really be possible to avoid bundling altogether? e.g. if A imports B imports C, you won’t know you need to fetch C until you’ve fetched B…
Now the server could look at the dependency graph and send back all of a requested module’s deps in addition, but that doesn’t sound like what you’re talking about.
The libsass-backed node-sass has enabled Ruby-free Sass compiles for over two years (in practical terms), and it reached parity with the latest Sass release around 6 months ago.
Tangentially related to the topic of the blog post, I know, but in terms of bundler transformations it’s important to know this information is out of date.
I’m using node and react and server-side rendering. So I need npm and I need babel transpiling. Is JSPM even an option?
And I want to develop quickly so I need hot module replacement. If I’m updating code on disk and there’s no watchers with JSPM, is the browser updating as I go?
This article could probably come with a qualifier: this is about using jspm vs webpack for apps where all your code runs in the browser.
Then there’s the declining activity on the repo.
Looks to me like JSPM is the poor, distant cousin to webpack.
Also, you say “hacks like minification and bundling soon become unnecessary”. Unless file size no longer matters with HTTP/2, perhaps you mean “hacks like bundling soon become unnecessary”
David, I would check out Jspm 0.17 which is in beta right now. It’s got a ton of new features and this article is really outdated at this point.
0.17 has it hot module loading built in, support of server side node modules (yes thats right), as well as runtime transpiling which makes getting and app up and running a breeze. Very little overhead. Docs available here: http://jspm.io/0.17-beta-guide/.
Lastly, the Angular team is using SystemJS as the default dependency manager fo ng2 so…this project is certainly not on the decline. 0.17 brings in so many features which make it an all in one solution.
Beautiful, awesome, and very useful article.
congratulations for the module is very helpful
very good post, well written and explained congratulations