> ## 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.

# Encrypt and Load Your .env File Securely at Runtime

> Go from a plaintext .env to a securely encrypted .env.enc committed to git then decrypt it automatically at runtime using encryptd's config() function.

This guide walks you through encrypting your first `.env` file and loading the decrypted variables into a Node.js application at runtime. By the end you will have a workflow where only `.env.enc` lives in your repository and your secrets never touch version control in plaintext.

<Warning>
  Never commit your passphrase or your original `.env` file to version control. The passphrase is the only thing protecting your encrypted file treat it like a password. Store it in a secret manager and make sure `.env` is listed in your `.gitignore`.
</Warning>

<Steps>
  <Step title="Install encryptd">
    If you have not installed encryptd yet, follow the [Installation guide](/installation) to configure GitHub Packages and add the package to your project. Then come back here.
  </Step>

  <Step title="Set your passphrase">
    Export your passphrase as an environment variable in your current shell session. Use a long, random string this is the secret that protects your encrypted file.

    ```bash theme={null}
    export ENV_PASSPHRASE="your-strong-passphrase"
    ```

    encryptd reads `ENV_PASSPHRASE` automatically in both the CLI and the library, so you do not need to hardcode it anywhere in your application code.

    <Tip>
      In CI/CD environments such as GitHub Actions, store the passphrase as an encrypted repository secret and inject it as an environment variable in your workflow. Add `ENV_PASSPHRASE: ${{ secrets.ENV_PASSPHRASE }}` to your workflow's `env` block. This keeps the value out of your source code and out of your build logs.
    </Tip>
  </Step>

  <Step title="Encrypt your .env file">
    Run the `encrypt` command from your project root. By default, encryptd reads `.env` and writes the encrypted output to `.env.enc`:

    ```bash theme={null}
    ENV_PASSPHRASE="your-strong-passphrase" npx secure-env encrypt
    ```

    To encrypt a different file or write to a custom output path, pass the source and destination paths explicitly:

    ```bash theme={null}
    ENV_PASSPHRASE="your-strong-passphrase" npx secure-env encrypt .env.production .env.production.enc
    ```

    After the command succeeds, you will find a `.env.enc` file in your project root containing a JSON blob with the encrypted salt, IV, ciphertext, and authentication tag.
  </Step>

  <Step title="Commit .env.enc and update .gitignore">
    Add `.env.enc` to version control and make sure the original `.env` is excluded:

    ```bash theme={null}
    # Add the encrypted file to version control
    git add .env.enc

    # Ensure the plaintext file is ignored
    echo ".env" >> .gitignore
    git add .gitignore
    ```

    Your teammates and your CI pipeline can now decrypt `.env.enc` using the shared passphrase without the plaintext file ever entering the repository.
  </Step>

  <Step title="Load encrypted variables in your application">
    Call `config()` early in your application's entry point, before any code that reads from `process.env`. It decrypts `.env.enc`, parses the key-value pairs, and writes them into `process.env`.

    ```typescript theme={null}
    import { config } from '@vernonthedev/encryptd';

    // Decrypts .env.enc using ENV_PASSPHRASE and populates process.env
    const env = config();

    console.log(env.DATABASE_URL);
    ```

    `config()` also accepts an options object when you need to customise the behaviour:

    ```typescript theme={null}
    import { config } from '@vernonthedev/encryptd';

    const env = config({
      path: '.env.production.enc',   // custom encrypted file path
      passphrase: 'your-passphrase', // inline passphrase (prefer ENV_PASSPHRASE)
      override: true,                // overwrite keys already set in process.env
    });
    ```

    `config()` returns a `Record<string, string>` containing every decrypted variable, so you can use the return value directly instead of reading from `process.env` if you prefer.
  </Step>
</Steps>

## Decrypt from the CLI

You can also decrypt an encrypted file back to plaintext using the `decrypt` subcommand. This is useful for inspecting the file, rotating secrets, or applying it to an environment that cannot run Node.js code.

```bash theme={null}
ENV_PASSPHRASE="your-strong-passphrase" npx secure-env decrypt .env.enc
```

The command decrypts the file and prints the plaintext key-value pairs to standard output. The syntax is:

```text theme={null}
secure-env decrypt [inputFile]
```

If `inputFile` is omitted, `secure-env decrypt` reads from `.env.enc` in the current directory.

## Low-level library API

For advanced use cases such as encrypting or decrypting strings programmatically without touching the filesystem encryptd exports `encryptEnv` and `decryptEnv` directly.

### `encryptEnv(plainText, passphrase)`

Encrypts a plaintext string and returns an `EnvPayload` object containing all fields needed to decrypt it later.

```typescript theme={null}
import { encryptEnv } from '@vernonthedev/encryptd';

const payload = encryptEnv('DATABASE_URL=postgres://localhost/mydb\nAPI_KEY=secret', 'your-strong-passphrase');

// payload satisfies EnvPayload:
// {
//   version?: number;
//   salt: string;   // base64-encoded random salt (used in key derivation)
//   iv: string;     // base64-encoded 96-bit nonce
//   content: string; // base64-encoded ciphertext
//   tag: string;    // base64-encoded GCM authentication tag
// }
console.log(payload);
```

### `decryptEnv(payload, passphrase)`

Decrypts an `EnvPayload` produced by `encryptEnv` and returns the original plaintext string.

```typescript theme={null}
import { encryptEnv, decryptEnv } from '@vernonthedev/encryptd';

const payload = encryptEnv('API_KEY=mysecret', 'your-strong-passphrase');
const plaintext = decryptEnv(payload, 'your-strong-passphrase');

console.log(plaintext); // 'API_KEY=mysecret'
```

### Type reference

```typescript theme={null}
interface EnvPayload {
  version?: number;
  salt: string;     // base64-encoded random salt
  iv: string;       // base64-encoded 96-bit nonce
  content: string;  // base64-encoded ciphertext
  tag: string;      // base64-encoded GCM authentication tag
}

interface ConfigOptions {
  path?: string;       // path to the encrypted file (default: '.env.enc')
  passphrase?: string; // inline passphrase (default: process.env.ENV_PASSPHRASE)
  override?: boolean;  // if true, overwrite keys already set in process.env
}
```
