IoC for Javascript & Node.js Quickstart provides a lightweight and flexible core to create a scalable API of a lib, a module, an application or a framework. is inspired (among others) by Angular and Pimple.
It is useful for starting a project quickly with a modular API ready to use. (and any object built on top of integrates dependency injection, lazy loading and is extensible via a plugins system easy to use.

No dependencies, works on Node.js and in the browser (only 7kb).


For Node.js

You can install with NPM (Node Package Manager).

npm install

For the browser

Although originally designed for use with Node.js, it can also be used directly in the browser (only 7kb).

See in the browser.


var noder = require('');

Best practice, create an instance of Noder class:

// ./api/index.js
var Noder = require('').Noder;
var api   = new Noder();

// code body that constructs your API

module.exports = api;

or shortcut:

// ./api/index.js
module.exports = require('').createNoder();

Use your API in another file:

var api = require('./api');

// load a plugin

// create an item in the container
api.$di.set('someItem', 'value of the item');

// ...


// create a collection
var items = noder.createCollection();

items.set('myKey', 'my key value');

// my key value

// get all items
var all = items.getAll();

// true
console.log(items instanceof noder.Collection);

See collection.

Dependency Injection

See dependency injection.

Lazy loading

noder.$require method provides a lazy require():

// define the property without loading the mongoose module

// false

// lazy loading
var mongoose = noder.mongoose;

// true

// true
console.log(noder.mongoose === require('mongoose'));


noder.$require('promise', 'bluebird');

// true
console.log(noder.promise === require('bluebird'));

Custom loader:

// factory: promisify the "fs" module
noder.$require('fs', function() {
  return noder.promise.promisifyAll(require('fs'));

  .then(function(contents) {
  .catch(function(err) {

See lazy loading.

Plugins provides a plugin system to make a package works as a plugin for and also as a standalone module or library.

Example of a Noder plugin:

 * Initialization for use as a standalone module.
 * @return {Noder} New `Noder` instance
module.exports = function blog() {

  var Noder = require('').Noder;
  var noder = new Noder();

  // or use the shortcut:
  // var noder = require('').createNoder();

  return module.exports.__noder(noder);

 * Init `blog` plugin.
 * @param  {Noder} noder  `Noder` instance
 * @return {Noder}        Current `Noder` instance
module.exports.__noder = function blogPlugin(noder) {

  // create config object only if not exists
  noder.$di.addOnce('config', {}, true);

  // sub-modules of blogPlugin
  // that add features to the instance of Noder

  // Always return the instance of Noder to allow chaining
  return noder;

See plugins.


Here is an example that could be a real case.

File: ./api/config

module.exports.__noder = function config(noder) {

  noder.$di.set('config' {
    connection: 'mongodb://localhost/blog',
    post: {
      limit: 20

  return noder;

File: ./api/db.js

var Post = require('../models/post.js');

module.exports.__noder = function db(noder) {

  // define custom loader
  noder.$require('mongoose', function() {

    var mongoose = require('mongoose');

    // note: `this` === `noder.$di._container`

    return mongoose;

  // define a singleton
  noder.$di.singleton('connectMongoose', function connectMongoose(mongoose) {

    return mongoose.connect(noder.$di.get('config').connection);

  // define a helper
  noder.$di.set('getPosts', function getPosts(callback) {

    var config = noder.$di.get('config');

    return Post
      .find({published: true})
      .sort({'date': -1})

  return noder;

File: ./api/index.js

// module.exports is a singleton
module.exports = require('').createNoder();

File: ./app.js

var api = require('./api');

// define lazy loader with alias
api.$require('markdown', 'marked');

// init config

// init DB dependencies

// init blog dependencies

// invoke the dependencies injected as arguments
api.$invoke(['view', 'getPosts'], function(view, getPosts) {

  getPosts(function(err, posts) {

    // `posts` will be of length 20 (see `config` object)
    for(var i in posts) {

      // parse markdown of each posts
      posts[i].contents = api.markdown(posts[i].contents);

    // render posts

// another way, use the dependencies in the scope (`this`)
api.$apply(function() {

  this.getPosts(function(err, posts) {

    // `posts` will be of length 20 (see `config` object)
    for(var i in posts) {

      // parse markdown of each posts
      posts[i].contents = api.markdown(posts[i].contents);

    // render posts

The workflow may be easier but it's to show an example using several things at once.

With a small modification, we could also obtain this way, file: ./app.js

var db = api.db;


// invoke this function with the dependency injected as argument
db('getPosts', function(getPosts) {

  getPosts(function(err, posts) {

    // `posts` will be of length 20 (see `config` object)
    api.view('blog/posts', err, posts);

Free rein to your imagination and your favorites good practices :)


The learning curve to be productive with is very short. The guide presents you a quick tour of some features of, the API is fully documented.

I suggest you read the few pages of this guide in order to know and to effectively exploit the capabilities provided by

Try to handle the noder.$di container, creates a service, try the dependency injection, creates a plugin ("hello world"). And go start your next project with :)

The concrete practice is the best for learning quickly!

Unit Tests is tested with Unit.js and Mocha.

Unit.js is a powerful and intuitive unit testing framework for Node.js and also for javascript in the browser. The core of Unit.js is built on top of

It's a unit testing framework that provides a awesome implementation of with dependency injection in the scope (this) of some BDD methods (given(), when(), then(), ... ), the plugin system and all features of!


MIT (c) 2013, Nicolas Tallefourtane.

Author is designed and built with love by Nicolas Tallefourtane.