跪拜 Guibai
← All articles
Frontend · JavaScript

Stop Exposing API Keys in the Browser: Move LLM Streaming to a BFF Layer

By 默_笙 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Shipping an API key in client-side JavaScript is a security incident waiting to happen, and raw streaming responses create brittle, hard-to-maintain frontend code. A thin Node.js BFF solves both problems with minimal infrastructure and keeps the architecture simple enough for a single frontend team to own.

Summary

Calling LLM APIs directly from a browser forces frontend code to juggle ReadableStream parsing, TextDecoder loops, and exposed API keys. A Node.js BFF layer absorbs that complexity by proxying requests, attaching secrets server-side, and returning clean data to the UI. The approach uses Express for routing and Vite's proxy config to solve cross-origin issues between the dev server and the BFF.

In an AI project, the BFF becomes a security boundary and a complexity sink. The frontend sends a request to `/api/stream`; Vite forwards it to the Express server on a different port, which then calls DeepSeek with the hidden key. The browser never sees the credential, and the streaming logic lives in one place instead of scattered across components.

The pattern fits a "Big Frontend" workflow where frontend engineers own their own Node services. It is not meant to replace a Java or Go backend for business logic or database access, but it handles lightweight forwarding, data reshaping, and API aggregation cleanly.

Takeaways
API keys for third-party services like DeepSeek should live in a BFF layer, never in browser-side code.
Streaming LLM responses require ReadableStream and TextDecoder handling that is better centralized in a Node server than duplicated in frontend components.
Express provides a lightweight way to build a BFF that proxies requests and attaches secrets server-side.
Vite's proxy configuration rewrites `/api` requests to a different port, eliminating cross-origin errors during development without CORS headers.
The BFF pattern is not a replacement for a primary backend; it is unsuitable for database access, complex business logic, or distributed transactions.
Conclusions

The article reflects a common pain point in frontend AI development: the jump from calling a REST API to handling raw binary streams is where many prototypes break down. A BFF layer is a pragmatic stopgap that lets teams ship streaming features without a full backend rewrite.

Positioning the BFF as a 'Big Frontend' responsibility rather than a backend concern shifts ownership. Frontend engineers who can write a simple Express server gain autonomy over API integration and security without depending on a separate backend team.

The Vite proxy trick is underappreciated in tutorials. It solves the localhost cross-origin problem without touching CORS configuration on the server, which keeps the BFF simpler and more portable.

Concepts & terms
BFF (Backend For Frontend)
A dedicated server layer that sits between a frontend application and downstream services, handling tasks like API key management, data formatting, and request aggregation so the client code stays thin.
Vite Proxy
A development-server feature that intercepts requests matching a path prefix (e.g., `/api`) and forwards them to a different target URL, avoiding browser cross-origin restrictions during local development.
ReadableStream
A Web API representing a stream of binary data that must be read in chunks, commonly encountered when consuming server-sent events or streaming LLM responses.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗