# @nestjs/config: the dotenv bridge for Nest applications

> The @nestjs/config package is the configuration module for the Nest framework, built on dotenv for loading process environment variables, with dotenv-expand for variable interpolation and the standard-schema spec for validation. The version numbering jumped from 4.0.4 to 12.0.0 in 2026 to track the Nest major release.

**nestjs/config** — Configuration module for Nest framework (node.js) 🍓

- Repository: https://github.com/nestjs/config
- Website: https://nestjs.com
- Stars: 592 · Forks: 105
- Language: TypeScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/nestjs-config

## A thin package with one job and four dependencies

The description of this repository is short: configuration module for the Nest framework, based on the dotenv package to load process environment variables. That is the entire scope, and the project is part of the wider Nest framework family, which is a progressive Node.js framework for building efficient and scalable server-side applications.

The dependency list in package.json is short and tells you what the package actually does. dotenv at 18.0.3 is the core, the library that reads a .env file into process.env. dotenv-expand at 13.0.0 is the second half of the story, and it is the one people are often surprised by: it expands variable references, so a value like DATABASE_URL can be assembled from other variables in the file. es-toolkit at 1.52.0 is a general purpose utility library. And @standard-schema/spec at 1.1.0 is the shared validation interface.

That last dependency is the interesting one for a configuration package. The standard schema specification is a common interface implemented by multiple validation libraries, and its presence here means the package can validate configuration without pinning you to one validator. The dev dependencies back that reading: zod, valibot and joi are all present, each at a recent version, alongside the standard schema spec itself.

The README does not document the validation behaviour, so this is an inference from the dependency list rather than a documented feature. But it is a reasonable one, and it is the kind of thing to verify in the Nest configuration guide rather than assume.

The package is MIT licensed, the author is Kamil Mysliwiec, and the framework homepage is nestjs.com.

## Installation and where the actual documentation lives

Installation is one command:

```bash
$ npm i --save @nestjs/config
```

And that is the extent of the README's own instructions, which tells you something about the division of labour. The quick start section does not describe the API, it links to an overview and tutorial on the Nest documentation site, under techniques and configuration.

That is a deliberate choice for a first-party module of a framework. The package is the mechanism, and the guide on docs.nestjs.com is the documentation. It also means the documentation lives in a different repository and follows the framework's own release cycle, so the version of the guide you read may not match the version of the package you have pinned.

The install command itself is worth noting for its shape. It uses the --save flag explicitly, which is the older npm behaviour, and the package is scoped under @nestjs, so the full name is @nestjs/config. The manifest agrees, with the name field set to @nestjs/config and the version at 12.0.1.

The support and contact details in the README are the framework's rather than the package's: the Nest Discord, the Open Collective backers and sponsors, the PayPal donation link, the Twitter account and the project website. Nest is described as an MIT-licensed open source project that can grow thanks to the sponsors and support by the amazing backers.

So if you are evaluating this package, the questions to ask are mostly questions about the framework rather than about the code, which is a reasonable signal of how small the code is.

## An ES module package with an explicit exports map

The package.json shows a project that has been modernised rather than left on the old CommonJS defaults.

The type field is set to module, so the package is an ES module. The main field points at ./dist/index.js, types at ./dist/index.d.ts, and there is an exports map that separates the import condition from the default condition, with the type declarations hoisted above the import entry so that TypeScript picks them up regardless of which condition applies:

```json
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js",
      "default": "./dist/index.js"
    },
    "./package.json": "./package.json"
  },
```

Exposing ./package.json as a subpath is a small courtesy that tooling sometimes needs, and it costs nothing.

The build script is rimraf -rf dist followed by tsc -p tsconfig.json, so the TypeScript compiler produces the distribution directly with no bundler in the middle. That is a deliberate simplicity, and it means there is no bundler config to keep in step with the framework.

The type declaration file at ./dist/index.d.ts is the public contract, and since the package is small, that file is short enough to read in full before you depend on it. If you are wondering whether a particular configuration hook exists, reading the type definitions is faster than searching documentation.

The peer dependency block exists and is truncated in the source available, which is worth noting because it tells you the package is not standalone. It is a module for Nest, and it declares its compatibility with the framework there rather than leaving it implicit.

## The test and lint stack, and the two release tracks

The tooling in the repository is worth reading because it shows how the package is verified and how it ships.

Tests run on Vitest, with the script test:integration running vitest run against a vitest.config.mts file. The .mts extension on the config is the TypeScript variant that is treated as an ES module, which is consistent with the package being type module. The tests/ directory sits at the top level next to lib/.

Linting has moved to oxlint, with the lint script running oxlint lib/ with the fix flag, and formatting is handled by prettier over the lib and test directories with the configuration in .prettierrc. The combination of oxlint for linting and prettier for formatting is the modern layout, since prettier does not handle lint rules and the two tools no longer overlap.

The release process has two tracks, which is visible in the scripts. The main line runs npm run build and then npm publish with public access. The next line does the same but publishes with the next tag, and both have matching prepublish hooks that build first. The release script itself is release-it, and there is a .release-it.json configuration alongside a .commitlintrc.json using the config-angular preset, which is a conventional commit format enforced at commit time rather than at release time.

Continuous integration is CircleCI, with a .circleci/ directory, and there is a renovate.json for dependency updates. The .nvmrc file pins the Node version used for development, and a .npmignore and .gitignore handle what goes into the published tarball.

The version history in the repository is worth reading for what it says about the project. Version 4.0.4 was published on 2026-04-09, then 12.0.0 on 2026-08-27 and 12.0.1 on 2026-09-22, and the last push was on 2026-10-19. The jump from 4.x to 12.x is the tell: the package version now follows the Nest framework major version, so a Nest 12 application gets config 12, and the old 4.x line was the previous scheme.

## What this package deliberately leaves out

Because the scope is narrow, it is worth being explicit about what the package does not try to be.

It is not a configuration store. There is no database of settings, no admin panel, no runtime flag flipping, and no mechanism for changing configuration without a restart. The package's job is to get values from the environment into the application at startup, and everything it does serves that.

It is not a secret manager either. The values arrive in process.env, which means they arrive from wherever your process environment comes from, and whatever protections apply to that apply here. In a container that is the orchestrator's environment, and on a developer machine it is a .env file. The package's dotenv dependency gives you a file format and a parser; it does not give you a place to keep credentials.

It is not a schema library, even though it depends on the standard schema spec and the dev dependencies include zod, valibot and joi. The presence of the spec is what lets validation plug in without a hard dependency on one validator, but the validation library itself is yours to choose and to add.

The one behaviour that is easy to inherit without noticing is dotenv-expand. Variable interpolation means a value in your environment can be assembled from other values in the environment, which is convenient when a database URL is composed from a host, a port and a name, and which is a surprise when a value you expected to be literal expands into something else. If you want literal values, that is a setting to check in the guide rather than something to discover in production.

That is the whole boundary. A small package that does one thing, leaves the choice of validator open, and inherits its interpolation behaviour from a dependency whose semantics you should read before you rely on them.

## Conclusion

nestjs/config suits a Nest application that needs environment variables loaded and validated in one place instead of scattered process.env reads, and the standard-schema dependency means validation can be wired to whichever validation library a project already uses. It does not suit you if you want configuration beyond environment variables, since the whole package is a dotenv bridge and anything more elaborate is out of scope. Before you adopt it, read the configuration guide linked from the README, check which Nest major your project runs against because the package version now follows it, and confirm that dotenv-expand is what you want, since interpolation of values that reference other variables is a behaviour your configuration will inherit.

## FAQ

### How do I install the @nestjs/config package?

Run npm i --save @nestjs/config. The README itself points to the Nest configuration guide, an overview and tutorial under techniques and configuration on docs.nestjs.com, for the actual usage documentation.

### What does @nestjs/config use to load environment variables?

It is based on dotenv for loading process environment variables, with dotenv-expand at 13.0.0 for expanding variable references, es-toolkit for general utilities, and the @standard-schema/spec for validation.

### Why did the @nestjs/config version jump from 4.0.4 to 12.0.0?

The package version now follows the Nest framework major version. Version 4.0.4 was published on 2026-04-09 and 12.0.0 on 2026-08-27, so a Nest 12 application pairs with config 12 while the old 4.x line was the previous numbering scheme.

### How is the @nestjs/config package tested and released?

Tests run on Vitest with vitest run against vitest.config.mts, linting uses oxlint and formatting uses prettier. Releases go through release-it with a .release-it.json configuration, and there are separate publish scripts for the main line and for the next tag, both of which build first through a prepublish hook.

## Sources

- [License: MIT](https://github.com/nestjs/config/blob/master/LICENSE)
- [nestjs/config on GitHub](https://github.com/nestjs/config)
- [Project website](https://nestjs.com)
- [README](https://github.com/nestjs/config/blob/master/README.md)
- [Releases](https://github.com/nestjs/config/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nestjs-config
