{"id":28076715,"url":"https://github.com/jaredhanson/electrolyte","last_synced_at":"2025-07-15T10:06:13.460Z","repository":{"id":11880105,"uuid":"14441251","full_name":"jaredhanson/electrolyte","owner":"jaredhanson","description":"Elegant dependency injection for Node.js.","archived":false,"fork":false,"pushed_at":"2024-08-30T22:49:59.000Z","size":420,"stargazers_count":561,"open_issues_count":36,"forks_count":61,"subscribers_count":24,"default_branch":"master","last_synced_at":"2025-06-28T03:51:31.436Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaredhanson.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2013-11-16T03:58:05.000Z","updated_at":"2025-06-03T19:22:27.000Z","dependencies_parsed_at":"2023-11-16T21:03:10.940Z","dependency_job_id":"eb183e93-55fa-493c-85d0-99c8a6475751","html_url":"https://github.com/jaredhanson/electrolyte","commit_stats":{"total_commits":320,"total_committers":9,"mean_commits":35.55555555555556,"dds":0.05625000000000002,"last_synced_commit":"9801e9efb5749925e0647b8ba9748265f8e329b0"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/jaredhanson/electrolyte","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredhanson%2Felectrolyte","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredhanson%2Felectrolyte/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredhanson%2Felectrolyte/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredhanson%2Felectrolyte/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaredhanson","download_url":"https://codeload.github.com/jaredhanson/electrolyte/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredhanson%2Felectrolyte/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265427349,"owners_count":23763292,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-13T01:47:43.875Z","updated_at":"2025-07-15T10:06:13.436Z","avatar_url":"https://github.com/jaredhanson.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Electrolyte\n\n[![Build](https://img.shields.io/travis/jaredhanson/electrolyte.svg)](https://travis-ci.org/jaredhanson/electrolyte)\n[![Coverage](https://img.shields.io/coveralls/jaredhanson/electrolyte.svg)](https://coveralls.io/r/jaredhanson/electrolyte)\n[![Quality](https://img.shields.io/codeclimate/github/jaredhanson/electrolyte.svg?label=quality)](https://codeclimate.com/github/jaredhanson/electrolyte)\n[![Dependencies](https://img.shields.io/david/jaredhanson/electrolyte.svg)](https://david-dm.org/jaredhanson/electrolyte)\n\n\nElectrolyte is a simple, lightweight [inversion of control](http://en.wikipedia.org/wiki/Inversion_of_control)\n(IoC) container for Node.js applications.\n\nElectrolyte automatically wires together the various components and services\nneeded by an application.  It does this using a technique known as\n[dependency injection](http://en.wikipedia.org/wiki/Dependency_injection) (DI).\nUsing Electrolyte eliminates boilerplate code and improves software quality by\nencouraging loose coupling between modules, resulting in greater reusability and\nincreased test coverage.\n\nFor further details about the software architecture used for IoC and dependency\ninjection, refer to [Inversion of Control Containers and the Dependency Injection pattern](http://martinfowler.com/articles/injection.html)\nby [Martin Fowler](http://martinfowler.com/).\n\n## Install\n\n    $ npm install electrolyte\n\n## Usage\n\nThere are two important terms to understand when using Electrolyte:\ncomponents and annotations.\n\n#### Components\n\nComponents are simply modules which return objects used within an application.\nFor instance, a typical web application might need a place to store settings, a\ndatabase connection, and a logging facility.\n\nHere's a component that initializes settings:\n\n```javascript\nexports = module.exports = function() {\n  var settings = {}\n    , env = process.env.NODE_ENV || 'development';\n\n  switch (env) {\n    case 'production':\n      settings.dbHost = 'sql.example.com';\n      settings.dbPort = 3306;\n      break;\n    default:\n      settings.dbHost = '127.0.0.1';\n      settings.dbPort = 3306;\n      break;\n  }\n\n  return settings;\n}\n\nexports['@singleton'] = true;\n```\n\nPretty simple.  A component exports a \"factory\" function, which is used to\ncreate and initialize an object.  In this case, it just sets a couple options\ndepending on the environment.\n\nWhat about `exports['@singleton']`?  That's an annotation, and we'll return to\nthat in a moment.\n\n\nHere's another component that initializes a database connection (saved as 'database.js'):\n\n```javascript\nvar mysql = require('mysql');\n\nexports = module.exports = function(settings) {\n  var connection = mysql.createConnection({\n    host: settings.dbHost,\n    port: settings.dbPort\n  });\n\n  connection.connect(function(err) {\n    if (err) { throw err; }\n  });\n\n  return connection;\n}\n\nexports['@singleton'] = true;\nexports['@require'] = [ 'settings' ];\n```\n\nAlso very simple.  A function is exported which creates a database connection.\nAnd those annotations appear again.\n\n#### Async Components\n\nAsync components are defined in an identical manner to traditional components\nexcept that the factory function should return a promise.\n\nLet's rewrite the database component above slightly to return a promise.\n\n```javascript\nvar mysql = require('mysql');\n\nexports = module.exports = function(settings) {\n  return mysql.connectAsPromise({\n    host: settings.dbHost,\n    port: settings.dbPort\n  }).then(function (conn) {\n    // do something clever\n    return conn;\n  });\n}\n\nexports['@singleton'] = true;\nexports['@require'] = [ 'settings' ];\n```\n\nLet's also define a users model that relies on the database component (saved as `users.js`).\n\n```javascript\nexports = module.exports = function(database) {\n  return {\n    create: function (name, email, password) {\n      return database.execute('INSERT INTO users ...');\n    }\n  };\n}\n\nexports['@singleton'] = true;\nexports['@require'] = [ 'database' ];\n```\n\n#### Annotations\n\nAnnotations provide an extra bit of metadata about the component, which\nElectrolyte uses to automatically wire together an application.\n\n- `@require`  Declares an array of dependencies needed by the component.  These\n   dependencies are automatically created and injected as arguments (in the same\n   order as listed in the array) to the exported function.\n\n- `@singleton`  Indicates that the component returns a singleton object, which\n  should be shared by all components in the application.\n\n#### Creating Components\n\nComponents are created by asking the IoC container to create them:\n\n```javascript\nvar IoC = require('electrolyte');\n\nvar db = IoC.create('database');\n```\n\nElectrolyte is smart enough to automatically traverse a component's dependencies\n(and dependencies of dependencies, and so on), correctly wiring together the\ncomplete object structure.\n\nIn the case of the database above, Electrolyte would first initialize the\n`settings` component, and pass the result as an argument to the `database`\ncomponent.  The database connection would then be returned from `IoC.create`.\n\nThis automatic instantiation and injection of components eliminates the\nboilerplate plumbing many application need for initialization.\n\n#### Creating Async Components\n\nAgain, components are created by asking the IoC container to create them:\n\n```javascript\nvar IoC = require('electrolyte');\n\nvar usersPromise = IoC.createAsync('users');\n\nusersPromise.then(function (users) {\n  ...\n});\n```\n\nHere as well electrolyte is smart enough to automatically traverse a component's\ndependencies, correctly wiring together the complete object structure and waiting\nfor each promise to resolve along the way.\n\nIn the case of the users model above, Electrolyte would first initialize the\n`settings` component, and pass the result as an argument to the `database`\ncomponent. Electrolyte would then wait for the database connection promise to\nresolve before passing the resulting value to the users component. `IoC.createAsync`\nthen returns a promise that resolves to the object defined by the users component\nafter the all of its dependencies resolve.\n\n#### Configure the Loader\n\nWhen a component is `@require`'d by another component, Electrolyte will\nautomatically load and instantiate it.  The loader needs to be configured with\nlocation where an application's components are found:\n\n```javascript\nIoC.use(IoC.dir('app/components'));\n```\n\n#### @require vs require()\n\nLoading components is similar in many regards to `require`ing a module, with\none primary difference: components have the ability to return an object that\nis configured according to application-level or environment-specific settings.\nTraditional modules, in contrast, assume very little about the runtime\nconfiguration of an application and export common, reusable bundles of\nfunctionality.\n\nUsing the strengths of each approach yields a nicely layered architecture, which\ncan be seen in the database component above.  The `mysql` module provides\nreusable functionality for communicating with MySQL databases.  The database\ncomponent provides a _configured instance_ created from that module that\nconnects to a specific database.\n\nThis pattern is common: modules are `require()`'d, and object instances created\nfrom those modules are `@require`'d.\n\nThere are scenarios in which this line can blur, and it becomes desireable to\ninject modules themselves.  This is typical with modules that provide\nnetwork-related functionality that needs to be mocked out in test environments.\n\nElectrolyte can be configured to do this automatically, by configuring the loader\nto inject modules:\n\n```javascript\nIoC.use(IoC.node_modules());\n````\n\nWith that in place, the database component above can be re-written as follows:\n\n```javascript\nexports = module.exports = function(mysql, settings) {\n  var connection = mysql.createConnection({\n    host: settings.dbHost,\n    port: settings.dbPort\n  });\n\n  connection.connect(function(err) {\n    if (err) { throw err; }\n  });\n\n  return connection;\n}\n\nexports['@singleton'] = true;\nexports['@require'] = [ 'mysql', 'settings' ];\n```\n\nNote that now the `mysql` module is injected by Electrolyte, rather than\nexplicitly `require()`'d.  This makes it easy to write tests for this component\nwhile mocking out network access entirely.\n\n## Examples\n\n- __[Express](https://github.com/jaredhanson/electrolyte/tree/master/examples/express)__\n  An example Express app using IoC to create routes, with necessary components.\n\n- __[Async Express](https://github.com/jaredhanson/electrolyte/tree/master/examples/async-express)__\n  An example Express app using IoC to create routes asynchronously, with necessary components.\n\n## Tests\n\n    $ npm install\n    $ npm test\n\n## Credits\n\n  - [Jared Hanson](http://github.com/jaredhanson)\n  - Atomic by Cengiz SARI from The Noun Project\n  - [Colour palette](http://www.colourlovers.com/palette/912371/Electrolytes)\n\n## License\n\n[The MIT License](http://opensource.org/licenses/MIT)\n\nCopyright (c) 2013 Jared Hanson \u003c[http://jaredhanson.net/](http://jaredhanson.net/)\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaredhanson%2Felectrolyte","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaredhanson%2Felectrolyte","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaredhanson%2Felectrolyte/lists"}