← Projects

Open source contribution · cross-boundary env fix

go-blueprint

What the user saw

the broken call

fetch('http://localhost:8080/')

browser console

ERR_CONNECTION_REFUSED
localhost:8080

Why it wasn’t simple

Vite blocks any env var without VITE_ prefix. program.go had to write the bridge.

The fix

program.go — reads root .env, writes frontend/.env

 globalEnvPath := filepath.Join(projectPath, ".env")
 vitePort := "8080" // Default fallback
 if strings.HasPrefix(line, "PORT=") {
   vitePort = strings.SplitN(line, "=", 2)[1]
 }
 frontendEnvContent := fmt.Sprintf("VITE_PORT=%s\n", vitePort)
 os.WriteFile(filepath.Join(frontendPath, ".env"), ...)

app.tsx.tmpl — the visible change (react & react+tailwind)

- fetch('http://localhost:8080/')
+ fetch(`http://localhost:${import.meta.env.VITE_PORT}/`)

3 CI workflow files — trailing /dev/null was silently breaking builds

- script -q /dev/null -c "go run ..." /dev/null
+ script -q /dev/null -c "go run ..."

Scope

7 files +36 −5 lines

program.go  ·  app.tsx.tmpl (×2)  ·  3 CI workflows  ·  react-vite.md

What I learned

  • Vite’s VITE_ prefix requirement and why it exists — security: don’t accidentally expose server env vars to the browser bundle.
  • Go’s code generation pattern: program.go doesn’t just copy files, it reads and transforms env state at generation time.
  • How to test GitHub Actions locally — asked in the PR, learned about act.
  • Trailing /dev/null in script -c breaks CI — silent failure, hard to spot without running it.

If you have a problem
worth solving —
let’s talk.