Open-Source Wikis

/

Ollama

/

How to contribute

/

Patterns and conventions

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 via c.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 keep errors.Is chains intact.
  • Sentinel errors are exported ErrXxx at 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:

  1. Add a func Foo() T that returns the parsed value.
  2. Document it in docs/faq.mdx if user-facing.
  3. Don't read the variable directly from os.Getenv elsewhere.

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/errgroup for request fan-out.
  • sync.Mutex for in-memory caches; the lock fields are named <Field>Mu (e.g., loadedMu in server/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: s for *Server, f for Modelfile, c for *gin.Context and 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

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.

Patterns and conventions – Ollama wiki | Factory