{"id":13580763,"url":"https://github.com/nestjsx/nestjs-config","last_synced_at":"2025-05-15T14:02:12.882Z","repository":{"id":36029728,"uuid":"122749858","full_name":"nestjsx/nestjs-config","owner":"nestjsx","description":"Config module for nestjs using dotenv :key:","archived":false,"fork":false,"pushed_at":"2023-08-11T10:26:55.000Z","size":2295,"stargazers_count":700,"open_issues_count":32,"forks_count":44,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-11T15:23:48.649Z","etag":null,"topics":["config","dotenv","nestjs","typescript"],"latest_commit_sha":null,"homepage":"","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/nestjsx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-02-24T14:56:57.000Z","updated_at":"2025-05-05T05:52:40.000Z","dependencies_parsed_at":"2023-07-16T16:54:26.335Z","dependency_job_id":"a6fd54c1-ef6c-4c75-94b9-310e984392f6","html_url":"https://github.com/nestjsx/nestjs-config","commit_stats":{"total_commits":368,"total_committers":24,"mean_commits":"15.333333333333334","dds":0.6820652173913043,"last_synced_commit":"0af0ba83dc365149eeb7a5bc3b4238a569484ea9"},"previous_names":["bashleigh/nest-config"],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjsx%2Fnestjs-config","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjsx%2Fnestjs-config/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjsx%2Fnestjs-config/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjsx%2Fnestjs-config/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nestjsx","download_url":"https://codeload.github.com/nestjsx/nestjs-config/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254101575,"owners_count":22014903,"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":["config","dotenv","nestjs","typescript"],"created_at":"2024-08-01T15:01:54.878Z","updated_at":"2025-05-15T14:02:12.859Z","avatar_url":"https://github.com/nestjsx.png","language":"TypeScript","funding_links":[],"categories":["Components \u0026 Libraries","资源","TypeScript","typescript"],"sub_categories":["组件和库"],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/43827489?s=400\u0026u=45ac0ac47d40b6d8f277c96bdf00244c10508aef\u0026v=4\"/\u003e\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://travis-ci.org/nestjsx/nestjs-config\"\u003e\u003cimg src=\"https://travis-ci.org/nestjsx/nestjs-config.svg?branch=master\" alt=\"travis\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/nestjs-config\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/nestjs-config.svg\" alt=\"npm\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/nestjsx/nestjs-config/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/nestjsx/nestjs-config.svg\" alt=\"license\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://coveralls.io/github/nestjsx/nestjs-config?branch=master\"\u003e\u003cimg src=\"https://coveralls.io/repos/github/nestjsx/nestjs-config/badge.svg?branch=master\" alt=\"coveralls\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://npm.packagequality.com/#?package=nestjs-config\"\u003e\u003cimg src=\"https://npm.packagequality.com/shield/nestjs-config.svg\" alt=\"package quality\"/\u003e\u003c/a\u003e\n    \u003cimg src=\"https://flat.badgen.net/dependabot/nestjsx/nestjs-config?icon=dependabot\" alt=\"dependabot\" /\u003e\n    \u003cimg src=\"https://camo.githubusercontent.com/a34cfbf37ba6848362bf2bee0f3915c2e38b1cc1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5052732d77656c636f6d652d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265\" alt=\"PRs welcome\"/\u003e\n    \u003ca href=\"https://github.com/juliandavidmr/awesome-nestjs#components--libraries\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/nestjsx/crud/master/img/awesome-nest.svg?sanitize=true\" alt=\"Awesome Nest\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/nestjs/nest\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/nestjsx/crud/master/img/nest-powered.svg?sanitize=true\" alt=\"Nest Powered\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/org/nestjsx\"\u003e\n      \u003cimg src=\"https://img.shields.io/npm/dt/nestjs-config.svg\" alt=\"npm downloads\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\u003ch1 align=\"center\"\u003eNestjs Config\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003eConfiguration component for NestJs.\u003c/p\u003e\n\n\n## Features\n\n- Load your configuration files using globs\n- Support for different environment configurations, thanks to [dotenv](https://github.com/motdotla/dotenv)\n- Change and Load configuration at runtime\n\n### Installation\n\n**Yarn**\n```bash\nyarn add nestjs-config\n```\n\n**NPM**\n```bash\nnpm install nestjs-config --save\n```\n\n### Getting Started\n\nLet's imagine that we have a folder called `src/config` in our project that contains several configuration files.\n\n```bash\n/src\n├── app.module.ts\n├── config\n│   ├── express.ts\n│   ├── graphql.ts\n│   └── grpc.ts\n```\n\nLet's register the config module in `app.module.ts`\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { ConfigModule } from 'nestjs-config';\nimport * as path from 'path';\n\n@Module({\n    imports: [\n        ConfigModule.load(path.resolve(__dirname, 'config', '**/!(*.d).{ts,js}')),\n    ],\n})\nexport class AppModule {}\n```\nThat's it!\n\n-----\n\n#### Complex Project Structure\n\nNow let's say that your application isn't located in a folder called `src`, but it's located in `src/app`.\n\nWe want to be able to set a different 'root path' to load our configurations from. Be it `src` or `dist`.\n\nImagine a more complex project structure like this:\n\n```\n/\n├── dist/\n├── src/\n│   ├── app/\n│   │   ├── app.module.ts\n│   │   └── bootstrap/\n│   │   │   ├── index.ts\n│   │   │   └── bootstrap.module.ts\n│   ├── migrations/\n│   ├── cli/\n│   ├── config/\n│   │   ├── app.ts\n│   │   └── database.ts\n│   └── main.ts\n├── tsconfig.json\n└── package.json\n```\n\nIn this example, config files are located in the `/src/config` folder, because they are shared \nbetween app, migrations and cli scripts. \n\nAlso during typescript compilation all files from `src/` folder will be moved to the `dist/` folder. \n\nMoreover, the `ConfigModule` is imported in the `BootstrapModule`, but not directly in `AppModule`.\n\n```ts\n// app.module.ts\nimport { Module } from '@nestjs/common';\nimport { BootstrapModule } from './bootstrap';\nimport { ConfigService } from 'nestjs-config';\n\nConfigService.rootPath = path.resolve(__dirname, '..');\n\n@Module({\n    imports: [BootstrapModule],\n})\nexport class AppModule {}\n```\n\n```typescript\n// bootstrap.module.ts\nimport * as path from 'path';\nimport { Module } from '@nestjs/common';\nimport { ConfigModule } from 'nestjs-config';\n\n@Module({\n    imports: [\n      ConfigModule.load(path.resolve('config', '**/!(*.d).{ts,js}')),\n    ],\n})\nexport class BootstrapModule {}\n```\nSetting the `ConfigService.rootPath` before calling `ConfigModule.load(...)` will change the default root dir of where your configs are loaded from.\n\nAnother method is to invoke `ConfigModule.resolveRootPath(__dirname)` from any module before loading the config and use glob with a relative path.\n  ```ts\n  // bootstrap.module.ts\n  import { Module } from '@nestjs/common';\n  import { ConfigModule } from 'nestjs-config';\n  \n  @Module({\n      imports: [\n        ConfigModule.resolveRootPath(__dirname).load('config/**/!(*.d).{ts,js}')\n      ],\n  })\n  export class BootstrapModule {}\n  ```\n\nIn both cases we provide the glob of our configuration as first argument, but it is relative to the `src/` folder (or eventually `dist/`).\n\n## Multi-modular config usage\n\nIn some cases your structure might take on this shape\n\n```\n/\n├── src/\n│   ├── cats/\n│   │   ├── cats.module.ts\n│   │   └── cats.config.ts\n│   ├── dogs/\n│   │   ├── dogs.module.ts\n│   │   └── dogs.config.ts\n│   ├── app.module.ts\n│   └── main.ts\n├── tsconfig.json\n└── package.json\n```\n\nWith the examples above you'd have to call your config like so `ConfigService.get('dogs.config.bark')`. You can use the `modifyConfigName` method option to change the name of your configs \n\n```ts\nimport { Module } from '@nestjs/common';\nimport { ConfigModule } from 'nestjs-config';\nimport * as path from 'path';\n\n@Module({\n    imports: [\n        ConfigModule.load(path.resolve(__dirname, '**/!(*.d).config.{ts,js}'), {\n            modifyConfigName: name =\u003e name.replace('.config', ''),\n        }),\n    ],\n})\nexport class AppModule {}\n```\nNow you can call your config like so `ConfigService.get('dogs.bark')`.\n\n## Production environments\n\nYou might have notice the use of `config/**/!(*.d).{ts,js}` in the glob. When running in production (running in JavaScript after TypeScript compilation) we want to disinclude the TypeScript definition files. The use of `config/**/*.ts` is fine in dev environments but we recommend using this example `config/**/!(*.d).{ts,js}` to avoid issues later on when running in a production environment.\n\n## Environment Configuration\n\nThis package ships with the amazing [dotenv](https://github.com/motdotla/dotenv) package that allows you to create\na `.env` file in your preferred location.\n\nLet's create one, for demo purposes!\n\n```bash\n# .env\nEXPRESS_PORT=3000\n```\n\nNow, in our `src/config/express.ts` configuration file, we can refer to that environment variable.\n\n```ts\n// src/config/express.ts\nexport default {\n    port: process.env.EXPRESS_PORT || 3000,\n}\n```\n\n\u003e **Note:** By default the package look for a `.env` file in the path that you have started your server from.\nIf you want to specify another path for your `.env` file, use the second parameter of `ConfigModule.load()`.\n\n\n### Usage\n\nNow we are ready to inject our `ConfigService` anywhere we'd like.\n\n```ts\nimport {ConfigService} from 'nestjs-config';\n\n@Injectable()\nclass SomeService {\n\n    constructor(private readonly config: ConfigService) {\n        this.config = config;\n    }\n    \n    isProduction() {\n        const env = this.config.get('app.environment');\n        \n        return env === 'production';\n    }\n}\n```\n\nYou may also use the `@InjectConfig` decorator as following:\n\n```ts\nimport {InjectConfig} from 'nestjs-config';\n\n@Injectable()\nclass SomeService {\n\n    constructor(@InjectConfig() private readonly config) {\n        this.config = config;\n    }\n}\n```\n\n## Custom Helpers\nThis feature allows you to create small helper function that computes values from your configurations.\n\nReconsider the `isProduction()` method from above. But in this case, let's define it as a helper:\n\n```ts\n// src/config/express.ts\n\nexport default {\n\n    environment: process.env.EXPRESS_ENVIRONMENT,\n    port: process.env.EXPRESS_PORT,\n    \n    // helpers\n    isProduction() {\n        return this.get('express.environment') === 'production';\n    }\n}\n```\n\nYou can use the helper function as follows:\n\n```ts\n// this.config is the ConfigService!\nthis.config.get('express').isProduction();\n\n// or\nthis.config._isProduction(); // note the underscore prefix.\n```\n\n#### Global Helpers\n\nYou can also attach helpers to the global instance as follow:\n\n```ts\nthis.config.registerHelper('isProduction', () =\u003e {\n    return this.get('express.environment') === 'production';\n});\n```\n\nAnd then use it like this:\n\n```ts\nthis.config.isProduction(); // note the missing underscore prefix\n```\n\n## Decorators \n\nIt's possible to use decorators instead of injecting the `ConfigService`. \nNote that the `@Configurable()` decorator replaces the `descriptor.value` for the\nmethod with its own function. Regarding to the current nestjs implementation\n([Issue-1180](https://github.com/nestjs/nest/issues/1180)), this behavior will \nbreak all decorators that **FOLLOW AFTER** the `@Configurable()` decorator.\n\nFor the expected behavior, the `@Configurable()` decorator **MUST** be placed at \nthe last position for one method.\n\n**Working Example:**\n```ts\nimport {Injectable, Get} from '@nestjs/common';\nimport {Configurable, ConfigParam} from 'nestjs-config';\n\n@Injectable()\nexport default class UserController {\n    \n    @Get('/')\n    @Configurable()\n    index(@ConfigParam('my.parameter', 'default value') parameter?: string) {\n        return { data: parameter };\n    }\n}\n```\n\n**Broken Example:**\n```ts\nimport {Injectable, Get, UseInterceptors} from '@nestjs/common';\nimport {Configurable, ConfigParam} from 'nestjs-config';\nimport {TransformInterceptor} from '../interceptors';\n\n@Injectable()\nexport default class UserController {\n    \n    @Configurable()\n    @Get('/')   // \u003c-- nestjs decorator won't work because it placed after @Configurable()\n    @UseInterceptors(TransformInterceptor)// \u003c-- nestjs decorator won't work because it placed after @Configurable()\n    index(@ConfigParam('my.parameter', 'default value') parameter?: string) {\n        return { data: parameter };\n    }\n}\n```\n\n**Broken Example 2:**\n```ts\nimport {Injectable, Get, UseInterceptors} from '@nestjs/common';\nimport {Configurable, ConfigParam} from 'nestjs-config';\nimport {TransformInterceptor} from '../interceptors';\n\n@Injectable()\nexport default class UserController {\n    \n    \n    @Get('/') // \u003c-- nestjs decorator will work fine because it placed before @Configurable()\n    @Configurable()\n    @UseInterceptors(TransformInterceptor) // \u003c-- nestjs decorator won't work because it placed after @Configurable()\n    index(@ConfigParam('my.parameter', 'default value') parameter?: string) {\n        return { data: parameter };\n    }\n}\n```\n\n## TypeORM \n\nUsing the `ConfigModule` in combination with [TypeORM](https://github.com/typeorm/typeorm) (e.g. in order to configure TypeORM) requires using the `forRootAsync()` function supplied by the typeorm package for nestjs (`@nestjs/typeorm`)\n\n```ts\nimport {Module} from '@nestjs/common';\nimport {ConfigModule, ConfigService} from 'nestjs-config';\nimport {TypeOrmModule} from '@nestjs/typeorm';\nimport * as path from 'path';\n\n@Module({\n    imports: [\n        ConfigModule.load(path.resolve(__dirname, 'config', '**', '!(*.d).{ts,js}')),\n        TypeOrmModule.forRootAsync({\n            useFactory: (config: ConfigService) =\u003e config.get('database'),\n            inject: [ConfigService],\n        }),\n    ],\n})\nexport default class AppModule {}\n```\n\nYour config file may look something like this: \n\n```ts\n//config/database.ts\nexport default {\n    type: 'mysql',\n    host: process.env.TYPEORM_HOST,\n    username: process.env.TYPEORM_USERNAME,\n    password: process.env.TYPEORM_PASSWORD,\n    database: process.env.TYPEORM_DATABASE,\n    port: parseInt(process.env.TYPEORM_PORT),\n    logging: process.env.TYPEORM_LOGGING === 'true',\n    entities: process.env.TYPEORM_ENTITIES.split(','),\n    migrationsRun: process.env.TYPEORM_MIGRATIONS_RUN === 'true',\n    synchronize: process.env.TYPEORM_SYNCHRONIZE === 'true',\n};\n```\n\n\u003e We recommend using a `TYPEORM_` prefix so when running in production environments you're also able to use the same envs for running the typeorm cli. [More options here](http://typeorm.io/#/using-ormconfig/using-environment-variables)\n\n## Custom env file path\n\nYou can specify dotenv options with the second parameter of the load method\n\n```ts\nConfigModule.load(path.resolve(__dirname, '*/**!(*.d).config.{ts,js}'), {\n    path: path.resolve(__dirname, '..', '.env.staging')),\n});\n```\n\n## Using different env files\n\nCreate a `.env` file at the root directory of your application had always been the best practice.\nYou could also create custom .env file per different environments.\n\n```bash\n# .env\nEXPRESS_PORT=3000\n\n# .env.dev\nEXPRESS_PORT=3001\n\n# .env.testing\nEXPRESS_PORT=3002\n\n# .env.staging\nEXPRESS_PORT=3003\n```\n\n```ts\nconst ENV = process.env.NODE_ENV;\n\nConfigModule.load(path.resolve(__dirname, '*/**!(*.d).config.{ts,js}'), {\n  path: path.resolve(process.cwd(), !ENV ? '.env' : `.env.${ENV}`),\n});\n```\n\nPerhaps you need a custom directory to manage env files.\n\nIn this example, the name of the custom directory is `env`.\n\n```bash\n/\n├── dist/\n├── env/\n│   ├── .env.dev\n│   ├── .env.testing\n│   └── .env.staging\n│   │\n├── src/\n│   ├── config/\n│   │   └── typeorm.config.ts\n│   └── main.ts\n├── tsconfig.json\n└── package.json\n```\n\n```ts\nconst ENV = process.env.NODE_ENV;\n\nConfigModule.load(path.resolve(__dirname, '*/**!(*.d).config.{ts,js}'), {\n  path: path.resolve(process.cwd(), 'env', !ENV ? '.env' : `.env.${ENV}`),\n});\n```\n\n\u003e **Note:** If you place env files inside an `src` directory, you won't be able to see env files included as a final output in `outDir` since TS compiler will never transpile files that do not match with \\*.ts extension.\n\n## Support\n\nAny support is welcome. At least you can give us a star :star:\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n\u003ca href=\"https://github.com/nestjsx/nestjs-config/graphs/contributors\"\u003e\n  \u003cimg src=\"https://opencollective.com/nestjsx/contributors.svg?width=890\u0026button=false\" /\u003e\n\u003c/a\u003e\n\n## ConfigService API\n\n#### get(param: string | string[], value: any = undefined): any\nGet a configuration value via path, you can use `dot notation` to traverse nested object. It returns a default value if the key does not exist.\n\n```ts\nthis.config.get('server.port'); // 3000\nthis.config.get('an.undefined.value', 'foobar'); // 'foobar' is returned if the key does not exist\n```\n\n#### set(param: string | string[], value: any = null): Config\nSet a value at runtime, it creates the specified key / value if it doesn't already exists.\n\n```ts\nthis.config.set('server.port', 2000); // {server:{ port: 2000 }}\n```\n\n#### has(param: string | string[]): boolean\nDetermine if the given path for a configuration exists and is set.\n\n```ts\nthis.config.has('server.port'); // true or false\n```\n\n#### merge(glob: string, options?: DotenvOptions): Promise\u003cvoid\u003e\nLoad other configuration files at runtime. This is great for package development.\n\n```ts\n@Module({})\nexport class PackageModule implements NestModule {\n\n    constructor(@InjectConfig() private readonly config) {}\n\n    async configure(consumer: MiddlewareConsumer) {\n        await this.config.merge(path.resolve(__dirname, '**/!(*.d).{ts,js}'));\n    }\n}\n```\n\n#### registerHelper(name: string, fn: (...args:any[]) =\u003e any): ConfigService\nRegister a custom global helper function\n\n```ts\nthis.config.registerHelper('isProduction', () =\u003e {\n    return this.get('express.environment') === 'production';\n});\n```\n\n#### resolveRootPath(path: string): typeof ConfigService\nchange the root path from where configs files are loaded\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { ConfigModule } from 'nestjs-config';\n\n@Module({\n    imports: [\n        ConfigModule.resolveRootPath(__dirname).load(path.resolve(__dirname, '**/!(*.d).{ts,js}')),\n    ],\n})\nexport class AppModule {}\n```\n\n#### root(path: string = ''): string\n\nReturns the current working dir or defined rootPath. \n\n```ts\nConfigService.root(); // /var/www/src\nConfigService.root('some/path/file.html'); // /var/www/src/some/path/file.html\n\nConfigService.resolveRootPath(__dirname).root(); // /var/www/src/app (or wherever resolveRootPath has been called with)\n```\n\n-----\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnestjsx%2Fnestjs-config","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnestjsx%2Fnestjs-config","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnestjsx%2Fnestjs-config/lists"}