{"id":22349142,"url":"https://github.com/mnasyrov/ditox","last_synced_at":"2025-04-10T01:06:24.893Z","repository":{"id":42044640,"uuid":"307775119","full_name":"mnasyrov/ditox","owner":"mnasyrov","description":"Dependency injection for modular web applications","archived":false,"fork":false,"pushed_at":"2025-03-02T09:08:48.000Z","size":3050,"stargazers_count":95,"open_issues_count":2,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-10T01:06:19.312Z","etag":null,"topics":["container","dependency","dependency-container","dependency-injection","di","injection","ioc","javascript","module","typescript"],"latest_commit_sha":null,"homepage":"https://ditox.js.org","language":"TypeScript","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/mnasyrov.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}},"created_at":"2020-10-27T17:18:04.000Z","updated_at":"2025-03-22T12:54:05.000Z","dependencies_parsed_at":"2023-01-30T17:16:04.653Z","dependency_job_id":"d9a4075f-e651-4582-a86e-d9b3bfc15f98","html_url":"https://github.com/mnasyrov/ditox","commit_stats":{"total_commits":158,"total_committers":4,"mean_commits":39.5,"dds":0.069620253164557,"last_synced_commit":"e3e836e48ca55794359ed3e94197eb27977002ce"},"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnasyrov%2Fditox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnasyrov%2Fditox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnasyrov%2Fditox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnasyrov%2Fditox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mnasyrov","download_url":"https://codeload.github.com/mnasyrov/ditox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137887,"owners_count":21053775,"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":["container","dependency","dependency-container","dependency-injection","di","injection","ioc","javascript","module","typescript"],"created_at":"2024-12-04T11:07:27.366Z","updated_at":"2025-04-10T01:06:24.876Z","avatar_url":"https://github.com/mnasyrov.png","language":"TypeScript","readme":"# Ditox.js\n\n\u003cimg alt=\"lemon\" src=\"media/lemon.svg\" width=\"120\" /\u003e\n\n**Dependency injection for modular web applications**\n\n[![npm](https://img.shields.io/npm/v/ditox)](https://www.npmjs.com/package/ditox)\n[![stars](https://img.shields.io/github/stars/mnasyrov/ditox)](https://github.com/mnasyrov/ditox/stargazers)\n[![types](https://img.shields.io/npm/types/ditox)](https://www.npmjs.com/package/ditox)\n[![licence](https://img.shields.io/github/license/mnasyrov/ditox)](https://github.com/mnasyrov/ditox/blob/master/LICENSE)\n[![coverage](https://coveralls.io/repos/github/mnasyrov/ditox/badge)](https://coveralls.io/github/mnasyrov/ditox)\n\n## Overview\n\nDitox.js is a lightweight dependency injection container for TypeScript. It\nprovides a simple functional API to bind values and factories to container by\ntokens, and resolve values later. The library supports different scopes for\nfactory bindings, including \"singleton\", \"scoped\", and \"transient\". Bindings can\nbe organised as a dependency module in declarative way.\n\nDitox.js works with containers, tokens, values and value factories. There are no\nclass decorators, field injectors and other magic. Explicit binding and\nresolving are used.\n\n## Features\n\n- Functional API\n- Container hierarchy\n- Scopes for factory bindings\n- Dependency modules\n- Multi-value tokens\n- Typescript typings\n\n## API References\n\nThe library is available as two packages:\n\n- **ditox** - DI container and core tools\n- **ditox-react** - Tools for React.js applications\n\nPlease see the documentation at [ditox.js.org](https://ditox.js.org)\n\n## Getting Started\n\n### Installation\n\nYou can use the following command to install packages:\n\n```shell\nnpm install --save ditox\nnpm install --save ditox-react\n```\n\nPackages can be used as [UMD](https://github.com/umdjs/umd) modules. Use\n[jsdelivr.com](https://jsdelivr.com) CDN site to load\n[ditox](https://www.jsdelivr.com/package/npm/ditox) and\n[ditox-react](https://www.jsdelivr.com/package/npm/ditox-react):\n\n```html\n\u003cscript src=\"//cdn.jsdelivr.net/npm/ditox@2.3.0/dist/umd/index.js\" /\u003e\n\u003cscript src=\"//cdn.jsdelivr.net/npm/ditox-react@2.3.0/dist/umd/index.js\" /\u003e\n\u003cscript\u003e\n  const container = Ditox.createContainer();\n  // DitoxReact.useDependency(SOME_TOKEN);\n\u003c/script\u003e\n```\n\n### Basic concepts\n\n- **Token** specifies a future injection of an \"internal\" implementation with a\n  concrete \"public\" type.\n\n  ```ts\n  type Logger = (message: string) =\u003e void;\n\n  const LOGGER_TOKEN = token\u003cLogger\u003e();\n  ```\n\n- **Container** keeps bindings of **tokens** to concrete values and\n  implementations\n\n  ```ts\n  const container = createContainer();\n  container.bindValue(LOGGER_TOKEN, (message) =\u003e console.log(message));\n  ```\n\n- **Code graph** is constructed at **runtime** by resolving values of tokens.\n\n  ```ts\n  const logger = container.resolve(LOGGER_TOKEN);\n  logger('Hello World!');\n  ```\n\n## Usage Examples\n\n### Binding a value\n\nCreate an injection token for a logger and DI container. Bind a logger\nimplementation and resolve its value later in the application:\n\n```typescript\nimport {createContainer, token} from 'ditox';\n\ntype LoggerService = {\n  log: (...messages: string[]) =\u003e void;\n};\n\n// Injection token\nconst LOGGER_TOKEN = token\u003cLoggerService\u003e();\n\n// Default implementation\nconst CONSOLE_LOGGER: LoggerService = {\n  log: (...messages) =\u003e console.log(...messages),\n};\n\n// Create a DI container\nconst container = createContainer();\n\ncontainer.bindValue(LOGGER_TOKEN, CONSOLE_LOGGER);\n\n// Later, somewhere in the app\nconst logger = container.resolve(LOGGER_TOKEN);\nlogger.log('Hello World!');\n```\n\n### Binding a factory\n\nBind a factory of a remote logger which depends on an HTTP client:\n\n```typescript\nimport {injectable} from 'ditox';\n\nexport type ServerClient = {\n  log: (...messages: string[]) =\u003e void;\n  sendMetric: (key: string, value: string) =\u003e void;\n};\n\nexport const SERVER_CLIENT_TOKEN = token\u003cServerClient\u003e();\n\nfunction createLoggerClient(client: ServerClient): Logger {\n  return {\n    log: (...messages) =\u003e client.log(...messages),\n  };\n}\n\ncontainer.bindFactory(\n  LOGGER_TOKEN,\n  injectable(createLoggerClient, SERVER_CLIENT_TOKEN),\n);\n\n// Later, somewhere in the app\nconst logger = container.resolve(LOGGER_TOKEN);\nlogger.log('Hello World!');\n```\n\n### DI module\n\nOrganise related bindings and functional as a DI module:\n\n```typescript\nimport {bindModule, declareModule} from 'ditox';\n\ntype SendMetricFn = (key: string, value: string) =\u003e void;\n\nconst SEND_METRIC_TOKEN = token\u003cSendMetricFn\u003e();\n\nfunction createMetricClient(client: ServerClient): Logger {\n  return {\n    sendMetric: (key: string, value: string) =\u003e client.sendMetric(key, value),\n  };\n}\n\n// Declare a DI module\nconst TELEMETRY_MODULE = declareModule\u003cLoggerModule\u003e({\n  factory: injectable((client) =\u003e {\n    const logger = createLoggerClient(client);\n\n    const sendMetric = (key: string, value: string) =\u003e {\n      logger('metric', key, value);\n      client.sendMetric(key, value);\n    };\n\n    return {logger, sendMetric};\n  }, SERVER_CLIENT_TOKEN),\n  exports: {\n    logger: LOGGER_TOKEN,\n    sendMetric: SEND_METRIC_TOKEN,\n  },\n});\n\n// Bind the module\nbindModule(container, TELEMETRY_MODULE);\n\n// Later, somewhere in the app\nconst logger = container.resolve(LOGGER_TOKEN);\nlogger.log('Hello World!');\n\nconst sendMetric = container.resolve(SEND_METRIC_TOKEN);\nsendMetric('foo', 'bar');\n```\n\n### Using in React app\n\nWrap a component tree by a DI container and bind modules:\n\n```tsx\n// index.tsx\n\nimport ReactDOM from 'react-dom';\n\nimport {Greeting} from './Greeting';\nimport {TELEMETRY_MODULE} from './telemetry';\n\nconst APP_MODULE = declareModule({\n  imports: [TELEMETRY_MODULE],\n});\n\nconst App: FC = () =\u003e {\n  return (\n    \u003cDependencyContainer root\u003e\n      \u003cDependencyModule module={APP_MODULE}\u003e\n        \u003cGreeting /\u003e\n      \u003c/DependencyModule\u003e\n    \u003c/DependencyContainer\u003e\n  );\n};\n\nReactDOM.render(\u003cApp /\u003e, document.getElementById('root'));\n```\n\nInjecting a dependency by a React component:\n\n```tsx\n// Greeting.tsx\n\nimport {useDependency} from 'ditox-react';\n\nexport const Greeting: FC = () =\u003e {\n  const logger = useDependency(LOGGER_TOKEN);\n\n  useEffect(() =\u003e {\n    logger.log('Hello World!');\n  }, [logger]);\n\n  return \u003c\u003eHello\u003c/\u003e;\n};\n```\n\n## Contact \u0026 Support\n\n- Follow 👨🏻‍💻 **@mnasyrov** on [GitHub](https://github.com/mnasyrov) for\n  announcements\n- Create a 💬 [GitHub issue](https://github.com/mnasyrov/ditox/issues) for bug\n  reports, feature requests, or questions\n- Add a ⭐️ star on [GitHub](https://github.com/mnasyrov/ditox/issues) and 🐦\n  [tweet](https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2Fmnasyrov%2Fditox\u0026hashtags=developers,frontend,javascript)\n  to promote the project\n\n## License\n\nThis project is licensed under the\n[MIT license](https://github.com/mnasyrov/ditox/blob/master/LICENSE).\n\n\u003c!---\nIII. Ditox Package\n- Explanation of the core library\n- List of available methods and functions\n- Examples of advanced usage\n\nIV. Ditox-React Package\n- Explanation of the React library\n- List of available components and functions\n- Examples of usage in a React project\n\nV. Best Practices\n- Recommendations for using Ditox.js effectively\n- Tips for optimizing performance\n\nVI. Troubleshooting\n- Common issues and solutions\n- How to report bugs or request new features\n\nVII. Contributing\n- Guidelines for contributing to the project\n- Code of conduct for contributors\n\nIX. Credits\n- Acknowledgements for contributors and external resources used in the project.\n---\u003e\n","funding_links":[],"categories":["Libraries"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnasyrov%2Fditox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmnasyrov%2Fditox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnasyrov%2Fditox/lists"}