Guide · Building real features
Keeping keys out of your code
Do this on day one. Retrofitting it means rotating everything.
Every API key you use is a small amount of your money and your users' data, in string form. The habit that protects them takes ten minutes to set up and is close to impossible to add cleanly later.
The rule
Secrets live in environment variables. Environment variables live in a .env file locally, and in your host's settings panel in production. The .env file is in .gitignore and never, ever committed.
Alongside it, commit a .env.example with the same keys and fake values. That's the file that tells future-you and anyone else what the project needs.
The one that catches people
A key used in browser JavaScript is public. Not "hard to find" — public. Anyone can open devtools and read it. Frameworks that prefix browser-exposed variables (NEXT_PUBLIC_, VITE_) are telling you this explicitly.
If a service's key must stay secret, calls to it go through your own server. The browser calls your endpoint; your endpoint holds the key. There is no way around this, and every "but I'll obfuscate it" plan has failed.
Scan this for anything that shouldn't be in a shared file — API keys, tokens, passwords, connection strings, private URLs: <paste> For each: move it to an environment variable, show the changed line, the .env.example entry, and the .gitignore lines I need. Then tell me which of these, if any, is used in browser code and therefore public no matter what I do.
If it's already committed
Assume it is compromised. Keys in public repositories are found by automated scanners within minutes — this is a well-documented, industrialised thing, not a hypothetical.
Rotate the key at the provider. Deleting the line and committing again does nothing: the old commit still contains it and anyone can read your history.
Rotate first, then clean up the history if you want to. In that order. The cleanup is optional; the rotation is not.
Give each key the least power you can
Most providers let you scope a key to read-only, to specific resources, or to a spend limit. Use it. A leaked key that can only read one bucket is an inconvenience. A leaked key with full account access is a very bad week.