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 initinit 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 noWith 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 devThe 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 loginpenv 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 pushWhen .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 devThat is the whole onboarding. There is no file to send them.
What is in your repository now
| Path | Committed | What it is |
|---|---|---|
.env.schema | yes | The one penv file. Names, types, and which keys are required. |
.env | no | Gone after push. penv pull writes it again when you need it. |
.penv/targets/<name>/target.toml | yes | Where your typed file goes, so nobody is asked twice. |
Which environment you are reading
penv takes the first of these that says something:
--envon the command linePENV_ENVin the environment penv itself was started withdevelopment, 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.