Skip to content

oliverandrich/burrow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

313 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Burrow

Burrow — Go gophers building a modular burrow

CI Release Go Version Go Report Card License Docs

A web framework for Go developers who want something like Django, Rails, or Flask — but with the deployment simplicity of a single static binary.

Most Go web development follows the "API backend + SPA frontend" pattern. Burrow takes a different approach: server-rendered HTML with templates, modular apps with their own routes, migrations, and middleware, and an embedded SQLite database. The result is an application you can deploy as a single file — ./myapp and you're done.

Built on Chi, Bun/SQLite, and Go's standard html/template. Ideal for self-hosted applications, internal tools, or any project where "download, start, use" is the goal.

Tip

Why Burrow? A burrow is a network of interconnected chambers — each with its own purpose, yet part of a larger whole. That's exactly how the framework works: pluggable apps are the rooms, and your gophers live in them.

Note

Burrow is designed for server-rendered web applications, not API-only services. If you're building a JSON API with a separate frontend, a lighter router like Chi on its own is probably a better fit.

Features

  • App-based architecture — build your application from composable, self-contained apps
  • Pure Go SQLite — no CGO required (CGO_ENABLED=0), cross-compiles anywhere
  • Per-app migrations — each app manages its own SQL migrations
  • Standard templates — Go's html/template with a global template set, per-app FuncMaps, and automatic layout wrapping
  • CSS-agnostic — bring your own CSS framework (Bootstrap, Tailwind, etc.)
  • Layout system — app layout via server, admin layout via admin package
  • CLI configuration — flags, environment variables, and TOML config via urfave/cli
  • CSRF protection — automatic token generation and validation
  • Flash messages — session-based flash message system
  • Bootstrap integration — Bootstrap 5 CSS/JS, inline SVG icons, htmx, and dark mode theme switcher
  • Contrib apps — auth (WebAuthn/passkeys), sessions, i18n, admin, CSRF, flash messages, jobs, uploads, rate limiting, healthcheck, static files

Quick Start

mkdir myapp && cd myapp
go mod init myapp
go get github.com/oliverandrich/burrow@latest
package main

import (
    "context"
    "log"
    "net/http"
    "os"

    "github.com/oliverandrich/burrow"
    "github.com/go-chi/chi/v5"
    "github.com/urfave/cli/v3"
)

// homeApp is a minimal app with a single route.
type homeApp struct{}

func (a *homeApp) Name() string                      { return "home" }
func (a *homeApp) Register(_ *burrow.AppConfig) error { return nil }
func (a *homeApp) Routes(r chi.Router) {
    r.Method("GET", "/", burrow.Handle(func(w http.ResponseWriter, r *http.Request) error {
        return burrow.Text(w, http.StatusOK, "Hello from Burrow!")
    }))
}

func main() {
    srv := burrow.NewServer(
        &homeApp{},
    )

    cmd := &cli.Command{
        Name:   "myapp",
        Flags:  srv.Flags(nil),
        Action: srv.Run,
    }

    if err := cmd.Run(context.Background(), os.Args); err != nil {
        log.Fatal(err)
    }
}
go mod tidy
go run .

See example/hello/ for a minimal hello world app, or example/notes/ for a complete example with auth, admin, i18n, and more.

Architecture

contrib/        Reusable apps
  admin/        Admin panel coordinator + ModelAdmin
  auth/         WebAuthn passkeys, recovery codes, email verification
  authmail/     Pluggable email renderer + SMTP implementation
  bootstrap/    Bootstrap 5 CSS/JS/htmx assets, theme switcher, layout
  bsicons/      Bootstrap Icons as inline SVG template functions
  csrf/         CSRF protection
  healthcheck/  Liveness and readiness probes
  htmx/         htmx static asset + request/response helpers
  i18n/         Locale detection and translations
  jobs/         SQLite-backed background job queue
  messages/     Flash messages
  ratelimit/    Per-client rate limiting
  session/      Cookie-based sessions
  staticfiles/  Static file serving with content-hashed URLs
  uploads/      File upload storage and serving
example/        Example applications (hello world, notes app)

The App Interface

Every app implements burrow.App:

type App interface {
    Name() string
    Register(cfg *AppConfig) error
}

Apps can optionally implement additional interfaces:

Interface Purpose
Migratable Provide embedded SQL migrations
HasRoutes Register HTTP routes
HasMiddleware Contribute middleware
HasNavItems Contribute navigation items
HasTemplates Contribute .html template files
HasFuncMap Contribute static template functions
HasRequestFuncMap Contribute request-scoped template functions
Configurable Define CLI flags and read configuration
HasCLICommands Contribute CLI subcommands
Seedable Seed the database with initial data
HasAdmin Contribute admin panel routes and nav items
HasStaticFiles Contribute embedded static file assets
HasTranslations Contribute translation files
HasDependencies Declare required apps
HasJobs Register background job handlers
PostConfigurable Second-pass configuration after all apps are configured
HasShutdown Clean up on graceful shutdown

Layouts

Layouts are template name strings. The app layout wraps user-facing pages:

srv.SetLayout("myapp/layout")

The admin layout is owned by the admin package:

admin.New(admin.WithLayout("custom/admin-layout"))

RenderTemplate renders page content, then wraps it in the layout template with .Content set to the rendered fragment. Layout templates access dynamic data via template functions:

{{ range navLinks }}...{{ end }}  {{/* filtered nav with active state */}}
{{ if currentUser }}...{{ end }}  {{/* authenticated user */}}
{{ csrfToken }}                   {{/* CSRF token for forms */}}

Configuration

Configuration is resolved in order: CLI flags > environment variables > TOML file.

Core flags include --host, --port, --database-dsn, --log-level, --log-format, --tls-mode, and more. Apps can contribute their own flags via the Configurable interface.

Migrations

Apps embed their SQL migrations and implement Migratable:

//go:embed migrations
var migrationFS embed.FS

func (a *App) MigrationFS() fs.FS {
    sub, _ := fs.Sub(migrationFS, "migrations")
    return sub
}

Migrations are tracked per-app in the _migrations table and run automatically on startup.

Development

just setup          # Check that all required dev tools are installed
just test           # Run all tests
just lint           # Run golangci-lint
just fmt            # Format code
just coverage       # Generate coverage report
just tidy           # Tidy module dependencies
just example-hello  # Run the hello world example
just example-notes  # Run the notes example application

Requires Go 1.25+. Run just setup to verify your dev environment.

Documentation

Full documentation is available in the docs/ directory.

License

Burrow is licensed under the European Union Public Licence v1.2 (EUPL-1.2). You can build any kind of software on top of Burrow — commercial, proprietary, or open source — without having to open-source your application code. See the licensing guide for details on what the EUPL means for you.

Third-party licenses are listed in THIRD_PARTY_LICENSES.md.

About

A modular Go web framework built on Chi, Bun/SQLite, and html/template — deploy as a single binary.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages