ollama/ollama
Patterns and conventions
What the existing code does — and what reviewers expect new code to do.
Module layout
The whole repo is one Go module: github.com/ollama/ollama in go.mod. Internal packages use the standard Go layout (one directory per package, lower-case names). There is no internal/ indirection at the root, but several subsystems use their own internal/ to hide helpers (e.g., server/internal/, cmd/internal/).
The non-core extension subtree lives under x/ — x/imagegen, x/mlxrunner, x/agent, x/create, x/server, etc. New runners and experimental subsystems land here first.
CLI structure
Every cobra command is registered in cmd.NewCLI (cmd/cmd.go). The pattern is:
runCmd := &cobra.Command{
Use: "run <model>",
Short: "Run a model",
Args: cobra.MinimumNArgs(1),
PreRunE: checkServerHeartbeat,
RunE: RunHandler,
}
runCmd.Flags().Bool("verbose", false, "Show timings for response")Handlers are exported package-level functions named <Verb>Handler (RunHandler, PullHandler, CreateHandler). PreRunE is checkServerHeartbeat for any command that talks to the daemon.
HTTP handlers
Handlers live as methods on Server in server/. Convention:
func (s *Server) <Name>Handler(c *gin.Context)- Bind the request body with
c.ShouldBindJSON; emit specific errors viac.AbortWithStatusJSON. - For inference handlers, register through
s.withInferenceRequestLogging(...). - For OpenAI/Anthropic compat, attach middleware from
middleware/that translates the request shape — the underlying handler stays canonical.
Routes return either NDJSON streams (/api/generate, /api/chat) or single JSON responses; streams flush via c.Writer.Flush().
Errors
- Wrap with
fmt.Errorf("%s: %w", context, err)to keeperrors.Ischains intact. - Sentinel errors are exported
ErrXxxat package scope (e.g.,parser.ErrModelNotFound,server.ErrMaxQueue). - Public error messages avoid leaking internal paths or PII.
Configuration
Read environment variables only through envconfig/config.go. Adding a new env var means:
- Add a
func Foo() Tthat returns the parsed value. - Document it in
docs/faq.mdxif user-facing. - Don't read the variable directly from
os.Getenvelsewhere.
The daemon snapshots configuration at startup; subsequent calls return the cached value.
Logging
log/slog everywhere. Conventional attributes:
"model"— model name."path"— filesystem path."pid"— process id (often the runner subprocess)."err"— the error.
logutil.Filter* helpers in logutil/ hide secrets when relevant.
Concurrency
golang.org/x/sync/errgroupfor request fan-out.sync.Mutexfor in-memory caches; the lock fields are named<Field>Mu(e.g.,loadedMuinserver/sched.go).- Channels for one-shot signals (
successCh,errCh,unloadedCh).
Naming
- Lower-case package names, single word where possible.
- Exported functions take the most-specific verb (
Pull,Push,Create,Show,Generate,Chat,Embed). - Receivers are short:
sfor*Server,fforModelfile,cfor*gin.Contextand for*Client.
Compatibility
CONTRIBUTING.md is firm: changes that break Ollama's API or the OpenAI-compatible API are not accepted. New fields are additive; old fields stay or move to parser.deprecatedParameters.
Generation and codegen
- Protobuf is checked in (see
convert/sentencepiece_model.proto). - TypeScript types for the API client are generated by
api/types_typescript_test.gousingtkrajina/typescriptify-golang-structs.
Testing
Covered in detail in testing. The shorthand: table-driven, behavior-focused, golden fixtures in testdata/.
Documentation
User-facing docs go under docs/ as .md and .mdx files; they're rendered to docs.ollama.com. Don't duplicate doc text in code comments — link to the rendered page instead.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.