Stop Exposing API Keys: A BFF Pattern for AI Streaming Apps
Shipping an AI feature that calls an LLM from the browser leaks the API key to anyone who opens DevTools. A thin Node BFF is the smallest safe pattern, and frontend engineers who can build it themselves ship faster without depending on backend capacity.
Frontend code that calls an LLM API directly exposes the secret key, forces every client to reimplement SSE stream parsing, and hits browser cross-origin blocks. Moving those concerns into a Node-based Backend For Frontend layer solves all three at once. The API key lives in a server-side `.env` file, the Express server digests raw SSE chunks into clean JSON, and Vite's dev proxy makes the browser see a same-origin request.
The walkthrough uses Vue 3, Vite, and Express to show the complete request path: a browser `fetch` to `/api/stream` gets rewritten and forwarded internally to Express on a different port, which then calls DeepSeek with the hidden key. Every step is mapped, from the file relay chain that loads a Vue SPA to the exact proxy configuration that keeps cross-origin checks out of the picture.
The article stops at the request plumbing; actual streaming response handling is promised as a follow-up. Even so, the skeleton demonstrates the core full-stack frontend skill of owning the entire chain from UI to AI provider without waiting for a separate backend team.
The architecture treats the BFF as a frontend-owned concern, which flips the usual backend-as-gatekeeper model and lets UI engineers control their own API surface.
Vite's proxy is presented as a development convenience, but the same pattern in production would require either a reverse proxy like Nginx or deploying the BFF on the same domain to avoid cross-origin issues entirely.
The walkthrough deliberately stops before implementing the streaming response, which is the harder problem; the current code only proves the request path works, not that a real-time chat experience is in place.