AI Engineering
5 min read

Don't Connect your Frontend directly to an LLM, or at the Very Least, Don't Ship that Version to Production

Calling an LLM straight from the browser is a fast way to prototype and a fast way to leak your API key. Here's what a minimum viable contract layer needs to do, and when it's actually okay to skip it."

Don't Connect your Frontend directly to an LLM, or at the Very Least, Don't Ship that Version to Production

It takes about ten minutes to wire a React app straight to an LLM provider. Drop in an API key, fire a fetch() call from a button click, and you have a working AI feature. It feels like magic. For a weekend prototype, it's the right decision.

Then someone ships that same code to production. That's when the ten-minute shortcut becomes a security incident, a runaway bill, or both.

This article explains why direct frontend-to-LLM integrations break at scale and why every production AI application needs a service layer between the browser and the model.

Why the Direct Connection Is So Tempting

Calling an LLM directly from the browser removes an entire layer of your architecture. You don't need a backend service. You don't need request contracts. You don't need additional infrastructure.

Several AI providers even encourage this approach by offering browser-friendly SDKs that make model calls feel as simple as any other HTTP request.

For hackathons, prototypes, and internal tools, this tradeoff makes sense. Speed matters more than architecture when you're validating an idea. The problem is that the exact code path that gets you to a demo is structurally the wrong foundation for a production application.

What Actually Breaks in Production

Your API Key Becomes Public

There is no such thing as a secret in the browser. Anything shipped to client-side JavaScript can be inspected through DevTools. Your API key isn't hidden. It's published.

Once someone extracts it, they're spending your model budget instead of theirs.

Rate Limiting Doesn't Exist

Client-side rate limiting is not a security mechanism. It's a suggestion. Anyone can bypass it by calling the API directly.

Without server-side controls, a buggy script or malicious actor can generate thousands of requests in minutes. Every one of those requests is billed to you.

Guardrails Live in the Wrong Place

Content filtering, prompt injection protection, PII redaction, and input validation all belong on the server. If these checks execute inside the browser, they can simply be skipped.

Security controls only matter when they execute inside a trusted environment. The browser is not one of them.

The Model Gets Too Much Power

Modern LLMs don't just generate text. They call tools, invoke functions, and query databases.

If your frontend decides which tools the model is allowed to access, you're trusting the client to enforce permissions. That's equivalent to asking the browser to enforce database access controls.

The browser is not a trust boundary.

Authentication and Authorization Disappear

Who is making this request? What resources can they access? What organization do they belong to? How many requests are they allowed to make?

None of those questions can be reliably answered by frontend code.

Authorization belongs on the server. Always.

You Lose Observability

Without a server sitting between your application and the model, you lose visibility into your system.

You can't reliably answer questions like: which users consume the most tokens, which prompts fail most often, which requests are timing out, or which customers are abusing the system.

You also lose the ability to switch providers without redeploying your frontend.

The Fix: An AI Service Layer

The solution isn't new. It's the same architectural principle that's been protecting databases and internal APIs for years.

Instead of allowing browsers to communicate directly with your LLM provider, place a thin service layer in between.

Application Architecture

Frontend
└── POST /api/chat

AI Service Layer
├── Authentication
├── Authorization
├── Rate Limiting
├── Prompt Construction
├── Guardrails
├── Tool Routing
├── Logging
├── Caching
└── Provider Selection

LLM Provider

The frontend sends only the user's message. Everything else happens on the server.

Your API key never leaves your infrastructure, your system prompt stays private, and your business logic remains centralized.

What That Service Layer Owns

A production-ready service layer should handle:

Authentication & Authorization: Verify who is making the request and what they're allowed to access.

Rate Limiting & Quotas: Enforce request limits on the server where they cannot be bypassed.

Input & Output Guardrails: Validate prompts before they reach the model. Filter or redact sensitive information before responses reach users.

Tool Access: Expose only the specific functions your application intends the model to use. Never expose raw infrastructure directly.

Logging & Observability: Capture every request for debugging, analytics, auditing, and anomaly detection.

Provider Abstraction: Hide vendor-specific APIs behind a stable interface so models can change without changing the frontend.

None of this requires a massive architecture. The minimum viable version is often just a lightweight API with a few endpoints and a proxy call to the model provider.

The Real Tradeoff

A service layer is not free. It introduces a small amount of additional latency, a backend service to deploy, and slightly more engineering effort.

For prototypes and internal demos, those costs may not be worth paying. If no real users depend on the application, shipping quickly is often the correct decision.

Production systems are different. Once real customers, real data, and real money are involved, the economics change.

The cost of one additional network hop is predictable. The cost of a leaked API key isn't. Neither is an unlimited inference bill. Neither is a prompt-injected tool invocation.

The Takeaway

Treat your LLM provider the same way you treat your database. Never expose it directly to the browser.

A thin service layer isn't overengineering. It's the minimum architecture required to build an AI application that is secure, observable, and maintainable.

The frontend should collect input and display responses. The backend should own authentication, authorization, prompts, tools, logging, rate limiting, and provider selection.

The frontend is the face. The service layer is the brain. Keep them separate.

React to this post

OY

Obed Yameogo

ML Engineer · PhD Scholar

LLMAPI SecuritySystem DesignBackend for FrontendAI Engineering

Discussion

Newsletter

Join the Builders List

Receive technical deep-dives on machine learning engineering, AI infrastructure, RAG systems, LLMs, AI agents etc, straight to your inbox.