Open-Source Wikis

/

Caddy

/

Lore

caddyserver/caddy

Lore

The story of how this codebase grew. Dates are derived from git history (commit timestamps and tag dates) on the local checkout.

The Caddy project predates this repository — the original v1 codebase lived in a different module (github.com/mholt/caddy). The repo at hand (github.com/caddyserver/caddy, module github.com/caddyserver/caddy/v2) is the v2 rewrite, started fresh in March 2019.

Eras

The v2 rewrite begins (Mar 2019)

The first commit on this repo is 859b5d7e — Initial commit on 2019-03-26, followed within hours by Rudimentary start of HTTP servers. The early commits sketch the v2 design: a single JSON config, a module registry with namespaced IDs, and apps as the only top-level loadable units. The decisive design choice that drives everything else — caddy.RegisterModule and ModuleInfo.New — is in place from the beginning.

Modular HTTP and TLS (Apr–Dec 2019)

Through 2019 the HTTP and TLS subsystems take shape:

  • modules/caddyhttp/ grows the route/matcher/handler model.
  • modules/caddytls/ integrates CertMagic and adds ACME issuance, file/folder loaders, and connection policies.
  • caddyconfig/caddyfile/ ports the Caddyfile parser; caddyconfig/httpcaddyfile/ wires it to the HTTP app. The Caddyfile becomes the friendly face on top of JSON.

The v2.0 line is cut later in 2020 once the surface area is stable enough.

Production hardening (2020–2022)

This era is dominated by additions rather than rewrites:

  • Reverse proxy gets dynamic upstream resolution, health checks, and selection policies (modules/caddyhttp/reverseproxy/).
  • The PKI app and ACME server arrive (modules/caddypki/), making Caddy a fully self-contained ACME issuer.
  • The events app (modules/caddyevents/) lands as a small pub/sub.
  • The metrics module exposes Prometheus on the admin API (modules/metrics/).
  • HTTP/3 / QUIC support shows up via quic-go (visible today in listeners.go).
  • File server gains directory listings, range requests, precompressed file serving (modules/caddyhttp/fileserver/).

CEL matchers and observability (2023)

modules/caddyhttp/celmatcher.go introduces request matching with Google's CEL expression language@m expression {…} matchers. modules/caddyhttp/tracing/ adds OpenTelemetry, and structured logging picks up filter encoders for log-line redaction (modules/logging/filters.go, ~24 KB).

TLS depth (2024–2025)

modules/caddytls/ech.go (43 KB today) adds Encrypted ClientHello support. CA pools (capools.go, ~28 KB) and leaf-cert loaders (leaffileloader.go, leaffolderloader.go, leafpemloader.go, leafstorageloader.go) gain the ability to trust issuer-specific CAs and pin leaves explicitly. connpolicy.go (39 KB) becomes one of the larger files in the repo.

Caddyfile ergonomics (ongoing)

The HTTP Caddyfile adapter (caddyconfig/httpcaddyfile/httptype.go, ~61 KB) is the heaviest single file in the repo and the one most likely to receive incremental UX improvements: directive ordering, shorthand expansion (shorthands.go), and global option handling (options.go).

Longest-standing code

These files have been here essentially since the v2 rewrite started:

  • caddy.go (~42 KB) — the Config type, Run, Load, Stop, hash-based skip logic.
  • modules.go (~12 KB) — RegisterModule, ModuleInfo, ModuleID, namespace conventions.
  • admin.go (~49 KB) — admin HTTP server, route registration, /load and /config semantics. The structural layout has remained, but features (load throttling, origin enforcement, configurable listener) have accreted.
  • caddyconfig/caddyfile/parse.go and dispenser.go — the Caddyfile parser and the token API used by every directive.

Major rewrites and refactors

  • HTTP transport refactor. modules/caddyhttp/reverseproxy/httptransport.go (~32 KB today) consolidated the HTTP/1, HTTP/2, and HTTP/3 transport configuration, replacing scattered ad-hoc fields with a single HTTPTransport module.
  • Listener layer. listen.go, listen_unix.go, and listen_reuseUnixSocket.go rebuilt how Caddy obtains sockets (with SO_REUSEPORT on Linux and graceful handoff during reload).
  • Matchers RequestMatcherWithError. A more recent change introduced RequestMatcherWithError alongside RequestMatcher (see modules/caddyhttp/caddyhttp.go). The old RequestMatcher interface is now marked deprecated; modules are migrating.
  • Atomics-everywhere pass. Commit 355c1782 — chore: Use atomics where appropriate (#7648) (Apr 2026) is one of the most recent broad sweeps, replacing mutex-guarded counters with sync/atomic types.

Deprecated or replaced features

  • RequestMatcher — superseded by RequestMatcherWithError (will be dropped after the migration finishes).
  • The HTTPS-only redirect listener has migrated through revisions but modules/caddyhttp/httpredirectlistener.go is now the canonical implementation.
  • Directives carry their own deprecation paths via Caddyfile warnings (caddyconfig.Warning, see caddyconfig/configadapters.go).

Growth trajectory

  • 2019: ~1 contributor, single-author bursts (Matthew Holt).
  • 2020–2022: contributor base widens; Francis Lavoie becomes the most active maintainer after Matt.
  • 2023–2025: 389 unique authors over the full history; sustained ~30 commits/month; broad multi-OS test matrix on CI (Linux, macOS, Windows; cross-build to s390x).
  • 2026: continued maintenance with auto-release-PR workflows (.github/workflows/auto-release-pr.yml, release-proposal.yml).

Speculation note

The "why" of some of these moves is not always recorded in commits. Where this page hedges ("appears to have been", "likely a response to"), it's because the only signal available is the diff itself.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Lore – Caddy wiki | Factory