Every AI product I have shipped and every build workshop I run uses the same shape: a FastAPI service that owns models, retrieval and data, and a Next.js application that owns what the user sees. Students ask whether that is too much for a first project. It is exactly enough, and here is why the seams fall where they do.
Why two services
Python owns the AI ecosystem — embeddings, rerankers, training libraries, OCR clients. TypeScript owns the browser — streaming rendering, forms, auth flows. Putting each where its tools live keeps both codebases small. The one exception I have shipped is DocuLens AI, a single Next.js app with no database, chosen deliberately for a sensitive-document tool with minimal infrastructure.
What lives in FastAPI
- Ingestion: chunking, embedding, OCR, storage.
- Retrieval and generation: hybrid search, reranking, the confidence gate, provider fallback.
- Streaming endpoints with Server-Sent Events; see streaming LLM answers with FastAPI.
- Structured logs, request ids, health checks.
What lives in Next.js
- Pages, forms, the streaming answer view and citation panel.
- Authentication and session handling.
- Calls to the API through a thin client with typed responses.
- Nothing that needs a model. If the front end is doing inference, it is a browser-side ONNX case, not a shortcut.
The seams
- A typed contract for every endpoint — request and response schemas that both sides validate.
- Environment variables for URLs and keys; never a key in the front end.
- One Docker image per service, one compose file for local development.
- Errors as typed events, so the UI can say something useful.
In a workshop
Students build the API first and test it with a script, then the front end against the running API. By the end of the afternoon both are deployed, and they have a template for the next three projects. That is the "Ship it" workshop on my talk menu.
— Pranjul Rathour, GenAI Engineer from Kanpur, India. Open to GenAI roles, hackathon judging, mentorship sessions and guest talks at any campus: pranjulrathour41@gmail.com.
