Quick Start
This walkthrough takes you from nothing to a page that calls an API with a server-side key. Pick your platform as you go — the steps are otherwise identical.
All values shown are placeholders. Replace them with your own.
Step 1 — Install envGo
⬇ envgo-windows-amd64.exe · ⬇ envgo-windows-arm64.exe (ARM64 Windows)
Put the downloaded binary on your PATH:
mkdir C:\envgocopy $env:USERPROFILE\Downloads\envgo-windows-amd64.exe C:\envgo\envgo.exeAdd C:\envgo to your user PATH:
[Environment]::SetEnvironmentVariable( "Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";C:\envgo", "User")Open a new terminal so the change takes effect, then verify:
envgo -v⬇ envGo-macOS-AppleSilicon.zip (M-series) · ⬇ envGo-macOS-Intel.zip (Intel)
The release ZIP is the easiest route:
- Extract the ZIP you downloaded —
envGo-macOS-AppleSilicon.zip(M-series) orenvGo-macOS-Intel.zip - Double-click
Install_envGo.commandinside it - Open a new terminal and verify
Or install manually:
mkdir -p ~/.local/bincp dist/envgo-darwin-arm64 ~/.local/bin/envgo # Apple Silicon# cp dist/envgo-darwin-amd64 ~/.local/bin/envgo # Intelchmod +x ~/.local/bin/envgoAdd it to PATH if it is not there yet:
echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.zshrcsource ~/.zshrcenvgo -v⬇ envgo-linux-amd64 · ⬇ envgo-linux-arm64
The downloaded file is the binary itself — no archive to extract:
uname -m # x86_64 → amd64, aarch64 → arm64chmod +x ~/Downloads/envgo-linux-amd64
# System-widesudo mv ~/Downloads/envgo-linux-amd64 /usr/local/bin/envgo
# Or per-user, no sudo neededmkdir -p ~/.local/binmv ~/Downloads/envgo-linux-amd64 ~/.local/bin/envgoIf you installed into ~/.local/bin, make sure it is on PATH:
echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.bashrcsource ~/.bashrc envgo -vNeed a build for another platform, or a SHA-256 checksum to verify one? See Download.
Step 2 — Create the project
mkdir myappcd myappenvgo initmkdir myapp && cd myappenvgo initmkdir myapp && cd myappenvgo initenvgo init writes five files: .env, .env.example, index.html,
.gitignore, and README.md.
Step 3 — Put a real key in .env
envgo init filled .env with placeholders (including commented MODE_PUBLIC/CONFIG). Open it and replace them:
MY_SECRET=some-real-valueOPENAI_API_KEY=sk-your-real-key-hereHOST=127.0.0.1PORT=8080# MODE_PUBLIC=false # true/public = public mode (needs envgo.routes.json)# CONFIG=envgo.routes.json # explicit path, overrides MODE_PUBLICUncomment MODE_PUBLIC=true to switch to public mode without flags. See CLI Commands.
HOST and PORT are different from the others
The first two keys become secrets that stay server-side. HOST and PORT do
not — they tell envgo run dev where to listen, so editing them changes how
you reach the server.
| Key | Value shown | What changing it does |
|---|---|---|
HOST | 127.0.0.1 | Interface to bind. 127.0.0.1 accepts connections from this machine only. 0.0.0.0 also accepts other devices on your network |
PORT | 8080 | Port to listen on, and the port the browser opens. Setting PORT=3000 means you get http://127.0.0.1:3000/ |
Change the port and run it again to see it take effect:
PORT=3000envgo run dev[envGo] using PORT from .env: 3000[envGo] envGo running -> http://127.0.0.1:3000/The browser opens on the new port, and the startup log confirms which value was picked up.
Three rules apply:
- They are read only by
envgo runandenvgo run dev. Plainenvgoand public mode (--config …) ignore them completely. - A command-line flag wins over the file.
envgo run dev --port 4000uses 4000 and ignoresPORTin.env. - Lowercase keys work too (
host,port), and a leading colon is stripped, soPORT=:3000is also valid.
Full details are in CLI Commands.
Open the file
notepad .envSave as UTF-8. Do not use PowerShell’s > redirection to write .env —
Windows PowerShell 5.1 writes UTF-16, which the parser cannot read.
nano .envnano .envStep 4 — Start the server
The command is the same on every platform:
envgo run devrun dev reads HOST and PORT from .env and opens your browser at
http://127.0.0.1:8080/.
Prefer not to auto-open the browser? Use envgo run instead.
Watch the startup output — it tells you what loaded:
[envGo] loaded 4 variables from .env[envGo] envGo running -> http://127.0.0.1:8080/If the port is taken, envGo automatically tries the next one up (up to 20 attempts), so check the printed address.
Step 5 — Check which keys are visible
envgo init created a page containing:
<h1>Hello from envGo!</h1><div id="MY_SECRET"></div><script src="/__env.js"></script>Because MY_SECRET exists in .env, the div is replaced at runtime with:
✓ MY_SECRET — Success (env exists, value hidden)If the id does not match any key, you get a red banner instead:
envGo — ID not match Key: 'MY_SECRETS' not found in .env.Did you mean 'MY_SECRET'? Check .env for 'MY_SECRET'The value of MY_SECRET is never sent to the browser. A message like this
confirms a key is present, nothing more.
Step 6 — Call an API with the key
This is a complete, working example. Every name and endpoint below is illustrative — adapt it to your API.
It takes two files that have to agree with each other. Here is the .env again
so you can see the pairing — it is the same file you edited in Step 3 (plus optional commented mode lines):
MY_SECRET=some-real-valueOPENAI_API_KEY=sk-your-real-key-hereHOST=127.0.0.1PORT=8080# MODE_PUBLIC=falseThe two files must line up in three places:
In index.html | Must exist in .env |
|---|---|
<div id="MY_SECRET"> | MY_SECRET |
<div id="OPENAI_API_KEY"> | OPENAI_API_KEY |
Bearer {OPENAI_API_KEY} | OPENAI_API_KEY |
If an id has no matching key you get a red ID not match Key banner. If a
{…} placeholder has no matching key the proxy call fails with
{"error":"missing env variable: OPENAI_API_KEY"}.
Also note that the button and output elements deliberately have no id, so
the presence checker leaves them alone.
<!DOCTYPE html><html><head> <meta charset="utf-8" /> <title>My App</title> <style> body { font-family: system-ui, sans-serif; max-width: 700px; margin: 3rem auto; } button { padding: 10px 18px; font-size: 15px; cursor: pointer; } pre { background: #0f172a; color: #7dd3fc; padding: 1rem; border-radius: 10px; overflow: auto; } </style></head><body> <h1>Hello from envGo!</h1>
<!-- Variable presence check --> <div id="MY_SECRET"></div> <div id="OPENAI_API_KEY"></div>
<!-- No id: these are not variables --> <button>Ask the API</button> <pre>Click the button…</pre>
<script src="/__env.js"></script> <script> const button = document.querySelector("button"); const output = document.querySelector("pre");
button.addEventListener("click", async () => { output.textContent = "Loading…"; try { // 1. Fetch the per-process session token const token = await fetch("/__envgo_token").then((r) => r.text());
// 2. Proxy the call; {OPENAI_API_KEY} is substituted server-side const res = await fetch("/proxy", { method: "POST", headers: { "Content-Type": "application/json", "X-EnvGo-Token": token, }, body: JSON.stringify({ target_url: "https://api.openai.com/v1/chat/completions", method: "POST", headers: { Authorization: "Bearer {OPENAI_API_KEY}" }, body: { model: "gpt-4", messages: [{ role: "user", content: "Say hello in one sentence." }], }, }), });
output.textContent = JSON.stringify(await res.json(), null, 2); } catch (err) { output.textContent = "Error: " + err.message; } }); </script></body></html>Two things about that code:
"Bearer {OPENAI_API_KEY}"is a placeholder. The literal text{OPENAI_API_KEY}is what the browser sends; the Go process swaps it for the real value before forwarding.- The host must be allowlisted. Restart the server with:
envgo run dev -a api.openai.comWithout --allow, envGo prints a warning on startup and refuses every proxy
request.
Step 7 — Watch hot reload
Leave the server running and change .env from another terminal:
Add-Content -Path .env -Value "NEW_KEY=hello" -Encoding utf8Reading it back with the same encoding matters more than you might expect —
Windows PowerShell 5.1’s default redirection writes UTF-16, which corrupts the
file. If a key ever shows up garbled, rewrite .env from Notepad saved as UTF-8.
PowerShell 7 handles UTF-8 by default.
echo "NEW_KEY=hello" >> .envecho "NEW_KEY=hello" >> .envWithin about 1.5 seconds the server logs:
[envGo] hot-reloaded 5 variables from .envNo restart needed.
Step 8 — Look at the dashboard
http://127.0.0.1:8080/__envgo_dashboardIt lists the loaded variable names, recent proxy requests with status and
duration, and any errors. Values are never shown. The same data endpoint is what
/__env.js reads to learn the variable names.
Complete command sequence
Copy-paste blocks for a fresh install, in one place. On Windows the commands are PowerShell; on macOS and Linux they are a POSIX shell.
# 1. Install (adjust the binary name for ARM64)# Download: https://github.com/dnysaz/envgo/releases/latest/download/envgo-windows-amd64.exemkdir C:\envgocopy $env:USERPROFILE\Downloads\envgo-windows-amd64.exe C:\envgo\envgo.exe[Environment]::SetEnvironmentVariable( "Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";C:\envgo", "User")# Open a NEW terminal here
# 2. Verifyenvgo -v
# 3. Create a projectmkdir myappcd myappenvgo init
# 4. Edit .env with a real keynotepad .env
# 5. Run, allowing one API hostenvgo run dev -a api.openai.com# 1. Install — from the extracted envGo-macOS-AppleSilicon.zip# (M-series; use envGo-macOS-Intel.zip and envgo-darwin-amd64 for Intel)# Download: https://github.com/dnysaz/envgo/releases/latest/download/envGo-macOS-AppleSilicon.zipmkdir -p ~/.local/bincp dist/envgo-darwin-arm64 ~/.local/bin/envgo # or envgo-darwin-amd64chmod +x ~/.local/bin/envgoecho 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.zshrcsource ~/.zshrc
# 2. Verifyenvgo -v
# 3. Create a projectmkdir myapp && cd myappenvgo init
# 4. Edit .env with a real keynano .env
# 5. Run, allowing one API hostenvgo run dev -a api.openai.com# 1. Installuname -m # x86_64 → amd64, aarch64 → arm64# Download: https://github.com/dnysaz/envgo/releases/latest/download/envgo-linux-amd64chmod +x ~/Downloads/envgo-linux-amd64sudo mv ~/Downloads/envgo-linux-amd64 /usr/local/bin/envgo
# 2. Verifyenvgo -v
# 3. Create a projectmkdir myapp && cd myappenvgo init
# 4. Edit .env with a real keynano .env
# 5. Run, allowing one API hostenvgo run dev -a api.openai.comCommon errors
These are identical on every platform:
| Response | Meaning | Fix |
|---|---|---|
{"error":"missing env variable: OPENAI_API_KEY"} | The key is not in .env | Add it, or fix the spelling |
{"error":"unauthorized"} | Token missing or stale | Fetch a fresh /__envgo_token |
{"error":"target host not in allowlist: api.openai.com"} | Host not allowed | Add it to --allow |
{"error":"only HTTPS targets are allowed"} | Target uses http:// | Use https:// |
Red banner reading ID not match Key | The element id does not match any key | Correct the id or the .env key |
Platform-specific installation problems — command not found, wrong
architecture, Gatekeeper, SmartScreen — are covered in
Installation.
Where to go next
- Add more routes and turn on rate limiting → Public Mode
- Understand every config field → Configuration
- Deploy it → Deploy to VPS
- Learn the security layers → Security Model