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

# Next.js Environment Variables: Encrypted Secrets

> Use Capy to encrypt Next.js secrets across dev, build, and deploy. Build-time inlining for static pages, runtime decryption for Edge and Node routes.

Capy works with Next.js across every runtime (Node, Edge) and every deploy target (Vercel, self-hosted). Wrap `next dev` and `next build` with `capy run` and read `process.env` as you always have.

<Steps>
  <Step title="Install the CLI">
    <CodeGroup>
      ```bash brew theme={null}
      brew install capysc/tap/capy
      ```

      ```bash npm theme={null}
      npm install -g @capysc/cli
      ```

      ```bash bun theme={null}
      bun add -g @capysc/cli
      ```
    </CodeGroup>

    Also add it as a dev dependency so your deploy platform installs it during builds:

    ```bash theme={null}
    bun add -D @capysc/cli
    ```
  </Step>

  <Step title="Sync your secrets">
    From a project that has a `.env`:

    ```bash theme={null}
    capy
    ```

    Capy authenticates you, creates a project on first run, encrypts every value in `.env`, and gitignores the file. Only `keep.lock` (a small versioning manifest) is committed.
  </Step>

  <Step title="Wrap dev and build in package.json">
    ```json theme={null}
    {
      "scripts": {
        "dev": "capy run -- next dev",
        "build": "capy run -- next build",
        "start": "capy run -- next start"
      }
    }
    ```

    `bun run dev` / `npm run dev` / `pnpm dev` all work as usual. `capy run` decrypts `.env` in memory and hands plaintext values to Next via `process.env`. Both Node and Edge routes read them the standard way:

    ```ts theme={null}
    const db = process.env.DATABASE_URL;
    ```
  </Step>

  <Step title="Invite a teammate">
    ```bash theme={null}
    capy invite teammate@example.com
    ```

    Capy prints a one-line redeem code. Send it out-of-band. They run `capy redeem <code>` and now share access.
  </Step>

  <Step title="Deploy to Vercel">
    Run:

    ```bash theme={null}
    capy deploy
    ```

    Pick **Vercel**. Capy prints two environment variables - `SECRETS_BLOB` and `PROJECT_KEY` - to paste into your Vercel project's **Settings → Environment Variables** (or `vercel env add`). Repeat for Preview / Development if you want Capy to decrypt there too.

    Next, point `next.config.js` at Capy's auto-generated env map:

    ```js theme={null}
    const capyEnv = require("./.capy/next-env");

    module.exports = {
      env: capyEnv,
    };
    ```

    That's it. On every `vercel deploy`:

    1. Vercel clones your branch, installs `@capysc/cli`, runs `capy run -- next build`.
    2. `capy run` sees `SECRETS_BLOB` + `PROJECT_KEY`, enters deployed mode, calls Capy's service to reconstruct the decrypt key, expands the blob into individual env vars, and writes `.capy/next-env.js` listing them.
    3. `next build` runs with plaintext env vars set, and Next inlines every variable named in the `env` field as a string literal in the compiled bundle.
    4. Runtime functions (Node and Edge) read the inlined literals. No runtime decryption, no service call per request.

    Add a secret to `.env`, run `capy`, redeploy - Next picks it up automatically from the regenerated `next-env.js`. No `next.config.js` churn.
  </Step>
</Steps>

## Edge vs. Node routes

Both work the same way. Capy values land in `process.env` at build time via Next's `env` config, and Next replaces `process.env.X` references with string literals during compilation. The resulting code has no runtime env lookup, so it runs identically in Node and Edge isolates.

## App Router, Pages Router, Middleware

All three read from `process.env` the standard way. No Capy-specific imports, no initialization call, no runtime library. The only Capy touchpoint in the Next codebase is the two lines in `next.config.js`.

## Self-hosted Next.js

Skip the `next.config.js` change and the Vercel env vars. Just set `capy run` as the process entrypoint:

```bash theme={null}
capy run -- next start
```

In this mode `capy run` decrypts via the local keyring (dev) or a locally-present `SECRETS_BLOB` + `PROJECT_KEY` (containers, long-running servers where you've set those manually).

## What's next

<Columns cols={2}>
  <Card title="Deploying" icon="rocket" href="/using/deploying" horizontal>
    Other platforms, CI/CD patterns, revocation.
  </Card>

  <Card title="capy run" icon="terminal" href="/cli/run" horizontal>
    Local and deployed modes in detail.
  </Card>
</Columns>
