Ollama is a Go-based local model runner that compiles a C++ llama.cpp inference server per GPU backend (CPU, CUDA, ROCm, Vulkan) plus a dedicated Apple MLX path, fronted by a Gin HTTP API, a CLI, and a React and Vite desktop app.
- Language
- Go
- Database
- SQLite
- Hosting
- Docker
- License
- MIT
- Running for
- 2 years
- Team
- 1-5 people
Why this architecture
Inference performance depends on the accelerator, so the C++ llama.cpp server is built as separate CPU, CUDA, ROCm, and Vulkan variants, with native Go code choosing the right one at runtime, while an independent MLX runner handles Apple Silicon instead of one shared code path.
Tech stack by layer
8 technologies · audited Sep 17, 2026- ReactImplements the desktop app UI under app/ui, including chat and settings screens.
- ViteBuilds and serves the desktop app UI.
- Tailwind CSSStyles the desktop app UI.
- SQLiteEmbedded storage via mattn/go-sqlite3, used for local state such as model metadata.
- DockerMulti-stage build compiles CPU, CUDA, ROCm, and Vulkan variants of the llama.cpp server.
Ollama architecture diagram
Open SVGDiagram as text
- ollama CLI (Go) → Ollama server (Go · Gin): HTTP
- Desktop app (React · Vite) → Ollama server (Go · Gin): HTTP
- API clients (OpenAI / Anthropic compatible) → Ollama server (Go · Gin): compatible APIs
- Ollama server (Go · Gin) → Inference runner (llama.cpp · per GPU): load · generate
- Ollama server (Go · Gin) → MLX runner (Apple Silicon): generate
- Ollama server (Go · Gin) → SQLite (local state): state
- Ollama server (Go · Gin) → Model store (manifests · layers): pull · read
Key architectural decisions
6 decisions- 01
Inference runs through llama.cpp, compiled per accelerator backend
The Dockerfile builds separate llama-server-cpu, llama-server-cuda_v12, llama-server-cuda_v13, llama-server-rocm_v7_2, and llama-server-vulkan stages from the same llama/server and llama/compat source under cmake presets, publishing each backend as its own scratch-stage artifact under lib/ollama/<variant>.
- 02
GPU discovery is implemented natively per platform in Go
The discover/ package has platform-specific files such as discover/gpu_darwin.go, discover/amd.go, discover/cuda_compat.go, and discover/vulkan.go, so runtime GPU detection for CUDA, ROCm, Vulkan, and Apple hardware is handled in Go rather than shelled out to external tooling.
- 03
Apple Silicon gets a dedicated MLX execution path alongside llama.cpp
The mlx/ and mlxrunner/ directories (mlx/dynamic_darwin.go, mlxrunner/runner.go, mlxrunner/speculate.go) implement a separate inference runner on top of Apple MLX, distinct from the llama.cpp-based llm/ and llama/ packages used for other backends.
- 04
OpenAI and Anthropic compatible API surfaces are first-class
The openai/ package (openai/openai.go, openai/responses.go) and middleware/openai.go and middleware/anthropic.go implement request/response translation layers, letting existing OpenAI- or Anthropic-format clients talk to a local Ollama server without modification.
- 05
The desktop app is a native shell around a Vite/React web UI
app/ui/app/package.json builds a React 19 application with vite build and TanStack Router (@tanstack/react-router), while native platform integration (tray icon, auto-update, OS windowing) lives in sibling Go directories such as app/wintray, app/updater, and app/webview rather than in the web UI itself.
- 06
Local model state is stored in embedded SQLite, not an external database
go.mod depends directly on github.com/mattn/go-sqlite3, and the manifest/ package (manifest/manifest.go, manifest/layer.go) manages on-disk model manifests, keeping Ollama runnable as a single binary with no external database service.
How Ollama is built
How Ollama is structured
Ollama's core is a Go module (go.mod, module github.com/ollama/ollama) with the CLI entry point in main.go and cmd/. The HTTP API and request handling live in api/, openai/, anthropic/, and middleware/. Model creation and quantization logic is under create/ (with per-architecture files like create/gemma4.go, create/qwen35.go, and create/cohere2moe.go), and on-disk model manifests are managed by manifest/. GPU and accelerator detection is isolated in discover/, with platform-specific files such as discover/gpu_darwin.go, discover/amd.go, and discover/vulkan.go. Native inference code lives in two parallel trees: llama/ and llm/ wrap the C/C++ llama.cpp server, while mlx/ and mlxrunner/ implement a separate execution path for Apple's MLX framework. The desktop application lives under app/, split between Go-based native integration (app/wintray, app/updater, app/webview, app/darwin) and a web-based UI in app/ui.
Frontend
app/ui/app/package.json describes a React 19 application built with Vite ("build": "tsc -b && vite build") and routed with TanStack Router (@tanstack/react-router, @tanstack/router-plugin). Styling uses Tailwind CSS 4 (tailwindcss, @tailwindcss/vite), and data fetching uses @tanstack/react-query. The UI renders markdown and math for model responses via react-markdown, remark-math, rehype-katex, and streamdown, and it depends on the published ollama npm client package to talk to the local server. Component development and visual testing use Storybook (storybook, @storybook/react-vite, @storybook/addon-a11y) alongside Vitest and Playwright for testing.
Backend & APIs
The Go backend uses gin-gonic/gin (per go.mod) as its HTTP web framework, spf13/cobra for CLI command structure, and charmbracelet/bubbletea with charmbracelet/lipgloss for the interactive terminal UI in cmd/tui. Request translation layers give Ollama compatibility with two external API shapes: openai/openai.go and openai/responses.go implement OpenAI Chat Completions and Responses API compatibility (tested in openai/openai_test.go and openai/responses_test.go), while anthropic/anthropic.go does the equivalent for Anthropic's Messages API. middleware/web_search.go and middleware/anthropic.go sit in front of these to normalize incoming requests before they reach the model-serving code.
Data & persistence
Ollama avoids an external database dependency. go.mod lists github.com/mattn/go-sqlite3 directly, and the manifest/ package (manifest/manifest.go, manifest/layer.go, manifest/paths.go) is responsible for reading and writing model manifests and layer metadata on disk, following the content-addressable layout Ollama uses to store downloaded models. This keeps the server a single self-contained binary rather than requiring a separately provisioned database service.
Build, test & deploy
The Dockerfile builds llama.cpp's llama-server component multiple times, once per accelerator: a cpu-deps stage installs the GCC toolchain for a CPU-only llama-server-cpu build, cuda-12-deps and cuda-13-deps stages install the matching CUDA toolkit for llama-server-cuda_v12 and llama-server-cuda_v13, a rocm-7-deps stage builds llama-server-rocm_v7_2 against ROCm 7.2.1, and a vulkan-deps stage downloads the LunarG Vulkan SDK to build llama-server-vulkan. Each variant is installed via cmake --install ... --component llama-server and copied into its own scratch-based publish stage, keeping the final artifacts backend-specific rather than one bloated image. NVIDIA Jetson devices get their own self-contained build stages (jetpack-5, jetpack-6) based on NVIDIA's l4t-jetpack base images. CI workflows include test.yaml, test-llamacpp-update.yaml (validating llama.cpp version bumps pinned in LLAMA_CPP_VERSION), test-install.yaml, and release.yaml.
Self-hosting notes
Ollama installs as a single binary via curl -fsSL https://ollama.com/install.sh | sh on macOS and Linux, or an equivalent PowerShell command on Windows, and it is also published as a Docker image (ollama/ollama on Docker Hub) that self-hosters can run directly. Because model state is stored locally with SQLite and content-addressable manifest files rather than in an external database, a self-hosted instance has no separate datastore to provision or back up beyond the model storage directory itself. The GPU backend a given install uses is selected automatically at runtime by the platform-specific code in discover/, so the same binary or Docker image adapts to CPU-only, CUDA, ROCm, or Vulkan hosts without a manual configuration flag.
Sources & repo audit
- go.mod (Gin, mattn/go-sqlite3, cobra-style CLI dependencies)
- Dockerfile (multi-backend llama.cpp build: CPU, CUDA, ROCm, Vulkan)
- app/ui/app/package.json (React 19 + Vite + TanStack Router desktop UI)
Independent analysis of repository at github.com/ollama/ollama. Spotted an inaccuracy? Use the claim form to request a correction.
Show this stack on your README or website
[](https://stackitfast.com/project/ollama)Paste it into your README. It shows your current stack and links to this page.
Scaffold it with your agent
Paste this prompt into Claude Code, Cursor, Windsurf or AGY to start a project with Ollama's architecture.
- 1Copy the promptThe full markdown spec, with every layer and decision.
- 2Open your AI toolClaude Code, Cursor, Windsurf or Copilot, in a new repo.
- 3Paste and scaffoldUse it as the first instruction; review before you ship.
# MISSION: Scaffold "Ollama" Production Architecture
You are an expert Senior Staff Software Architect and Full-Stack Engineer. Your mission is to scaffold and implement a production-grade, highly reliable, and modular codebase following the proven architecture of **Ollama**.
---
## 1. PROJECT SPECIFICATIONS & BENCHMARK
- **Reference Architecture**: Ollama
- **What It Does**: Ollama is a Go-based local model runner that compiles a C++ llama.cpp inference server per GPU backend (CPU, CUDA, ROCm, Vulkan) plus a dedicated Apple MLX path, fronted by a Gin HTTP API, a CLI, and a React and Vite desktop app.
- **Domain & Category**: Local AI Inference Engine
- **Production Scale**: 1-5 people
- **Development Mode**: AI-AGENT
- **Architectural Rationale**: Inference performance depends on the accelerator, so the C++ llama.cpp server is built as separate CPU, CUDA, ROCm, and Vulkan variants, with native Go code choosing the right one at runtime, while an independent MLX runner handles Apple Silicon instead of one shared code path.
- **Live Website Reference**: https://ollama.com
- **Source Repository**: https://github.com/ollama/ollama
---
## 2. PRODUCTION TECH STACK
- **Full Stack Array**: Go, TypeScript, React, C++, SQLite, Docker, Vite, Tailwind CSS
- **Primary Language(s)**: Go, C, TypeScript
- **License of the reference repo**: MIT
- **Frontend**: React — Implements the desktop app UI under app/ui, including chat and settings screens.; Vite — Builds and serves the desktop app UI.; Tailwind CSS — Styles the desktop app UI.
- **Backend & APIs**: Go — Implements the CLI, HTTP server, model manifest handling, and GPU discovery.; Gin — HTTP web framework used by the Ollama API server.; C++ — llama.cpp-based inference server compiled per GPU backend from the llama/server source tree.
- **Data & persistence**: SQLite — Embedded storage via mattn/go-sqlite3, used for local state such as model metadata.
- **Infrastructure & deploy**: Docker — Multi-stage build compiles CPU, CUDA, ROCm, and Vulkan variants of the llama.cpp server.
---
## 3. KEY ARCHITECTURAL DECISIONS (audited from https://github.com/ollama/ollama @ ec3cc23)
1. **Inference runs through llama.cpp, compiled per accelerator backend**: The Dockerfile builds separate llama-server-cpu, llama-server-cuda_v12, llama-server-cuda_v13, llama-server-rocm_v7_2, and llama-server-vulkan stages from the same llama/server and llama/compat source under cmake presets, publishing each backend as its own scratch-stage artifact under lib/ollama/<variant>.
2. **GPU discovery is implemented natively per platform in Go**: The discover/ package has platform-specific files such as discover/gpu_darwin.go, discover/amd.go, discover/cuda_compat.go, and discover/vulkan.go, so runtime GPU detection for CUDA, ROCm, Vulkan, and Apple hardware is handled in Go rather than shelled out to external tooling.
3. **Apple Silicon gets a dedicated MLX execution path alongside llama.cpp**: The mlx/ and mlxrunner/ directories (mlx/dynamic_darwin.go, mlxrunner/runner.go, mlxrunner/speculate.go) implement a separate inference runner on top of Apple MLX, distinct from the llama.cpp-based llm/ and llama/ packages used for other backends.
4. **OpenAI and Anthropic compatible API surfaces are first-class**: The openai/ package (openai/openai.go, openai/responses.go) and middleware/openai.go and middleware/anthropic.go implement request/response translation layers, letting existing OpenAI- or Anthropic-format clients talk to a local Ollama server without modification.
5. **The desktop app is a native shell around a Vite/React web UI**: app/ui/app/package.json builds a React 19 application with vite build and TanStack Router (@tanstack/react-router), while native platform integration (tray icon, auto-update, OS windowing) lives in sibling Go directories such as app/wintray, app/updater, and app/webview rather than in the web UI itself.
6. **Local model state is stored in embedded SQLite, not an external database**: go.mod depends directly on github.com/mattn/go-sqlite3, and the manifest/ package (manifest/manifest.go, manifest/layer.go) manages on-disk model manifests, keeping Ollama runnable as a single binary with no external database service.
---
## 4. NON-NEGOTIABLE ARCHITECTURAL GUARDRAILS
1. **Monorepo & Modular Separation**:
- Structure as a Turborepo monorepo with strict package boundaries:
- `apps/web`: Application UI, routing, layouts, and server endpoints.
- `packages/ui`: Shared design tokens, CSS variables, and Radix UI primitive components.
- `packages/db`: Database schemas, client singleton, declarative migrations, and seed scripts.
- `packages/config`: Shared TypeScript, ESLint, and build configurations.
2. **Strict Type Safety & Zero `any` Policy**:
- Enable `strict: true`, `noImplicitAny: true`, and `strictNullChecks: true`.
- Validate ALL external inputs, API request bodies, and query parameters with **Zod** schemas before execution.
3. **Frontend & Rendering Guidelines**:
- Utilize Vite 6 with TanStack Router for fully type-safe routing. Manage server state and caching via TanStack Query v5 with optimistic UI updates.
4. **Design System & Aesthetics**:
- Keep every color, radius, shadow and font in a single token file (CSS variables) and consume tokens everywhere; never hardcode hex values in components.
- Prefer crisp 1px borders and one subtle shadow scale over blurry default shadows. Pair one sans-serif for body/headings with one monospace for tags, badges, metrics, and code.
5. **Data Layer & Reliability**:
- Write declarative schema definitions with foreign keys, composite indexes on queried filters, and automated timestamp triggers.
- Use connection pooling and prepared statements for serverless database execution.
---
## 5. STEP-BY-STEP SCAFFOLDING ROADMAP
- **Phase 1: Workspace & Root Config**: Initialize package manager, monorepo configuration (`turbo.json`, `tsconfig.base.json`, `package.json`).
- **Phase 2: Database Schema & Client**: Set up the data layer (SQLite): client, connection pool, models, and migration scripts.
- **Phase 3: Design Tokens & UI Primitives**: Build accessible `Button`, `Input`, `Card`, `Badge`, and layout wrappers inside `packages/ui`.
- **Phase 4: Core Application Routes & Handlers**: Implement primary authentication, user session handling, and application routes.
- **Phase 5: Quality Assurance & Build Verification**: Run `tsc --noEmit`, ESLint, Prettier, and smoke test suites to ensure zero compilation or runtime errors.
---
## 6. EXECUTION INSTRUCTIONS
1. Review all specifications, architectural guardrails, and stack choices above.
2. Present the full monorepo directory tree structure.
3. Systematically generate the complete, production-ready codebase according to the 5-phase roadmap above — starting with the root workspace setup, followed by the database schema, UI design system package, and full-stack application routes until the repository is fully scaffolded and ready to run.Frequently asked about Ollama
What tech stack does Ollama use?
Ollama is written primarily in Go (the CLI, HTTP server using Gin, and GPU discovery), with a C++ llama.cpp inference server compiled per accelerator backend, an Apple MLX runner for Apple Silicon, and a React/Vite desktop app UI.
Does Ollama need a GPU?
No, but it detects and uses one when available; the discover/ package has dedicated Go files for CUDA, ROCm, Vulkan, and Apple GPU detection, and the Dockerfile builds a CPU-only llama-server-cpu variant alongside the accelerator-specific ones.
What database does Ollama use?
Ollama does not require an external database; it depends directly on mattn/go-sqlite3 (see go.mod) for local state and manages model manifests as files through its manifest/ package.
Is Ollama compatible with the OpenAI API?
Yes, the openai/ package and middleware/openai.go implement an OpenAI-compatible request and response translation layer, and a parallel middleware/anthropic.go does the same for Anthropic-style requests.
One email a month: new deep dives and stack trends
New source-audited architectures, head-to-head comparisons and the monthly stack report. No spam, unsubscribe anytime.
Similar architectures
- PocketBaseClassicEmbedded Backend · SoloShares Go · SQLite · Vite
- BeszelClassicLightweight Server & Container Monitoring · Solo DeveloperShares Go · SQLite · React
- DragonflyClassicMulti-Threaded In-Memory Key-Value Store · 20+ PeopleShares C++ · Go · Docker
- BunClassicAll-in-One JavaScript Runtime & Toolchain · 1M+ MAUShares C++ · TypeScript · SQLite
- Fasten HealthClassicPersonal Health Records & Medical EHR Engine · Solo DeveloperShares Go · TypeScript · SQLite
- MindsHub (formerly MindsDB)AI-agentDesktop & Web AI Agent Workspace · 20+ PeopleShares TypeScript · React · Vite