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

# encryptd JavaScript API: config, encryptEnv, and decryptEnv

> Learn how to use config(), encryptEnv(), and decryptEnv() from @vernonthedev/encryptd to load and manage encrypted .env files in Node.js.

`@vernonthedev/encryptd` exports three public functions you can use directly in your Node.js application code. The high-level `config()` function covers the common case of loading an encrypted `.env.enc` file into `process.env` at startup. The lower-level `encryptEnv()` and `decryptEnv()` functions are thin TypeScript wrappers around the Rust native addon and give you direct access to the AES-256-GCM primitives when you need programmatic control for example, in a key-rotation or secret-management script.

***

## Importing the package

Start by importing the functions you need from `@vernonthedev/encryptd`:

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

***

## `config(options?)`

Call `config()` early in your application's entry point, before any code that reads from `process.env`. It reads the encrypted env file, decrypts it using the passphrase, parses the key-value pairs according to standard `.env` conventions, and writes them into `process.env`. It also returns all parsed pairs as a plain object so you can use values directly without reading from `process.env`.

Parsing follows standard `.env` conventions: blank lines and `#` comments are ignored, quoted values have their surrounding quotes stripped, and keys that already exist in `process.env` are left untouched unless you set `override: true`.

<Steps>
  <Step title="Call config() with defaults">
    With no arguments, `config()` reads `.env.enc` from the current working directory and uses `ENV_PASSPHRASE` from the environment for decryption:

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

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

    console.log(env.DATABASE_URL);
    ```
  </Step>

  <Step title="Call config() with all options">
    Pass an options object to customise the file path, supply the passphrase inline, or force-overwrite existing `process.env` keys:

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

    const env = config({
      path: '.env.production.enc',    // custom file path (default: ".env.enc")
      passphrase: process.env.MY_SECRET, // explicit passphrase (falls back to ENV_PASSPHRASE)
      override: true,                 // overwrite keys already in process.env (default: false)
    });

    console.log(env.DATABASE_URL);
    ```
  </Step>

  <Step title="Use the return value">
    `config()` returns a `Record<string, string>` containing every key-value pair parsed from the decrypted file. All values are strings, mirroring the behaviour of `process.env`:

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

    const env = config();

    // Access values directly from the return value
    const dbUrl: string = env.DATABASE_URL;
    const apiKey: string = env.API_KEY;

    // Or read from process.env both hold the same values
    console.log(process.env.DATABASE_URL === env.DATABASE_URL); // true
    ```
  </Step>
</Steps>

### Parameters

| Option               | Type      | Default      | Description                                                                                                                                                          |
| -------------------- | --------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `options.path`       | `string`  | `".env.enc"` | Path to the encrypted env file, resolved relative to `process.cwd()`. Accepts relative and absolute paths.                                                           |
| `options.passphrase` | `string`  | —            | Passphrase for PBKDF2 key derivation and AES-256-GCM decryption. Falls back to `process.env.ENV_PASSPHRASE` when omitted. Throws if neither source provides a value. |
| `options.override`   | `boolean` | `false`      | When `false`, keys already present in `process.env` are preserved. Set to `true` to overwrite them with values from the encrypted file.                              |

***

## `encryptEnv(plainText, passphrase)`

`encryptEnv()` is a low-level Rust bridge that encrypts an arbitrary UTF-8 string with AES-256-GCM. It generates a fresh random 16-byte PBKDF2 salt and a fresh random 96-bit nonce on every call, so the same input always produces a different ciphertext. It returns an `EnvPayload` object containing the hex-encoded salt, IV, ciphertext, and GCM authentication tag.

<Note>
  Most application code does not need to call `encryptEnv()` directly. Use the `secure-env encrypt` CLI command to produce `.env.enc` files as part of your workflow, and call `config()` at runtime to load them. Reserve `encryptEnv()` and `decryptEnv()` for programmatic use cases such as key-rotation scripts, secret-management tooling, or test fixtures that need to generate encrypted payloads on the fly.
</Note>

<CodeGroup>
  ```typescript Basic usage theme={null}
  import { encryptEnv } from '@vernonthedev/encryptd';

  const payload = encryptEnv(
    'DATABASE_URL=postgres://localhost/mydb\nAPI_KEY=abc123',
    'my-passphrase'
  );

  console.log(payload);
  // { version: 1, salt: '...', iv: '...', content: '...', tag: '...' }
  ```

  ```typescript Serialise encrypted payload to disk theme={null}
  import { encryptEnv } from '@vernonthedev/encryptd';
  import { writeFileSync, readFileSync } from 'fs';

  const plaintext = readFileSync('.env', 'utf-8');
  const payload = encryptEnv(plaintext, process.env.ENV_PASSPHRASE!);

  writeFileSync('.env.enc', JSON.stringify(payload, null, 2), 'utf-8');
  ```
</CodeGroup>

### Parameters

| Parameter    | Type     | Required | Description                                                                                                           |
| ------------ | -------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
| `plainText`  | `string` | Yes      | The UTF-8 string to encrypt. For `.env` use-cases this is the raw file contents, but the function accepts any string. |
| `passphrase` | `string` | Yes      | Passphrase passed to PBKDF2-HMAC-SHA256 (100,000 iterations) to derive the 256-bit AES key.                           |

***

## `decryptEnv(payload, passphrase)`

`decryptEnv()` is the counterpart low-level Rust bridge that decrypts an `EnvPayload` produced by `encryptEnv()` or by the `secure-env encrypt` CLI. The GCM authentication tag is verified automatically, if the tag does not match, meaning the wrong passphrase was supplied or the ciphertext was tampered with, the function throws a `[RustLib] Decryption failed` error.

<CodeGroup>
  ```typescript Basic usage theme={null}
  import { decryptEnv } from '@vernonthedev/encryptd';
  import { readFileSync } from 'fs';

  const payload = JSON.parse(readFileSync('.env.enc', 'utf-8'));
  const plainText = decryptEnv(payload, 'my-passphrase');

  console.log(plainText);
  // DATABASE_URL=postgres://localhost/mydb
  // API_KEY=abc123
  ```

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

  const original = 'DATABASE_URL=postgres://localhost/mydb\nSECRET=hunter2';
  const payload  = encryptEnv(original, 'my-passphrase');
  const restored = decryptEnv(payload, 'my-passphrase');

  console.log(original === restored); // true
  ```
</CodeGroup>

### Parameters

| Parameter    | Type         | Required | Description                                                                                                           |
| ------------ | ------------ | -------- | --------------------------------------------------------------------------------------------------------------------- |
| `payload`    | `EnvPayload` | Yes      | The `EnvPayload` object to decrypt. All four fields (`salt`, `iv`, `content`, `tag`) must be present and hex-encoded. |
| `passphrase` | `string`     | Yes      | The passphrase used during the original encryption. Must match exactly, including case and special characters.        |

<Warning>
  The `[RustLib] Decryption failed` error intentionally does not distinguish between a wrong passphrase and a tampered file. This is by design revealing which condition occurred would weaken the authentication guarantee provided by AES-256-GCM.
</Warning>

***

## Errors

All errors thrown by `@vernonthedev/encryptd` are standard JavaScript `Error` objects. The message always starts with a source prefix `[SrcIndex]` for errors originating in the TypeScript layer, or `[RustLib]` for errors originating in the Rust native addon to make stack traces easier to triage.

| Error message                                                                                  | Cause                                                                                                         |
| ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `[SrcIndex] ENV_PASSPHRASE not set. Pass it via options.passphrase or ENV_PASSPHRASE env var.` | `config()` was called without `options.passphrase` and `process.env.ENV_PASSPHRASE` is not set.               |
| `[SrcIndex] Encrypted env file not found at <path>`                                            | The resolved file path does not exist. Check `options.path` and the current working directory.                |
| `[SrcIndex] Invalid encrypted env file at <path>. Expected valid JSON.`                        | The file exists but could not be parsed as JSON. The file may be corrupt or not an `EnvPayload`.              |
| `[RustLib] Decryption failed. Wrong key or tampered file.`                                     | The GCM authentication tag did not verify. Either the passphrase is wrong or the ciphertext was modified.     |
| `[RustLib] Invalid salt hex: ...`                                                              | The `salt` field in the payload is not valid hexadecimal. The file may be corrupt or hand-edited incorrectly. |
| `[RustLib] Invalid IV hex: ...`                                                                | The `iv` field in the payload is not valid hexadecimal. The file may be corrupt or hand-edited incorrectly.   |
