Beego — Structure#

Layout pattern#

Framework-specific (Domain Quadrant)

Beego v2 uses a deliberate four-domain decomposition (core/, client/, server/, task/) that does not follow the standard Go Layout (cmd/internal/pkg). There is no cmd/ directory — beego is a pure library with no binaries of its own. The layout reflects architectural boundaries between cross-cutting concerns, outbound I/O, inbound serving, and scheduled work, all coexisting in a single Go module.

Directory map#

beego/
├── core/                    — Cross-cutting infrastructure (foundation layer)
│   ├── admin/               — In-process health/admin monitor endpoint
│   ├── bean/                — IoC container / dependency injection (bean factory)
│   ├── berror/              — Structured error types with numeric error codes
│   ├── config/              — Config loading interface + format drivers
│   │   ├── env/             —   Environment variable driver
│   │   ├── etcd/            —   etcd-backed remote config driver
│   │   ├── json/            —   JSON config driver
│   │   ├── toml/            —   TOML config driver
│   │   ├── xml/             —   XML config driver
│   │   └── yaml/            —   YAML config driver
│   ├── logs/                — Structured logger + output adapters
│   │   ├── alils/           —   Alibaba Cloud Log Service adapter
│   │   └── es/              —   Elasticsearch adapter
│   ├── utils/               — General-purpose utilities (pagination, string, time)
│   │   └── pagination/      —   Paginator helper
│   └── validation/          — Input validation rule engine
├── client/                  — Outbound I/O clients
│   ├── cache/               — Cache interface + in-process strategy wrappers
│   │   ├── memcache/        —   Memcache backend
│   │   ├── redis/           —   Redis backend
│   │   └── ssdb/            —   SSDB backend
│   ├── httplib/             — HTTP client with filter/middleware chain
│   │   ├── filter/          —   HTTP client filter implementations
│   │   ├── mock/            —   HTTP client mock for testing
│   │   └── testing/         —   Test helpers for httplib
│   └── orm/                 — Full-featured ORM
│       ├── clauses/         —   SQL clause builder types
│       ├── filter/          —   ORM filter middleware
│       ├── hints/           —   Query option hints (index, ForceIndex, etc.)
│       ├── internal/        —   Private ORM internals (buffers, models, logs, utils)
│       ├── migration/       —   DB schema migration engine
│       └── mock/            —   Mock ORM implementation for testing
├── server/                  — Inbound request handling
│   └── web/                 — MVC web server (flagship component)
│       ├── captcha/         —   CAPTCHA image generation
│       ├── context/         —   HTTP request/response context wrapper
│       ├── filter/          —   Web middleware filters (one subdir per filter)
│       │   ├── apiauth/     —     HMAC API authentication
│       │   ├── auth/        —     HTTP basic auth
│       │   ├── authz/       —     Casbin-based authorization
│       │   ├── cors/        —     CORS headers
│       │   ├── opentracing/ —     OpenTracing integration
│       │   ├── prometheus/  —     Prometheus metrics
│       │   ├── ratelimit/   —     Token-bucket rate limiter
│       │   └── session/     —     Session middleware (filter adapter)
│       ├── grace/           —   Graceful shutdown (hot reload support)
│       ├── mock/            —   Mock web server for testing
│       ├── pagination/      —   Template pagination helpers
│       ├── session/         —   Session interface + storage backends
│       │   ├── couchbase/   —     CouchBase backend
│       │   ├── ledis/       —     LedisDB backend
│       │   ├── memcache/    —     Memcache backend
│       │   ├── mysql/       —     MySQL backend
│       │   ├── postgres/    —     PostgreSQL backend
│       │   ├── redis/       —     Redis backend
│       │   ├── redis_cluster/—    Redis Cluster backend
│       │   ├── redis_sentinel/—   Redis Sentinel backend
│       │   └── ssdb/        —     SSDB backend
│       ├── swagger/         —   Swagger 2.0 spec auto-generation
│       └── test/            —   Web test utilities
├── task/                    — Cron / scheduled task engine
├── test/                    — Integration test fixtures
│   └── views/               —   Template files for integration tests
│       └── blocks/          —   Template block fragments
├── scripts/                 — CI/test orchestration helpers
│   ├── orm_docker_compose.yaml —  Docker Compose for ORM DB tests
│   └── test_docker_compose.yaml — Docker Compose for web integration tests
├── .github/workflows/       — GitHub Actions CI pipelines
├── Makefile                 — Test runners + goimports formatter
├── go.mod / go.sum
├── doc.go                   — Root package declaration (package beego)
├── build_info.go            — Build-time version variables + VERSION const
└── ERROR_SPECIFICATION.md   — Error code specification document

Entry points#

None. Beego is a pure library — there is no cmd/ directory and no main.go files anywhere in the repository. The companion code-generation tool (bee) is a separate binary in a separate repository. Users integrate beego by importing packages (e.g., github.com/beego/beego/v2/server/web) and calling framework entry points like web.Run().

Package organization#

  • Internal packages: Only client/orm/internal/ uses Go’s internal/ mechanism (sub-packages: buffers, logs, models, utils). These are implementation details of the ORM not intended for external consumers.
  • Public packages: Everything else is exported public API — the entire core/, client/, server/, and task/ hierarchies are importable by user code, including all backend drivers.
  • Layering: Domain-based rather than clean architecture:
    • core/ is the foundation: no dependencies on client/ or server/
    • client/ depends on core/ (config, logs, berror, utils)
    • server/web/ depends on core/ and selectively on client/ (httplib, cache)
    • task/ is largely independent, depends only on core/logs
    • Backend subdirectories (redis, mysql, etc.) depend only on their parent interface package

Build system#

  • Build tool: Make + go test + Docker Compose (for database-backed tests)
  • Key targets:
    • test-orm-mysql5 / test-orm-mysql8 — spins up Docker MySQL and runs ORM tests
    • test-orm-pgsql — spins up Docker PostgreSQL and runs ORM tests
    • test-orm-tidb — runs ORM against TiDB in-memory
    • test-orm-all — runs all four database ORM test suites in sequence
    • fmt — runs goimports with local import sorting
  • Docker: docker-compose is used only for test database provisioning, not for building or packaging the library itself
  • CI: GitHub Actions (test.yml, stale.yml, need-feedback.yml, changelog.yml) handle automated testing and community management

Notable structural decisions#

  1. Four-domain split as the primary organizing principle: The v2 rewrite replaced a flat beego. namespace with four bounded domains (core/client/server/task). This is architecturally unusual among Go libraries, which typically use flat layouts. It creates clear import boundaries and makes selective adoption possible — a project can use core/logs or client/orm without importing the entire web framework.

  2. One subdirectory per backend, universally applied: The pattern of “one directory per pluggable backend” is applied consistently across core/config/ (7 format drivers), client/cache/ (3 backends), server/web/session/ (9 backends), and core/logs/ (2 remote adapters). This produces a very regular, easy-to-navigate layout where adding a new backend is always the same operation regardless of subsystem.

  3. Mock packages co-located with implementation: Both client/orm/mock/ and server/web/mock/ sit inside the same domain as the real implementation rather than in a separate testutil/ tree. This makes mocking first-class and easy to discover.

  4. server/web/filter/ as middleware registry via filesystem: Each middleware has its own subdirectory under filter/ rather than being registered in a central file. This scales well for a framework that ships many built-in middlewares (8 sub-packages covering auth, CORS, tracing, metrics, rate limiting, etc.).

  5. Shallow internal/ use despite large surface: With 363 Go files, beego exposes nearly all of its code as public API. Only client/orm/internal/ is hidden. This is a deliberate framework design choice — it maximizes composability and allows advanced users to build on internal types at the cost of a larger, more stable API surface commitment.

  6. No top-level entry binary: The architectural decision to ship zero binaries in the main module keeps the framework focused as a dependency. Build tooling (bee CLI) lives elsewhere, separating framework evolution from tool evolution.