Frictionless browser package management

jspm is a package manager for the [SystemJS universal module loader](https://github.com/systemjs/systemjs), built on top of the dynamic [ES6 module loader](https://github.com/ModuleLoader/es6-module-loader) Load any module format (ES6, AMD, CommonJS and globals) directly from endpoints such as `npm` and `github` with flat versioned dependency management. For production, use the jspm CLI tool to download packages locally, lock down versions and build into a bundle. In development, load modules directly from CDN for frictionless experimentation, switching into production on the same code with a single configuration change. <br> For an overview and demo of jspm, see the JSConf 2014 presentation here, or scroll down to see a written example workflow below. <div style="text-align: center;"> <iframe width="560" height="315" src="http://www.youtube.com/embed/szJjsduHBQQ" frameborder="0" allowfullscreen></iframe> </div> <br> #### Workflow Example **1. Include the SystemJS loader from jspm in the page:** jspm-test.html ```html <script src="https://jspm.io/system@0.9.js"></script> <script> // import 'app.js' from the current URL System.import('~/app').catch(console.error.bind(console)); </script> ``` **2. Require modules directly from GitHub, npm or the jspm registry:** Writing CommonJS for example: app.js ```javascript var collections = require('npm:lodash-node/modern/collections'); var $ = require('github:components/jquery'); $(document.body).html(collections.max([1,2,3,4])); ``` Open `jspm-test.html`, and all the modules are loaded over the CDN, AMD alongside with CommonJS, GitHub working alongside npm. **3. Install the packages locally locking down versions:** ``` jspm install github:components/jquery npm:lodash-node ``` ![jspm install](install.gif) jspm-test.html ```html <script src="jspm_packages/system.js"></script> <script src="config.js"></script> <script> System.import('~/app').catch(console.error.bind(console)); </script> ``` The exact same application now works locally with versions locked down. **4. Build into a bundle for production:** ``` jspm bundle app ``` ![jspm install](build.gif) jspm-test.html ```html <script src="jspm_packages/system.js"></script> <script src="config.js"></script> <script src="build.js"></script> <script> System.import('~/app').catch(console.error.bind(console)); </script> ``` Mixed dependency trees of ES6, AMD, CommonJS and globals get bundled into a single file for production. <br> <div class="loader-icon"></div> #### SystemJS jspm package management is designed around the [SystemJS ES6 loader](https://github.com/systemjs/systemjs). * RequireJS-style module loader with similar configuration and [plugin system](https://github.com/systemjs/systemjs#plugins). * Built on top of the [ES6 Module Loader polyfill](https://github.com/ModuleLoader/es6-module-loader), making it standards-compliant and future-friendly. [Read more at the SystemJS project page on GitHub](https://github.com/systemjs/systemjs) _Note that SystemJS is built on the latest ES6 draft modules specification and may still be subject to change._ <br> <div class="cli-icon"></div> #### jspm CLI * Uses flat version management to download into version-suffixed folders (eg `jspm_packages/npm/lodash-node@x.y.z`). * Shares versions between dependencies, upgrading or downgrading dependency resolutions within their supported ranges to minimize forks. * Because the CLI understands the loader, modular code works without the need for complex manual configuration. [Read the CLI documentation on Github](https://github.com/jspm/jspm-cli) <br> <div class="cdn-icon"></div> #### Endpoints & Registry **Endpoints** Packages are always provided from endpoints with a syntax `endpoint:package`. When requesting a package directly by name, the main entry point is used from the package.json. For example - `System.import('github:twbs/bootstrap')`. Individual modules or asset files can also be requested from inside the package (`npm:repo/sub/module`). The following endpoints are currently supported: * **npm:** * Most packages on npm will work naturally with full version management, with no further configuration necessary. * The NodeJS builtins are provided by the same libraries used in Browserify. * **GitHub:** * Packages on GitHub get their versions from semver tag names (with or without a `v` prefix). * When a GitHub release for a given tag is provided, the release archive will be used instead of the repo. * GitHub packages will benefit from jspm configuration being provided through the package.json or an override. **Package Configuration** [jspm extends the package.json spec](https://github.com/jspm/registry/wiki/Configuring-Packages-for-jspm) with some new properties to understand how to treat packages. Configuration options include the main entry point, module format, files and ignore rules, minfication, transpilation from ES6 to ES5, map config and dependencies (when combined with a registry property). To provide configuration for existing libraries on GitHub or NPM without access to the underlying repo, the jspm registry provides a [package.json override service](https://github.com/jspm/registry#packagejson-overrides). **Registry** The [jspm registry](https://github.com/jspm/registry) provides a convenience mapping from shortcut names such as `jquery` into full endpoint names `github:components/jquery`. **Version Management** Versions can be added to the request, for example - `System.import('npm:jquery@^2.1.0/some/file')` or `System.import('github:twbs/bootstrap@3')`. The major requirement for version-management in the browser is **flat dependency management**, which is a completely different problem to the hierarchical dependency management used in npm. A flat folder structure is used with version suffices on package folders. This way, packages can be individually cached. The key to making this possible is to use semver-compatibility to share dependencies as much as possible. 1. As packages are loaded, semver-compatible dependency sharing in the dependency tree will happen greedily. Any forks can be inspected by looking at `System.versions`. 2. For production, use jspm CLI to do version resolution and injection. Forks are minimized by calculating the allowed version range for a given dependency to satisfy all other dependencies. By default the latest stable semver version is used, and if none is found, the master branch is used. _Always write dependencies within files without any version included (`require('jquery')` / `System.import('jquery')`). This way the latest stable version is used in development, and versions can also be automatically locked through injection of configuration by the jspm CLI._ <br> #### Sites Using jspm CDN * [Hya.io](http://app.hya.io) * [Kickstrap](http://getkickstrap.com) * [Guardian Developers Site](http://developers.theguardian.com) * [adamkochanowicz.com](http://adamkochanowicz.com) [Add your site with a PR](https://github.com/jspm/jspm.io). <br> #### Projects Built for jspm * [Karma-jspm](https://github.com/Workiva/karma-jspm) - Karma support for jspm * [jspm-git](https://github.com/Orbs/jspm-git) - Generic endpoint for Git repositories [Add your project with a PR](https://github.com/jspm/jspm.io). <br> #### Next Steps [Join the Google Group](http://groups.google.com/group/jspm-io) to stay informed, engage in discussion, provide feedback or ask for support. If you are interested in being notified on future jspm announcements, sign up to stay informed here: <form class="signup-group"> <input type="text" class="signup" value="Notify me of future announcements"></input> <input type="submit" class="signup-submit" value="Sign up"></input> <div class="cog"></div> </form> Fork me on GitHub