Skip to main content
Capy’s runtime story is one command: capy run -- <your command>. It wraps any process, decrypts .env in memory, and hands the plaintext values to the child as ordinary environment variables. Your app reads process.env (or os.environ, or ENV[...], or whatever your language uses) - no library to import, no SDK per language.

The pattern

Capy:
  1. Reads .env from the current directory.
  2. Resolves the project key from the first available source (local keyring, deploy code env var, or explicit CAPY_KEY).
  3. Decrypts every capy:… snippet.
  4. Spawns the child with the decrypted values set in its environment.
  5. Forwards SIGINT, SIGTERM, and SIGHUP to the child; exits with the child’s exit code.
The plaintext lives only in the child process’s memory - never written to disk.

Examples

In package.json scripts

Put capy run in your scripts once and forget about it:
Then bun run dev / npm run dev / pnpm dev all work as usual; the wrapping is invisible.

Precedence: shell env vs. decrypted .env

If a variable is already set in the shell (or by the platform running capy run), capy run leaves it alone. Only variables that appear in .env as capy:… snippets get decrypted into the child’s environment. That matches dotenv’s usual precedence: explicit env wins over file-based env.

What’s next

Deploying

How the runtime key source gets set in production.

capy run (CLI reference)

Flags and behavior details.
Last modified on May 20, 2026