Skip to content
Download

@sct/env

Loads a project's .sct secrets into process.env and keeps them current.

npm install @sct/env

Needs macOS, Node.js 22.18+ or Bun, and sct on PATH.

Set up sct once

The SDK starts the sct command. Install it first.

  1. bun run package:macBuilds the signed app from the repo.
  2. bun run install:cliWrites the sct command to ~/.local/bin.
  3. open dist/sct-darwin-arm64/sct.appRegister the folder and save its secrets.

Load before imports

Static imports run before loadEnv(). Import modules that read process.env on load after it.

boot.ts
import { loadEnv } from '@sct/env'import Stripe from 'stripe'
// Reads this project's secrets from macOS Keychain into process.env.await loadEnv({  onChange: () => console.log('process.env updated'),})
export const stripe = new Stripe(process.env.STRIPE_KEY)

React to changes

Saved changes reach process.env in about 500 ms. Rebuild clients that copied a credential.

boot.ts
await loadEnv({  onChange: () => rebuildClients(),  onError: (error) => reportSecretAccessFailure(error),})

Stop updates

Call loadEnv() once at startup. Each call owns one helper until it stops or the app exits.

boot.ts
const stop = await loadEnv()
// Ends the helper and puts inherited values back.stop()

Options

Project secrets override inherited variables. Deleting a key restores the inherited value.

OptionTypeWhat it does
projectstringAn exact registered project name. Without it, the SDK uses the nearest registered parent folder.
onChange() => voidRuns after each later update, never after the first load.
onError(error: Error) => voidRuns when a later read fails. Without it, a message with no values goes to stderr.

Other loaders

Libraries read process.env. They never read or decrypt the vault file.

dotenv
Keeps injected variables. Code that requires a .env read must handle the missing file.
Bun
Its automatic .env load does not read the vault. process.env already holds the values.
Vite
VITE_ variables reach browser code. Keep private credentials out of public prefixes.

The SDK belongs in trusted server code. Browser bundles cannot use it.