> ## Documentation Index
> Fetch the complete documentation index at: https://encryptd.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Encrypting and Decrypting .env Files with the secure-env CLI

> Learn how to use the secure-env binary to encrypt plaintext .env files and decrypt .env.enc files from the command line with AES-256-GCM.

The `secure-env` binary ships with `@vernonthedev/encryptd` and exposes two subcommands: `encrypt` converts a plaintext `.env` file into an encrypted `.env.enc` JSON file, and `decrypt` reverses that process and prints the recovered plaintext to stdout. Both commands require the `ENV_PASSPHRASE` environment variable to be set before they run the CLI throws immediately if it is missing.

***

## `secure-env encrypt`

The `encrypt` command reads the plaintext input file, encrypts it with AES-256-GCM using a key derived from `ENV_PASSPHRASE` via PBKDF2-HMAC-SHA256, and writes the resulting `EnvPayload` JSON to the output file. A success message is printed to stdout on completion.

### Syntax

```sh theme={null}
ENV_PASSPHRASE="<passphrase>" npx secure-env encrypt [inputFile] [outputFile]
```

### Arguments

| Argument     | Type     | Default      | Description                                                                                                                                               |
| ------------ | -------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inputFile`  | `string` | `".env"`     | Path to the plaintext `.env` file to encrypt. Resolved relative to the current working directory. The file must exist or the command exits with an error. |
| `outputFile` | `string` | `".env.enc"` | Path where the encrypted JSON file will be written. Created or overwritten. Resolved relative to the current working directory.                           |

### Environment variables

| Variable         | Required | Description                                                                                                                                  |
| ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `ENV_PASSPHRASE` | Yes      | Passphrase used to derive the AES-256-GCM encryption key via PBKDF2-HMAC-SHA256. The command throws immediately if this variable is not set. |

### Examples

<CodeGroup>
  ```sh Default paths (.env → .env.enc) theme={null}
  ENV_PASSPHRASE="my-secret-passphrase" npx secure-env encrypt
  # Encrypted .env -> .env.enc
  ```

  ```sh Custom input and output paths theme={null}
  ENV_PASSPHRASE="s3cr3t" npx secure-env encrypt .env.production .env.production.enc
  # Encrypted .env.production -> .env.production.enc
  ```
</CodeGroup>

***

## `secure-env decrypt`

The `decrypt` command reads the encrypted JSON file produced by `secure-env encrypt`, decrypts it using `ENV_PASSPHRASE`, and prints the recovered plaintext to **stdout**. Nothing is written to disk and `process.env` is not mutated.

<Note>
  The `decrypt` command is a read-only operation. It prints decrypted content to stdout only it does **not** write a file to disk or load variables into `process.env`. To load decrypted variables into a running Node.js process, use the [`config()`](/usage/library) library function instead.
</Note>

### Syntax

```sh theme={null}
ENV_PASSPHRASE="<passphrase>" npx secure-env decrypt [inputFile]
```

### Arguments

| Argument    | Type     | Default      | Description                                                                                            |
| ----------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------ |
| `inputFile` | `string` | `".env.enc"` | Path to the encrypted `.env.enc` file to decrypt. Must be valid JSON matching the `EnvPayload` schema. |

### Environment variables

| Variable         | Required | Description                                               |
| ---------------- | -------- | --------------------------------------------------------- |
| `ENV_PASSPHRASE` | Yes      | Must exactly match the passphrase used during encryption. |

### Examples

<CodeGroup>
  ```sh Default path (.env.enc → stdout) theme={null}
  ENV_PASSPHRASE="my-secret-passphrase" npx secure-env decrypt
  # DATABASE_URL=postgres://localhost/mydb
  # API_KEY=abc123
  ```

  ```sh Custom input path theme={null}
  ENV_PASSPHRASE="s3cr3t" npx secure-env decrypt .env.production.enc
  ```

  ```sh Pipe decrypted output to a file (emergency recovery) theme={null}
  ENV_PASSPHRASE="s3cr3t" npx secure-env decrypt > .env.recovered
  ```
</CodeGroup>

***

## Exit behavior

The CLI exits with a non-zero status code (thrown `Error`) in the following situations:

| Condition                                            | Error message                                              |
| ---------------------------------------------------- | ---------------------------------------------------------- |
| `ENV_PASSPHRASE` not set                             | `[SrcIndex] Set ENV_PASSPHRASE env var.`                   |
| Input file does not exist                            | `[SrcIndex] <inputFile> not found.`                        |
| Decryption fails (wrong passphrase or tampered file) | `[RustLib] Decryption failed. Wrong key or tampered file.` |
| Encrypted file is not valid JSON                     | Standard `JSON.parse` error                                |

<Warning>
  If you receive `[RustLib] Decryption failed`, verify that `ENV_PASSPHRASE` is set to exactly the same value that was used when the file was encrypted including case and any special characters. The error is intentionally non-specific: the CLI cannot distinguish between a wrong passphrase and a tampered file.
</Warning>

***

## Usage without `npx`

If you install `@vernonthedev/encryptd` as a local dev dependency, the `secure-env` binary is available inside `node_modules/.bin/`. You can invoke it directly or register it as an npm script to avoid typing the full path every time.

<Tabs>
  <Tab title="pnpm exec">
    ```sh theme={null}
    ENV_PASSPHRASE="s3cr3t" pnpm exec secure-env encrypt
    ENV_PASSPHRASE="s3cr3t" pnpm exec secure-env decrypt
    ```
  </Tab>

  <Tab title="Direct binary path">
    ```sh theme={null}
    ENV_PASSPHRASE="s3cr3t" ./node_modules/.bin/secure-env encrypt
    ENV_PASSPHRASE="s3cr3t" ./node_modules/.bin/secure-env decrypt
    ```
  </Tab>

  <Tab title="npm scripts">
    Add the commands to your `package.json` so you can run them without specifying the binary path:

    ```json package.json theme={null}
    {
      "scripts": {
        "encrypt": "secure-env encrypt",
        "decrypt": "secure-env decrypt"
      }
    }
    ```

    Then invoke them with:

    ```sh theme={null}
    ENV_PASSPHRASE="s3cr3t" npm run encrypt
    ENV_PASSPHRASE="s3cr3t" npm run decrypt
    ```
  </Tab>
</Tabs>
