---
title: Migrate from dotenv
description: How to migrate from dotenv (CLI and npm package) to varlock
---
import InstallJsDepsWidget from "@/components/InstallJsDepsWidget.astro";
import ExecCommandWidget from "@/components/ExecCommandWidget.astro";
import { TabItem, Tabs } from "@astrojs/starlight/components";

## Why migrate from dotenv?

- **Validation**: Catch misconfigurations early with schema-driven validation.
- **Security**: Redact secrets and prevent accidental leaks.
- **Type-safety**: Generate types automatically for your config.
- **External secrets**: Load secrets from providers like 1Password, AWS, and more.

---

## Migrating from dotenvx CLI

If you use `dotenvx` via the CLI, you can switch to `varlock run`:

```bash
# Before (dotenv CLI)
dotenvx run -- node app.js

# env specific
dotenvx run -f .env.staging -- node app.js

# install varlock
brew install dmno-dev/tap/varlock

# After (varlock CLI)
varlock run -- node app.js

# To specify an environment, set your env flag (see your .env.schema)
APP_ENV=staging varlock run -- node app.js
```

> You can use multiple `.env` files (see [Environments guide](/guides/environments)).

---

## Migrating from dotenv npm package

Initialize your project with `varlock init` to install `varlock` and generate a `.env.schema` from any existing `.env` files.

<ExecCommandWidget command="varlock init" showBinary={false} dlx={true} />

Then to use `varlock` in your code, you can replace `dotenv/config` with `varlock/auto-load`:

```diff title="index.js" 
// Before (dotenv)
- import 'dotenv/config';
+ import 'varlock/auto-load';
```

Finally, you can remove `dotenv` from your dependencies:

<InstallJsDepsWidget packages="dotenv" remove />

## Using overrides

If `dotenv` is being used under the hood of one of your dependencies, you can use `overrides` to seamlessly swap in `varlock` instead.


<Tabs syncKey='package-manager'>
      
  <TabItem label="npm">
    See [NPM overrides docs](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides)

    ```diff lang="json" title="package.json"
    {
    +  "overrides": {
    +    "other-dep": {
    +      "dotenv": "npm:varlock"
    +    }
    +  }
    }
    ```
  </TabItem>

  <TabItem label="yarn">
    See [yarn resolutions docs](https://yarnpkg.com/configuration/manifest#resolutions)

    ```diff lang="json" title="package.json"
    {
    +  "resolutions": {
    +    "**/dotenv": "npm:varlock"
    +  },
    }
    ```
    **In a monorepo, this override must be done in the monorepo's root package.json file!**
  </TabItem>

  <TabItem label="pnpm">
    <Tabs syncKey='pnpm-version'>
      <TabItem label="pnpm version 10+">
        See [pnpm v10 overrides docs](https://pnpm.io/settings#overrides)

        ```diff lang="yaml" title="pnpm-workspace.yaml"
        +overrides:
        +  "dotenv": "npm:varlock"
        ```
        
        **This must be set in `pnpm-workspace.yaml`, which lives at the root of your repo, regardless of whether you are using a monorepo or not.**

      </TabItem>
      <TabItem label="pnpm version 9">
        ### pnpm version 9
        See [pnpm v9 overrides docs](https://pnpm.io/9.x/package_json#pnpmoverrides)

        ```diff lang="json" title="package.json"
        {
        +  "pnpm": {
        +    "overrides": {
        +      "dotenv": "npm:varlock"
        +    }
        +  }
        }
        ```
        **In a monorepo, this override must be done in the monorepo's root package.json file!**
        
      </TabItem>
    </Tabs>
  </TabItem>
</Tabs>

---

## Further reading

- [Environments guide](/guides/environments)
- [Schema guide](/guides/schema)
- [Reference: CLI commands](/reference/cli-commands)
- [Reference: Item decorators](/reference/item-decorators) 
