Docs
Guidesince 1.0.0-alpha.3

Quickstart

The first minute needs no account. The second minute moves your values to the cloud and deletes the file.

Five commands, in a repository that already has a .env.

From your file to your team

Write the schema

penv init

init reads the .env beside you and writes .env.schema. It adds .env to your .gitignore on the way.

At a terminal it offers a picker over every coding agent harness penv knows, with the ones it found installed here already ticked. A harness counts as installed when its config folder is on disk or its binary is on your PATH. init also generates the typed file for each language your repository uses.

It prints what it inferred:

KEY                TYPE     REQUIRED  SENSITIVE
DATABASE_URL       url      yes       yes
STRIPE_SECRET_KEY  string   yes       yes
PORT               port     no        no

With no .env there, init writes an empty one and tells you to add keys and run penv init --force.

Run your app

penv run -- pnpm dev

The values go into that child process and nowhere else. penv validates first, so a missing or wrong value stops the run with the key named instead of a crash three seconds in.

When a coding agent is driving the session, penv scrubs every sensitive value out of the child's output as it streams.

Sign in

penv login

penv prints an eight-character code and the page to open, and opens a browser for you when you are at a terminal. Approve that code and the credential lands in your operating system keychain, good for 30 days from its last use.

Move the values to the cloud

penv push

When .env.schema has no @penv= header, penv says which project it is about to create. It creates that project with a development environment and writes the slug the server returned into the header. Then it sends every key with the value the file holds, and deletes .env.

Change it once. It lands everywhere your code runs.

Hand it to your team

A teammate clones the repository and types:

penv run -- pnpm dev

That is the whole onboarding. There is no file to send them.

What is in your repository now

PathCommittedWhat it is
.env.schemayesThe one penv file. Names, types, and which keys are required.
.envnoGone after push. penv pull writes it again when you need it.
.penv/targets/<name>/target.tomlyesWhere your typed file goes, so nobody is asked twice.

Which environment you are reading

penv takes the first of these that says something:

  • --env on the command line
  • PENV_ENV in the environment penv itself was started with
  • development, when neither of the first two says anything

In local mode development is the only environment there is, and every other name is refused with exit code 6.

A person reads an environment when they hold a role scoped to it, granted on that project's Access page in the console. Without one the server answers 403 and penv reports environment_refused, exit code 6. A machine reads only the environment its credential is bound to.

Adopt an app that already has a .env file