{"id":14155514,"url":"https://github.com/mrspartak/config","last_synced_at":"2025-10-24T01:58:12.393Z","repository":{"id":243854492,"uuid":"812054678","full_name":"mrspartak/config","owner":"mrspartak","description":"Typescript runtime configuration resolver","archived":false,"fork":false,"pushed_at":"2024-06-22T21:31:45.000Z","size":475,"stargazers_count":21,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-14T20:08:25.761Z","etag":null,"topics":["configuration","javascript","superstruct","typescript","valibot","validation","yup","zod"],"latest_commit_sha":null,"homepage":"https://mrspartak.github.io/config/","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/mrspartak.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2024-06-07T21:25:12.000Z","updated_at":"2024-09-08T03:59:16.000Z","dependencies_parsed_at":"2024-06-22T04:35:42.226Z","dependency_job_id":"f2caf258-5be9-4586-9382-bceb7d3bc22d","html_url":"https://github.com/mrspartak/config","commit_stats":null,"previous_names":["mrspartak/config"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrspartak%2Fconfig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrspartak%2Fconfig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrspartak%2Fconfig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrspartak%2Fconfig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrspartak","download_url":"https://codeload.github.com/mrspartak/config/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243826783,"owners_count":20354220,"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":["configuration","javascript","superstruct","typescript","valibot","validation","yup","zod"],"created_at":"2024-08-17T08:03:45.164Z","updated_at":"2025-10-24T01:58:07.366Z","avatar_url":"https://github.com/mrspartak.png","language":"TypeScript","funding_links":[],"categories":["typescript","CSS In JS With Types"],"sub_categories":["Runtime"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg width=\"560\" src=\"https://raw.githubusercontent.com/mrspartak/config/master/assets/logo.svg\" alt=\"Vite logo\"\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://npmjs.com/package/@mrspartak/config\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@mrspartak/config.svg\" alt=\"npm package\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://npmjs.com/package/@mrspartak/config\"\u003e\u003cimg src=\"https://img.shields.io/bundlephobia/min/%40mrspartak/config.svg\" alt=\"bundle size\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://npmjs.com/package/@mrspartak/config\"\u003e\u003cimg src=\"https://img.shields.io/npm/dw/%40mrspartak%2Fconfig.svg\" alt=\"downloads\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://nodejs.org/en/about/previous-releases\"\u003e\u003cimg src=\"https://img.shields.io/node/v/@mrspartak/config.svg\" alt=\"node compatibility\"\u003e\u003c/a\u003e\n  \u003ca href='https://coveralls.io/github/mrspartak/config?branch=master'\u003e\u003cimg src='https://coveralls.io/repos/github/mrspartak/config/badge.svg?branch=master' alt='Coverage Status' /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\n\n# 🔧 Typescript runtime configuration resolver \n\n@mrspartak/config is a robust TypeScript runtime configuration resolver designed to ensure that your application runs with the correct settings every time. It supports dynamic runtime validation, deep merging of configurations, and integrates seamlessly with your choice of data validation libraries.\n\n- ⚡️ **Runtime Validation**: Ensure your application never runs with the wrong configuration.\n- 🧙‍♂️ **TypeScript IntelliSense**: Leverage auto-completion and type-checking at development time.\n- 🍃 **Zero Dependencies**: Lightweight with no external dependencies\n- 🤲 **Flexible Configuration Merging**: Supports merging multiple configurations with a default overwrite strategy.\n- 👓 **Versatile Configuration Sources**: Load from JSON files, URLs, or direct objects. Inderect .env support\n- 🐻 **Extensible Validation Support**: Compatible with **Zod**, **Valibot**, **Yup**, **Superstruct**, and more.\n- ✅ **Production Ready**: Thoroughly tested and stable for use.\n- 📦 **Front-end friendly**: Can be used on a front-end with bundlers.\n\n## Installation\n```sh\n# yarn\nyarn add @mrspartak/config\n# npm\nnpm i @mrspartak/config\n# pnpm\npnpm add @mrspartak/config\n# bun\nbun add @mrspartak/config\n```\n\n## Mentions\n- [My article on how to do configurations](https://medium.com/@assorium/mastering-typescript-runtime-configurations-5dbfec90be87)\n\n## Using with JSON config on a back-end\n\n\u003e This is a recomended way of doing back-end run-time configuration. It allows to have readable structures and can be used with configmaps and secrets on deploy. \n\n```ts\n// file: state/config.ts\nimport { fromJSONFile } from \"@mrspartak/config\";\nimport * as z from \"zod\"\n\nconst config = await fromJSONFile({\n  path: [\"../config/default.json\", \"../config/runtime.json\"],\n  schema: z.object({\n    db: z.object({\n      host: z.string(),\n      port: z.number(),\n      username: z.string(),\n      password: z.string()\n    }),\n    app: z.object({\n      port: z.number().optional().default(3000)\n    })\n  }),\n});\n\nexport default config\n```\n\n```ts\n// file: index.ts\n// Import your resolved configuration\nimport config from './state/config.js';\n\n// Use the configuration in your application\nimport db from 'some-db-provider';\nconst dbClient = db(config.db); // Enjoy IntelliSense here!\n```\n\n## Using with .env configuration on back-end\n\n\u003e Libriaries that parse .env configuration files are rich with features, so no reason to write my own. But this library can still be used on top for validation and IntelliSense purposes.\n\n```ts\n// file: state/config.ts\nimport { fromObject } from \"@mrspartak/config\";\nimport * as z from \"zod\"\n\nconst schema = z\n  .object({\n    NODE_ENV: z.enum([\"development\", \"production\"]),\n    DB_HOST: z.string(),\n    DB_PORT: z.number(),\n    DB_USER: z.string(),\n    DB_PASSWORD: z.string(),\n    APP_PORT: z.number().default(3000),\n  })\n  .transform((data) =\u003e ({\n    environment: data.NODE_ENV,\n    port: data.APP_PORT,\n    db: {\n      host: data.DB_HOST,\n      port: data.DB_PORT,\n      user: data.DB_USER,\n      password: data.DB_PASSWORD,\n    },\n  }));\n\nconst config = await fromObject({\n  data: process.env,\n  schema\n})\n\nexport default config\n```\n\n```ts\n// file index.ts\nimport 'dotenv/config'\n// ! Configuration must be loaded after dotenv so it will populate process.env\nimport config from './state/config.js';\n\n// Use the configuration in your application\nimport db from 'some-db-provider';\nconst dbClient = db(config.db); // Enjoy IntelliSense here!\n```\n\n## Using on front-end\n\n\u003e There is a separate build, that trims Node APIs for usage on front-end. Because this library is mostly build to improve DX, I see no reason to bundle it for usage on front-ends without a bundler (vite, webpack...)  \n\u003e It supports both build-time and run-time configurations\n\n### Build-time front-end configuration\n```ts\n// file: state/config.ts\nimport { fromObject } from \"@mrspartak/config/web\"; // a separate build of the library\nimport * as z from \"zod\"\n\nconst schema = z\n  .object({\n    API_URL: z.string(),\n  })\n\nconst config = await fromObject({\n  data: import.meta.env, // example with vite \n  schema\n})\n\nexport default config\n```\n\n### Run-time front-end configuration\n```ts\n// file: state/config.ts\nimport { fromURL } from \"@mrspartak/config/web\"; // a separate build of the library\nimport * as z from \"zod\"\n\nconst environment = import.meta.env.DEV ? \"development\" : \"production\"\nconst configPath = `/config/${environment}.json`\n\nconst schema = z\n  .object({\n    api_url: z.string(),\n  })\n\nconst config = await fromURL({\n  url: configPath, // will load a json from URL\n  schema\n})\n\nexport default config\n```\n\n### Front-end usage\n\n```tsx\n// file main.tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom/client\"\nimport { ConfigProvider } from \"@/context/ConfigContext\"\nimport { Routes } from \"@/routes\"\n\nasync function main() {\n  // Can be build-time, run-time or even both\n  const config = await import(\"@/state/config\"); \n\n  ReactDOM.createRoot(document.getElementById(\"root\")!).render(\n    \u003cReact.StrictMode\u003e\n      \u003cConfigProvider config={config}\u003e\n        \u003cRoutes /\u003e\n      \u003c/ConfigProvider\u003e\n    \u003c/React.StrictMode\u003e\n  )\n}\n\nmain().catch(error =\u003e {\n  console.error(\"Mount error\", error)\n  ReactDOM.createRoot(document.getElementById(\"root\")!).render(\n    \u003cReact.StrictMode\u003e\n      \u003cdiv className=\"flex items-center justify-center h-screen\"\u003e\n          1. Try to reaload the page.\n          \u003cbr /\u003e\n          2. If doesn't help, please talk to developers, something went wrong.\n      \u003c/div\u003e\n    \u003c/React.StrictMode\u003e\n})\n```\n\nAPI documentation is generated from TS declaration is avialable here: https://mrspartak.github.io/config/\n\n## Contributing\nI welcome contributions from the community! Whether it's improving the documentation, adding new features, or reporting bugs, please feel free to make a pull request or open an issue.\n\n## License\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrspartak%2Fconfig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrspartak%2Fconfig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrspartak%2Fconfig/lists"}