gofastr

module
v0.39.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: MIT

README

GoFastr

The full-stack Go framework that doesn't get in the way of you or your agents.

GoFastr is an experimental full-stack Go framework. Declare your domain in Go and get server-rendered screens, REST endpoints, MCP tools, an OpenAPI spec, SQL migrations, and a typed query builder — plain Go you can read, edit, and own. No reflection, no generated code you can't open. Auth, background jobs, search, and storage are opt-in packages, and you can drop to net/http or database/sql at any point.

It is built for both the agentic web and AI-assisted development. The app you ship joins the agentic web: the agents your users bring call your data over MCP, with the same login and permissions your users have. While you build, gofastr dev hands your coding agent — Claude Code or Codex — the app's routes, config, and logs over MCP, to help build and debug it.

Start with the quickstart. Or scaffold a whole app in one command — screens, API, auth — with the CLI: gofastr init <name>, or gofastr generate from a one-file declaration (blueprint tutorial).

Status: early / v0.x — MIT-licensed and usable, but the API may change between releases, so pin a version (go get …@v0.x.y). A v1.0.0 tag will mark the stability promise. Ship at your own risk until then.

Quickstart

Requires Go 1.26+. Install the CLI:

go install github.com/DonaldMurillo/gofastr/cmd/gofastr@latest

Three complete programs, smallest to fullest — the same three the site's homepage shows (examples/site): plain core/, one framework entity, and the full app shape. CI extracts all three from this README, compiles them, boots them, and curls them (cmd/gofastr/readme_quickstart_test.go).

Core only

core/ is stdlib-first building blocks — router, typed handlers, render, a SQL query builder, schema, migrate, mcp — each usable without the framework. The basic app is one screen and one API route:

package main

import (
	"context"
	"net/http"

	"github.com/DonaldMurillo/gofastr/core/handler"
	"github.com/DonaldMurillo/gofastr/core/render"
	"github.com/DonaldMurillo/gofastr/core/router"
)

type Pong struct {
	Status string `json:"status"`
}

func main() {
	r := router.New()

	// A server-rendered page.
	r.Get("/", render.HTMLHandler(func(req *http.Request) render.HTML {
		return render.Tag("h1", nil, render.Text("Hello from core."))
	}))

	// A typed JSON route — the adapter binds input and serializes output.
	r.Get("/api/ping", handler.HandlerAdapter(func(ctx context.Context, _ struct{}) (Pong, error) {
		return Pong{Status: "ok"}, nil
	}))

	http.ListenAndServe(":8080", r)
}
Framework

One framework entity is a complete server — a migrated table, REST CRUD, an OpenAPI spec, and MCP tools. Add only what you need from there.

package main

import (
	"database/sql"
	"log"

	"github.com/DonaldMurillo/gofastr/core/schema"
	"github.com/DonaldMurillo/gofastr/framework"
	_ "github.com/mattn/go-sqlite3"
)

func main() {
	db, _ := sql.Open("sqlite3", "app.db")
	app := framework.NewApp(framework.WithDB(db), framework.WithMCP()) // WithMCP serves the tools at /mcp

	// CRUD is auto-on when a DB is set (CRUD *bool: nil = auto).
	app.Entity("posts", framework.EntityConfig{
		Public: true, // anonymous read AND write; omit it and CRUD requires a session (secure by default)
		MCP:    true, // emit posts_list/get/create/update/delete MCP tools
		Fields: []schema.Field{{Name: "title", Type: schema.String, Required: true}},
	})

	log.Fatal(app.Start(":8080")) // GET/POST /posts, /openapi.json, MCP — all live
}

That's the whole program. No config files, no codegen step, no registration boilerplate. Add entities-as-JSON, batteries, the UI runtime, or the generator when you need them. For how a flat app grows into internal/<domain>/ as boundaries appear, see project structure.

Donald's Way

The full app shape: server-rendered screens with SEO, an owner-scoped entity API, MCP for agents, and login + sessions — one binary. A screen is Go too: Render returns HTML, and a small JS runtime hydrates it in place — no React or Vue on the client:

package main

import (
	"database/sql"
	"log"

	"github.com/DonaldMurillo/gofastr/battery/auth"
	"github.com/DonaldMurillo/gofastr/core-ui/app"
	"github.com/DonaldMurillo/gofastr/core-ui/html"
	"github.com/DonaldMurillo/gofastr/core/render"
	"github.com/DonaldMurillo/gofastr/core/schema"
	"github.com/DonaldMurillo/gofastr/framework"
	"github.com/DonaldMurillo/gofastr/framework/uihost"
	_ "github.com/mattn/go-sqlite3"
)

// A screen is plain Go: Render returns server-rendered HTML.
type HomeScreen struct{}

func (s *HomeScreen) ScreenTitle() string { return "Notes" }
func (s *HomeScreen) Render() render.HTML {
	return html.Heading(html.HeadingConfig{Level: 1}, render.Text("My notes"))
}

func main() {
	db, _ := sql.Open("sqlite3", "notes.db")

	// Server-rendered screens. Each also serves an auto llm.md.
	ui := app.NewApp("Notes")
	ui.Register("/", &HomeScreen{}, nil)

	// SEO for those pages.
	host := uihost.New(ui,
		uihost.WithDescription("A tiny notes app."),
		uihost.WithOpenGraph(uihost.OG{Title: "Notes", Type: "website"}),
		uihost.WithSitemap(uihost.SitemapConfig{BaseURL: "https://notes.example"}),
	)

	// MCP for agents.
	fwApp := framework.NewUIHostApp(host,
		framework.WithDB(db),
		framework.WithAPIPrefix("/api"),
		framework.WithMCP(),
	)

	// OwnerField scopes rows per user: anonymous → 401, cross-user → 404.
	fwApp.Entity("notes", framework.EntityConfig{
		OwnerField: "user_id",
		MCP:        true,
		Fields:     []schema.Field{{Name: "title", Type: schema.String, Required: true}},
	})

	// Login + sessions.
	authMgr := auth.New(auth.AuthConfig{
		DevMode:      true, // dev only: mints a per-process JWT secret; set JWTSecret in prod
		UserStore:    auth.NewEntityUserStore(db, "auth_users"),
		SessionStore: auth.NewEntitySessionStore(db, "auth_sessions"),
	})
	authMgr.Use(auth.NewCorePlugin())
	if err := authMgr.Init(fwApp); err != nil {
		log.Fatal(err)
	}
	fwApp.Use(auth.SessionMiddleware(authMgr))

	log.Fatal(fwApp.Start(":8080"))
}

GET / is the rendered screen. Anonymous GET /api/notes answers 401 — OwnerField scopes rows per user, and auto-CRUD requires a session unless the entity is Public. /auth/register and /auth/login come from the auth battery, and the MCP tools at /mcp respect the same owner scope as the REST API.

Run it from a clone

To work on the framework itself, or run the examples:

git clone https://github.com/DonaldMurillo/gofastr.git
cd gofastr
go test ./...                        # full suite needs Docker (Postgres testcontainers) and Chrome (chromedp e2e)
go run ./cmd/gofastr --help          # CLI overview
go run ./examples/blog               # minimal blog with auto-CRUD on SQLite

Two Git worktrees of the same app — one per coding agent, for example — can run side by side: with isolation on, each linked worktree gets its own local port and database path, so nothing collides (framework/docs/content/isolation.md).

With the blog example running (go run ./examples/blog), open http://localhost:8080 and try:

curl http://localhost:8080/posts
curl 'http://localhost:8080/posts/search?q=gofastr'   # custom route the example adds
# /openapi.json is auth-gated by default (it enumerates every route).
# Browse it via Swagger UI at /api/docs/, or expose the raw spec with
# framework.WithPublicOpenAPI() and then:
curl http://localhost:8080/openapi.json | jq .info     # auto-generated spec
Updating GoFastr

The module dependency and the installed CLI are versioned independently — keep them on the same release. Read the release notes for the release you're moving to first (breaking changes are marked), then:

go list -m -versions github.com/DonaldMurillo/gofastr    # what's available
go get github.com/DonaldMurillo/gofastr@vX.Y.Z           # the app dependency
go install github.com/DonaldMurillo/gofastr/cmd/gofastr@vX.Y.Z  # the CLI (doesn't update with go.mod)
go mod tidy && go build ./... && go test ./...
go list -m github.com/DonaldMurillo/gofastr              # confirm the selected version

Or let the CLI guide it: gofastr upgrade reads your go.mod, lists every migration note between your version and the target, and points at the affected lines in your code (--apply runs the steps). Full guide: framework/docs/content/upgrading.md or gofastr docs upgrading.

The code you don't write

Routes, validation, migrations, pagination, uploads, spec, agent tools — the framework emits all of it from one declaration (app.Entity in Go, or an entities: entry in a blueprint). Declarations are optional: core/ routes and hand-written screens run without them. A declaration grows the same way it starts — fields, enums, relations, soft delete:

app.Entity("posts", framework.EntityConfig{
    SoftDelete: true,
    Fields: []schema.Field{
        {Name: "title", Type: schema.String, Required: true},
        {Name: "body", Type: schema.Text},
        {Name: "status", Type: schema.Enum,
            Values: []string{"draft", "published"}, Default: "draft"},
        {Name: "author_id", Type: schema.Relation, To: "users"},
    },
    MCP: true,
})
Output Auto-generated
HTTP GET / POST /posts, GET / PUT / PATCH / DELETE /posts/{id}
Batch endpoints POST / PATCH / DELETE /posts/_batch — atomic; one tx for all items
SSE stream GET /posts/_events — entity.created/updated/deleted, scoped per tenant
Filtering ?status=published&views_gte=10&sort=-created_at&page=2
Eager loading ?include=author.profile,comments — flat or nested, validated against the registry
Cursor paging ?cursor=&limit=50 — keyset by EntityConfig.CursorField (defaults to PK)
Multipart upload multipart/form-data on Image/File fields → streamed through WithFileStorage
Validation Required, unique, enum, min/max, regex pattern, multi-tenant scope
Migrations Versioned runner — advisory-lock serialization, checksum-drift + dirty-state guards, NoTransaction escape hatch, a down section when a safe inverse exists; declarative incremental generation; real-Postgres tested
FK constraints BelongsTo relations emit FOREIGN KEY clauses; AutoMigrate topo-sorts tables
Transactions Create/Update/Delete + hooks share one tx; TxFromContext(ctx) exposes it
OpenAPI 3 /openapi.json and Swagger UI at /api/docs/
MCP posts_list, posts_get, posts_create, posts_update, posts_delete
Soft delete deleted_at column + automatic filter
Multi-tenant tenant_id column + automatic scope from request context
Hooks BeforeCreate, AfterUpdate, etc. for custom behaviour
Custom routes EntityConfig.Endpoints with optional MCP exposure
Client SDKs gofastr generate sdk — Go module + JS/TS client artifacts an app can serve via sdkdocs.Mount, with a live docs site (framework/sdkdocs)
Customer CLI gofastr generate cli — a branded terminal client for your customers, scoped API-token auth

Try all of it against a running server: examples/api-tour is the curl tour — eager loading, cursor paging, atomic batch, SSE, uploads, sparse updates. Hooks run inside the write's transaction (hooks-and-transactions).

The design bets

  • Two layers. A small core/ of stdlib-first primitives sits under an opinionated framework/. Use the framework for the common path; drop to core and write plain net/http when it's in your way. (The one external touchpoint is core/middleware/tracing.go, which pulls in OpenTelemetry; the rest of core/ is stdlib-only.)
  • Server-rendered UI, hydrated in place. Screens are Go: Render returns HTML and the server sends the full page. A small JS runtime attaches to it; in-page changes — sort, paginate, add a row — call the server and swap one region, and cross-page navigation swaps content client-side with a route cache, so there are no hard refreshes. No React or Vue on the client, and no router code for you to write.
  • The interactive layer keeps no server state. Sessions are signed tokens, so any replica serves any request. Updates pull first — client signals, then RPC, then polling — and SSE push is reserved for presence and collaboration (reactivity.md).
  • Security scopes live in the declaration, fail-closed. owner_field makes auto-CRUD per-user (anonymous → 401, cross-user → 404), access: gates operations behind RBAC permissions (403), multi_tenant scopes by tenant — and gofastr validate flags PII-shaped fields (email, phone, address, …) exposed without any of them. The MCP tools respect the same scopes as the REST routes.
  • You own the output. The generated code is normal Go you read, debug, commit, edit, and compose from your own main. Registration is ordinary Go in the generated files; no reflection discovers your entities, and no platform sits between your binary and your server.
  • Batteries are separate packages. Auth, cache, email, queue, search, storage sit behind narrow interfaces — swap any one without forking.
  • A blueprint scaffolds the whole app when you want a head start. A single gofastr.yml generates both halves — SQL + REST + OpenAPI + MCP and the screens — in one pass, consistent from the start. Then it's plain Go you own and edit, and the running app never needs the blueprint again. See examples/meridian for the whole pipeline — a SaaS console + marketing site — live and tested.

The repo in 60 seconds

Directory What it is Depend on it when…
core/ Stdlib-only primitives — router, query, schema, render, mcp, openapi, migrate. Each usable on its own. you want plain Go building blocks, no framework.
framework/ The opinionated entity layer (App, EntityConfig, CRUD, hooks, migrations). A thin facade re-exporting its focused runtime subpackages. you want one declaration → SQL + REST + OpenAPI + MCP.
core-ui/ Server-driven UI runtime — html primitives, patterns, widget islands, signals, the vanilla-JS runtime. Independently usable. you're rendering HTML from Go.
battery/ Opt-in infrastructure — admin, auth, cache, email, embed, log, notify, print, queue, search, setup, storage, webhook. Each behind a small interface. you need a real subsystem; import only the ones you use.
cmd/gofastr The CLI — init, generate, pack (lossy app→blueprint snapshot), migrate, build, dev, docs, and more. you're scaffolding or generating code.
kiln Experimental agent build-mode runtime (mutate an in-memory IR over HTTP). you're driving the app from an agent.
examples/ Runnable reference apps — the meridian blueprint flagship (a SaaS billing console + marketing site), the ecommerce blueprint pipeline, plus blog, api-tour, spa, and the docs site. you want to see it wired end-to-end.

You import framework and the batteries you opt into — not each of its subpackages. The subpackage split is an internal seam (see framework/ARCHITECTURE.md); the public API is framework.X plus the batteries you reach for.

Built with GoFastr

In production:

  • Barcode & QR Code Maker — a live tool, no signup required, to generate and read barcodes and QR codes (QR, EAN-13, UPC-A, Code 128, Data Matrix, and more) as PNG, SVG, or PDF, with CSV/Excel batch export to a ZIP, a REST API, and an MCP server. Built and running on GoFastr.

The framework also runs on itself — GoFastr's own tooling and reference apps are built on the same framework, core-ui, and batteries a user app imports:

  • examples/site, the docs site and canonical component gallery, runs on framework + framework/ui + framework/uihost + the core-ui pattern presets + battery/print.
  • examples/meridian, the declaration-first flagship, is generated from a gofastr.yml blueprint — a SaaS billing console (customers, subscriptions, invoices with status workflows, MRR + charts) and its public marketing site, auth, RBAC, and admin back-office, with writable app screens (add/edit/delete) and the generated end-to-end test suite green.
  • examples/ecommerce, a second blueprint pipeline (five entities, owner-scoped orders), is generated the same way and exercised by its own end-to-end test.

Both blueprint apps are secure by default and carry a generated end-to-end test suite — every screen, the full create→edit→delete lifecycle, and RBAC asserted — the suite itself generated, not hand-written (each app is scaffolded from its gofastr.yml and then extended in owned Go, e.g. Meridian's sdkdocs mount and brand CSS).

The project uses these tools on itself. External production adopters are the part still ahead of us — see Project status.

Documentation

Every doc below is embedded into the gofastr binary — gofastr docs browses them offline, and the framework_docs_* MCP tools expose them to agents connected to a running app.

  • The gofastr CLI — every subcommand mapped to its doc: init, dev, migrate, generate, audit, upgrade
  • Blueprint tutorialgenerate a whole app from one file: blueprint → generated UI + API → auth + owner scoping + RBAC → customize in plain Go → deploy
  • Kiln (experimental) — agent-driven build mode
  • UI capability mapstart from the job: architecture, state ownership, delivery/scaling semantics, runnable proof, and explicit non-goals
  • UI getting startedthe 15-minute path: scaffold → design direction → theme → framework-native composition
  • UI composition recipes — product-shaped page structures built entirely from framework/ui primitives
  • UI components indexthe catalog: every component the framework ships, with its go doc path and live demo at /components/<slug> in examples/site
  • core-ui architecturedeeper UI/runtime reference (SSR, hydration, islands, component CSS, data-fui-* primitives)
  • Interactive patterns — every data-fui-* behavior, plus "Writing a hand-written island, end to end" (no-reload updates on your own screens) and themed confirms
  • framework architecture — package layout, layering rules, cycle-breaking interfaces
  • Entity declarations — JSON schema reference
  • Migrations — versioned migrations and the CLI
  • Query DSLEntity.where(...).order(...).limit(N)
  • Search — the battery/search interface
  • Embed — local semantic search via battery/embed
  • Security — defaults, headers, and limits
  • Deployment — single-binary build, graceful shutdown, production checklist
  • Horizontal scaling — what's process-local by default and the replica-safe alternative for each
  • Observability — metrics and tracing
  • PWA — installable app manifest + versioned offline shell via uihost.WithPWA
  • Agent-ready — the discovery endpoints for AI agents (llms.txt, agent card, MCP)

The full, per-topic index lives in the docs site catalogue (gofastr docs --list, or examples/site/docs_catalog.go), which a parity test keeps in sync with every embedded page. The list above is a curated subset.

Project status

GoFastr is pre-1.0 and explicitly not stable:

  • The core/ primitives are usable and tested in isolation.
  • The framework/ entity layer handles SQLite + Postgres CRUD apps today.
  • core-ui/ changes fastest — APIs may break between commits.
  • The CLI binary blank-imports only github.com/mattn/go-sqlite3. To run migrations against Postgres, build a custom binary that imports your driver of choice.

Why this exists

This is a personal project first — a way to practice building something large alongside AI. A few things I wanted to dig into:

  • Solidify my web-tech foundations. Rebuild the stack from the socket up so the fundamentals stop feeling like magic.
  • Attack UI generation from a different angle. My background is in Node, so I wanted to see what server-rendered, server-driven UI looks like when you take the heavy client framework off the table and generate the markup in a compiled language instead.
  • Work in a compiled language. Most of what I've built is in Node, where mistakes surface at runtime, in production. I wanted to know what it's like when a compiler catches them first — when you ship one binary and types actually hold up under a refactor.
  • Skip the convention-vs-configuration false choice. When it's your own framework you don't have to pick a side — you get opinionated defaults and a hatch down to plain stdlib code in the same app.
  • Build something large, fun, and open source with AI. Most of this repo was written alongside coding agents, so the workflow itself is part of the experiment.
  • Build for agents on both sides. In production, the agents your users bring call the app's data over MCP — with the same login and permissions the users have. While you build, gofastr dev hands your coding agent the running app's routes, config, and logs over MCP. Both fall out of writing plain, readable Go.

Contributing

This repo is a personal research tree at the moment. Issues and PRs are welcome but expect strong opinions about scope: the goal is a framework an AI agent can drive end-to-end, not a kitchen-sink CMS.

Before pushing, the .githooks/pre-push gate runs go test -race -count=1 ./... and govulncheck. Enable hooks once with:

git config core.hooksPath .githooks
Testing against Postgres

The framework's tests fan over both SQLite and Postgres. With Docker running, every dialect-aware test runs on both engines automatically:

make test            # SQLite only, fast
make test-pg         # both dialects via testcontainers (Docker)
make test-pg-env     # both dialects, points at TEST_POSTGRES_DSN
make test-race       # race detector across the whole repo

Each Postgres test gets its own schema for isolation; the container is shared across the whole go test invocation so cold-start is amortised.

License

GoFastr is released under the MIT License — free to use, modify, and distribute, including in commercial and closed-source projects, provided the copyright notice and license text are preserved. The software is provided "as is", without warranty; see LICENSE for the full terms.

Directories

Path Synopsis
battery
admin
Package admin is a small read-only admin battery for GoFastr apps — stock screens on top of the data the framework already collects: queue jobs (when battery/queue is wired) and the audit log (when framework.WithAuditLog is set).
Package admin is a small read-only admin battery for GoFastr apps — stock screens on top of the data the framework already collects: queue jobs (when battery/queue is wired) and the audit log (when framework.WithAuditLog is set).
auth
Package auth is GoFastr's authentication subsystem.
Package auth is GoFastr's authentication subsystem.
cache
Package cache is part of the GoFastr framework.
Package cache is part of the GoFastr framework.
email
Package email is part of the GoFastr framework.
Package email is part of the GoFastr framework.
embed
Package embed provides a local semantic-search battery for GoFastr.
Package embed provides a local semantic-search battery for GoFastr.
experimental/redisflags
Package redisflags provides a Redis-backed feature flag store for the core/featureflag evaluator.
Package redisflags provides a Redis-backed feature flag store for the core/featureflag evaluator.
experimental/redisidempotency
Package redisidempotency provides a Redis-backed store for the idempotency middleware.
Package redisidempotency provides a Redis-backed store for the idempotency middleware.
log
Package log is the GoFastr server-log plugin.
Package log is the GoFastr server-log plugin.
notify
Package notify is a small unified-notifications primitive for GoFastr apps.
Package notify is a small unified-notifications primitive for GoFastr apps.
print
Package print is a GoFastr battery for printable documents.
Package print is a GoFastr battery for printable documents.
print/chromepdf
Package chromepdf is the headless-Chromium PDF backend for the github.com/DonaldMurillo/gofastr/battery/print battery.
Package chromepdf is the headless-Chromium PDF backend for the github.com/DonaldMurillo/gofastr/battery/print battery.
queue
Package queue is part of the GoFastr framework.
Package queue is part of the GoFastr framework.
search
Package search provides pluggable search backends for GoFastr.
Package search provides pluggable search backends for GoFastr.
setup
Package setup provides a first-run setup flow for self-hosted GoFastr apps.
Package setup provides a first-run setup flow for self-hosted GoFastr apps.
storage
Package storage is part of the GoFastr framework.
Package storage is part of the GoFastr framework.
webhook
Package webhook is the outbound-webhook battery for GoFastr.
Package webhook is the outbound-webhook battery for GoFastr.
benchmarks
apps/crud command
crud is the typical entity-CRUD shape: one entity backed by SQLite, auto-migrate, full CRUD routes.
crud is the typical entity-CRUD shape: one entity backed by SQLite, auto-migrate, full CRUD routes.
apps/full command
full is a realistic shape with every supported framework surface wired on at once: three related entities with relations, audit log, cron, MCP, the UI host with one screen, file storage, search backend, access control, multi-tenancy, custom endpoints, plugins, and the OpenAPI + Swagger UI surface.
full is a realistic shape with every supported framework surface wired on at once: three related entities with relations, audit log, cron, MCP, the UI host with one screen, file storage, search backend, access control, multi-tenancy, custom endpoints, plugins, and the OpenAPI + Swagger UI surface.
apps/minimal command
minimal is the smallest meaningful GoFastr binary: NewApp + one plaintext route.
minimal is the smallest meaningful GoFastr binary: NewApp + one plaintext route.
cmd
bench-resources command
bench-resources measures binary size, peak RAM during `go build`, and runtime RAM (idle + under load) for the bench apps under benchmarks/apps/ plus cmd/gofastr and cmd/kiln.
bench-resources measures binary size, peak RAM during `go build`, and runtime RAM (idle + under load) for the bench apps under benchmarks/apps/ plus cmd/gofastr and cmd/kiln.
check-csp command
check-csp is a build-time linter that fails when production Go source emits inline <script> blocks.
check-csp is a build-time linter that fails when production Go source emits inline <script> blocks.
gofastr command
Package main — `gofastr harness` subcommand.
Package main — `gofastr harness` subcommand.
kiln command
kiln is the Kiln runtime CLI.
kiln is the Kiln runtime CLI.
repolint command
Package codegen provides YAML-driven code generation primitives for GoFastr.
Package codegen provides YAML-driven code generation primitives for GoFastr.
core
config
Package config provides a first-class configuration loader that binds environment variables, config files, and secret sources into typed Go structs with validation.
Package config provides a first-class configuration loader that binds environment variables, config files, and secret sources into typed Go structs with validation.
dotenv
Package dotenv parses .env files into a map and (optionally) applies them to the process environment.
Package dotenv parses .env files into a map and (optionally) applies them to the process environment.
fanout
Package fanout carries real-time messages between replicas.
Package fanout carries real-time messages between replicas.
featureflag
Package featureflag is a minimal feature-flag primitive for GoFastr apps.
Package featureflag is a minimal feature-flag primitive for GoFastr apps.
fuzzy
Package fuzzy holds small string-similarity helpers shared across the codebase.
Package fuzzy holds small string-similarity helpers shared across the codebase.
handler
Package handler is part of the GoFastr framework.
Package handler is part of the GoFastr framework.
i18n
Package i18n is a small internationalization primitive for GoFastr apps: locale negotiation from `Accept-Language`, JSON-backed message catalogs with `{{placeholder}}` interpolation, and CLDR-style plural categories (zero / one / two / few / many / other) with sensible English defaults and a hook for per-locale custom rules.
Package i18n is a small internationalization primitive for GoFastr apps: locale negotiation from `Accept-Language`, JSON-backed message catalogs with `{{placeholder}}` interpolation, and CLDR-style plural categories (zero / one / two / few / many / other) with sensible English defaults and a hook for per-locale custom rules.
markdown
Package markdown is a small, dependency-free Markdown renderer.
Package markdown is a small, dependency-free Markdown renderer.
mcp
Package mcp is part of the GoFastr framework.
Package mcp is part of the GoFastr framework.
middleware
Package middleware is part of the GoFastr framework.
Package middleware is part of the GoFastr framework.
migrate
Package migrate is a versioned SQL migration runner with optional per-group migration streams.
Package migrate is a versioned SQL migration runner with optional per-group migration streams.
moduleproto
Package moduleproto implements the wire protocol between the GoFastr host process and an out-of-process third-party module, as specified by issue #37 (design §4).
Package moduleproto implements the wire protocol between the GoFastr host process and an out-of-process third-party module, as specified by issue #37 (design §4).
openapi
Package openapi is part of the GoFastr framework.
Package openapi is part of the GoFastr framework.
query
Package query is part of the GoFastr framework.
Package query is part of the GoFastr framework.
render
Package render is part of the GoFastr framework.
Package render is part of the GoFastr framework.
router
Package router is part of the GoFastr framework.
Package router is part of the GoFastr framework.
schema
Package schema is part of the GoFastr framework.
Package schema is part of the GoFastr framework.
static
Package static is part of the GoFastr framework.
Package static is part of the GoFastr framework.
stream
Package stream is part of the GoFastr framework.
Package stream is part of the GoFastr framework.
upload
Package upload is part of the GoFastr framework.
Package upload is part of the GoFastr framework.
core-ui
app
Package app is the URL → rendered page pipeline for GoFastr UI.
Package app is the URL → rendered page pipeline for GoFastr UI.
app/decide
Package decide provides the constructors for app.Decision values returned from Policy.Decide implementations.
Package decide provides the constructors for app.Decision values returned from Policy.Decide implementations.
check
Package check provides an AST-based linter for .ui.go files.
Package check provides an AST-based linter for .ui.go files.
component
Package component defines the component model for GoFastr's core-ui framework.
Package component defines the component model for GoFastr's core-ui framework.
compute
Package compute registers content-addressed Web Worker and WebAssembly assets for GoFastr applications.
Package compute registers content-addressed Web Worker and WebAssembly assets for GoFastr applications.
di
html
Package html provides semantic, ADA-compliant HTML element primitives for the GoFastr core-ui framework.
Package html provides semantic, ADA-compliant HTML element primitives for the GoFastr core-ui framework.
interactive
Package interactive provides declarative interactivity primitives for GoFastr components.
Package interactive provides declarative interactivity primitives for GoFastr components.
island
Package island is the runtime-side manager for server-driven SSE updates.
Package island is the runtime-side manager for server-driven SSE updates.
node
Package node is the JSON-clean UI element tree — the serializable description of a screen that renders to HTML via core-ui/noderender.
Package node is the JSON-clean UI element tree — the serializable description of a screen that renders to HTML via core-ui/noderender.
patterns/accordion
Package accordion provides disclosure widgets built on the native <details>/<summary> html.
Package accordion provides disclosure widgets built on the native <details>/<summary> html.
patterns/breadcrumbs
Package breadcrumbs renders an ARIA-correct breadcrumb trail.
Package breadcrumbs renders an ARIA-correct breadcrumb trail.
patterns/combobox
Package combobox implements the WAI-ARIA Combobox 1.2 pattern as a server-rendered input that's bound to a debounced RPC dropdown.
Package combobox implements the WAI-ARIA Combobox 1.2 pattern as a server-rendered input that's bound to a debounced RPC dropdown.
patterns/disclosure
Package disclosure renders a single styled <details>/<summary> disclosure section.
Package disclosure renders a single styled <details>/<summary> disclosure section.
patterns/infinitescroll
Package infinitescroll provides a sentinel-based infinite-scroll container that lazily fetches the next page of items via RPC as the user scrolls.
Package infinitescroll provides a sentinel-based infinite-scroll container that lazily fetches the next page of items via RPC as the user scrolls.
patterns/multiselect
Package multiselect renders a checkbox-group inside a disclosure with chip rendering of the selected values above the trigger.
Package multiselect renders a checkbox-group inside a disclosure with chip rendering of the selected values above the trigger.
patterns/nestedlist
Package nestedlist renders recursive <ul>/<ol> hierarchies with optional native <details> collapse on branches.
Package nestedlist renders recursive <ul>/<ol> hierarchies with optional native <details> collapse on branches.
patterns/pagination
Package pagination renders a numeric pagination nav.
Package pagination renders a numeric pagination nav.
patterns/progress
Package progress provides a thin wrapper around the native <progress> element with theme-aware styling.
Package progress provides a thin wrapper around the native <progress> element with theme-aware styling.
patterns/scrollspy
Package scrollspy attaches IntersectionObserver-based section tracking to any list of in-page anchors.
Package scrollspy attaches IntersectionObserver-based section tracking to any list of in-page anchors.
patterns/skeleton
Package skeleton provides shimmer placeholders rendered with pure CSS.
Package skeleton provides shimmer placeholders rendered with pure CSS.
patterns/sortablelist
Package sortablelist renders a reorderable list with HTML5 drag-and-drop plus keyboard fallback (Space to grab, Arrow up/down to move within a column, Arrow left/right to move between columns, Space again to drop, Esc to cancel).
Package sortablelist renders a reorderable list with HTML5 drag-and-drop plus keyboard fallback (Space to grab, Arrow up/down to move within a column, Arrow left/right to move between columns, Space again to drop, Esc to cancel).
patterns/tabs
Package tabs provides a tabbed-content layout with zero JavaScript.
Package tabs provides a tabbed-content layout with zero JavaScript.
patterns/tree
Package tree provides a TreeView component built on the WAI-ARIA tree pattern.
Package tree provides a TreeView component built on the WAI-ARIA tree pattern.
registry
Package registry is the process-global catalog of components whose CSS is shipped as real stylesheets and loaded on demand by the runtime.
Package registry is the process-global catalog of components whose CSS is shipped as real stylesheets and loaded on demand by the runtime.
runtime
Package runtime provides the GoFastr client-side JavaScript runtime as an embedded resource.
Package runtime provides the GoFastr client-side JavaScript runtime as an embedded resource.
runtime/minify
Package minify implements a token-aware JavaScript minifier used to shrink the embedded runtime sources before they're served.
Package minify implements a token-aware JavaScript minifier used to shrink the embedded runtime sources before they're served.
seo
Package seo provides typed Schema.org structs that marshal to the JSON-LD shape Google and other crawlers consume for rich results (FAQ snippets, product cards, breadcrumb trails, article cards).
Package seo provides typed Schema.org structs that marshal to the JSON-LD shape Google and other crawlers consume for rich results (FAQ snippets, product cards, breadcrumb trails, article cards).
store
Package store is a typed, server-declared shared-state primitive for the GoFastr UI.
Package store is a typed, server-declared shared-state primitive for the GoFastr UI.
style
Package style provides the typed design system and CSS builders for the GoFastr core-ui framework.
Package style provides the typed design system and CSS builders for the GoFastr core-ui framework.
uinodev1
Package uinodev1 implements the closed ui.node.v1 wire type and validator for process-isolated third-party modules (design §9, issue #37).
Package uinodev1 implements the closed ui.node.v1 wire type and validator for process-isolated third-party modules (design §9, issue #37).
widget
Package widget provides the framework's overlay-UI primitive.
Package widget provides the framework's overlay-UI primitive.
widget/preset
Package preset bundles the most common widget surfaces as opinionated builders on top of widget.Definition.
Package preset bundles the most common widget surfaces as opinionated builders on top of widget.Definition.
widget/theme
Package theme provides the framework's default page theme — the visual identity for any app built via core-ui (or its consumers like kiln).
Package theme provides the framework's default page theme — the visual identity for any app built via core-ui (or its consumers like kiln).
evals
examples
api-tour command
Package main is a tour of the v2 API surface added to the framework:
Package main is a tour of the v2 API surface added to the framework:
backoffice command
Command backoffice is a minimal example of the battery/admin entity CRUD admin rendered through a UI host: a few entities, a (demo-grade) login, and admin.New(...) generating the whole back-office with defaults.
Command backoffice is a minimal example of the battery/admin entity CRUD admin rendered through a UI host: a few entities, a (demo-grade) login, and admin.New(...) generating the whole back-office with defaults.
blog command
ecommerce
Package ecommerce is GoFastr's declaration-driven flagship example: a complete storefront — five related entities, screens, navigation, custom endpoints, seed data, and a theme — declared once in gofastr.yml and emitted as runnable Go by the CLI:
Package ecommerce is GoFastr's declaration-driven flagship example: a complete storefront — five related entities, screens, navigation, custom endpoints, seed data, and a theme — declared once in gofastr.yml and emitted as runnable Go by the CLI:
ecommerce/app command
Code generated by gofastr.
Code generated by gofastr.
embed-demo command
Package main is a minimal demonstration of the battery/embed package.
Package main is a minimal demonstration of the battery/embed package.
meridian command
Code generated by gofastr.
Code generated by gofastr.
meridian/cmd/meridian command
meridian is a terminal client for your app's HTTP API, generated by `gofastr generate cli --binary=meridian`.
meridian is a terminal client for your app's HTTP API, generated by `gofastr generate cli --binary=meridian`.
processmodule-demo command
Package main is the processmodule-demo: a minimal but real third-party module that speaks the moduleproto protocol over stdio.
Package main is the processmodule-demo: a minimal but real third-party module that speaks the moduleproto protocol over stdio.
site command
spa command
static-site command
Package framework is the public surface of the GoFastr framework.
Package framework is the public surface of the GoFastr framework.
agentsinv
Package agentsinv is a process-wide registry of agent-onboarding snippets contributed by batteries and the framework root.
Package agentsinv is a process-wide registry of agent-onboarding snippets contributed by batteries and the framework root.
datexport
Package datexport is a process-wide registry of data-bearing tables that live OUTSIDE the framework entity registry — the physical tables a battery (auth sessions, the job queue, …) or an app creates with raw DDL.
Package datexport is a process-wide registry of data-bearing tables that live OUTSIDE the framework entity registry — the physical tables a battery (auth sessions, the job queue, …) or an app creates with raw DDL.
db
Package db holds shared low-level database abstractions used across the GoFastr framework subpackages.
Package db holds shared low-level database abstractions used across the GoFastr framework subpackages.
dev
Package dev provides dev-mode-only helpers (livereload, debug surfaces).
Package dev provides dev-mode-only helpers (livereload, debug surfaces).
docs
Package docs ships the framework's user-facing markdown docs as an embedded filesystem.
Package docs ships the framework's user-facing markdown docs as an embedded filesystem.
dsl
experimental/apiversions
Package apiversions provides first-class API versioning built on top of route groups.
Package apiversions provides first-class API versioning built on top of route groups.
factory
Package factory provides Rails-style fixture / factory helpers for GoFastr tests and dev-time seeders.
Package factory provides Rails-style fixture / factory helpers for GoFastr tests and dev-time seeders.
fanout
Package fanout provides a Postgres-backed implementation of core/fanout.Fanout using LISTEN/NOTIFY.
Package fanout provides a Postgres-backed implementation of core/fanout.Fanout using LISTEN/NOTIFY.
harness
Package harness is part of the GoFastr harness.
Package harness is part of the GoFastr harness.
harness/client
Package client is part of the GoFastr harness.
Package client is part of the GoFastr harness.
harness/client/tui
Package tui is part of the GoFastr harness.
Package tui is part of the GoFastr harness.
harness/client/web
Package web is part of the GoFastr harness.
Package web is part of the GoFastr harness.
harness/context
Package context is part of the GoFastr harness.
Package context is part of the GoFastr harness.
harness/control
Package control is part of the GoFastr harness.
Package control is part of the GoFastr harness.
harness/control/auth
Package auth implements the capability-token model: claim set, internal JWT-like encoding (no third-party dep), revocation list, and the issuance flow with TTY/notification confirmation.
Package auth implements the capability-token model: claim set, internal JWT-like encoding (no third-party dep), revocation list, and the issuance flow with TTY/notification confirmation.
harness/control/conformance
Package conformance is the cross-transport parity test framework.
Package conformance is the cross-transport parity test framework.
harness/control/inproc
Package inproc is part of the GoFastr harness.
Package inproc is part of the GoFastr harness.
harness/control/mcpserver
Package mcpserver will expose the harness engine as an MCP server.
Package mcpserver will expose the harness engine as an MCP server.
harness/control/multiplex
Package multiplex is part of the GoFastr harness.
Package multiplex is part of the GoFastr harness.
harness/control/resources
Package resources is part of the GoFastr harness.
Package resources is part of the GoFastr harness.
harness/control/rest
Package rest is part of the GoFastr harness.
Package rest is part of the GoFastr harness.
harness/control/ws
Package ws will implement the WebSocket transport for the control plane.
Package ws will implement the WebSocket transport for the control plane.
harness/engine
Package engine is part of the GoFastr harness.
Package engine is part of the GoFastr harness.
harness/hook
Package hook is part of the GoFastr harness.
Package hook is part of the GoFastr harness.
harness/ids
Package ids is part of the GoFastr harness.
Package ids is part of the GoFastr harness.
harness/internal/clock
Package clock provides a swap-able clock for tests.
Package clock provides a swap-able clock for tests.
harness/internal/ulid
Package ulid is part of the GoFastr harness.
Package ulid is part of the GoFastr harness.
harness/logging
Package logging is part of the GoFastr harness.
Package logging is part of the GoFastr harness.
harness/mcpclient
Package mcpclient implements the MCP client (consumer side) the harness uses to talk to external MCP servers.
Package mcpclient implements the MCP client (consumer side) the harness uses to talk to external MCP servers.
harness/memory
Package memory is part of the GoFastr harness.
Package memory is part of the GoFastr harness.
harness/plugin
Package plugin is part of the GoFastr harness.
Package plugin is part of the GoFastr harness.
harness/profile
Package profile is part of the GoFastr harness.
Package profile is part of the GoFastr harness.
harness/provider
Package provider is part of the GoFastr harness.
Package provider is part of the GoFastr harness.
harness/provider/copilot
Package copilot implements the GitHub Copilot Provider.
Package copilot implements the GitHub Copilot Provider.
harness/provider/credstore
Package credstore implements credential storage.
Package credstore implements credential storage.
harness/provider/failover
Package failover composes a chain of Providers with a circuit-breaker per upstream.
Package failover composes a chain of Providers with a circuit-breaker per upstream.
harness/provider/helper
Package helper is part of the GoFastr harness.
Package helper is part of the GoFastr harness.
harness/provider/internal/openai
Package openai is an internal OpenAI-compatible adapter used by the OpenRouter and ZAI providers (both speak the same wire shape).
Package openai is an internal OpenAI-compatible adapter used by the OpenRouter and ZAI providers (both speak the same wire shape).
harness/provider/openrouter
Package openrouter is part of the GoFastr harness.
Package openrouter is part of the GoFastr harness.
harness/provider/routing
Package routing will implement RoutingProvider: a Provider that composes {router, executors[]} so a single turn can use a cheap model for routing and an expensive model for execution.
Package routing will implement RoutingProvider: a Provider that composes {router, executors[]} so a single turn can use a cheap model for routing and an expensive model for execution.
harness/provider/zai
Package zai is part of the GoFastr harness.
Package zai is part of the GoFastr harness.
harness/secrets
Package secrets locates and loads the repo-local .harness-secrets/env file.
Package secrets locates and loads the repo-local .harness-secrets/env file.
harness/session
Package session is part of the GoFastr harness.
Package session is part of the GoFastr harness.
harness/session/sqlite
Package sqlite is part of the GoFastr harness.
Package sqlite is part of the GoFastr harness.
harness/skill
Package skill is part of the GoFastr harness.
Package skill is part of the GoFastr harness.
harness/skill/skillmd
Package skillmd is part of the GoFastr harness.
Package skillmd is part of the GoFastr harness.
harness/slash
Package slash is part of the GoFastr harness.
Package slash is part of the GoFastr harness.
harness/tool
Package tool is part of the GoFastr harness.
Package tool is part of the GoFastr harness.
harness/tool/builtins
Package builtins is part of the GoFastr harness.
Package builtins is part of the GoFastr harness.
harness/tool/pack
Package pack is part of the GoFastr harness.
Package pack is part of the GoFastr harness.
harness/tool/permission
Package permission is part of the GoFastr harness.
Package permission is part of the GoFastr harness.
harness/tracing
Package tracing is part of the GoFastr harness.
Package tracing is part of the GoFastr harness.
i18nui
Package i18nui provides translated default strings for framework UI surfaces.
Package i18nui provides translated default strings for framework UI surfaces.
image
Package image is a chainable image pipeline: decode → transform → encode, pure Go with only the standard library and golang.org/x/image as dependencies.
Package image is a chainable image pipeline: decode → transform → encode, pure Go with only the standard library and golang.org/x/image as dependencies.
image/internal/vp8l
Package vp8l implements a pure-Go VP8L (WebP lossless) encoder.
Package vp8l implements a pure-Go VP8L (WebP lossless) encoder.
internal/casing
Package casing holds snake_case <-> camelCase helpers used internally by the GoFastr framework.
Package casing holds snake_case <-> camelCase helpers used internally by the GoFastr framework.
internal/testdb
Package testdb provides shared per-test database helpers used by the framework's internal tests AND by framework_test (external) tests that can't access package-private helpers.
Package testdb provides shared per-test database helpers used by the framework's internal tests AND by framework_test (external) tests that can't access package-private helpers.
isolation
Package isolation resolves worktree-specific local runtime resources.
Package isolation resolves worktree-specific local runtime resources.
lifecycle
Package lifecycle provides a documented, cooperative graceful-shutdown contract for GoFastr applications.
Package lifecycle provides a documented, cooperative graceful-shutdown contract for GoFastr applications.
outbox
Package outbox implements a transactional outbox for reliable event delivery to declared durable consumers.
Package outbox implements a transactional outbox for reliable event delivery to declared durable consumers.
owner
Package owner provides a single seam for "who owns this row" lookups during CRUD operations.
Package owner provides a single seam for "who owns this row" lookups during CRUD operations.
pluginhost
Package pluginhost is the reusable, plugin-agnostic host glue for GoFastr heavy-JS plugins that run inside an opaque-origin sandboxed iframe.
Package pluginhost is the reusable, plugin-agnostic host glue for GoFastr heavy-JS plugins that run inside an opaque-origin sandboxed iframe.
routegroup
Package routegroup provides the App-level route group abstraction.
Package routegroup provides the App-level route group abstraction.
sdk
Package sdk is the shared contract between `gofastr generate sdk` (which emits client SDKs and packs the downloadable artifacts) and the serving side (framework/sdkdocs, which hosts them).
Package sdk is the shared contract between `gofastr generate sdk` (which emits client SDKs and packs the downloadable artifacts) and the serving side (framework/sdkdocs, which hosts them).
sdkdocs
Package sdkdocs serves a public SDK documentation site for a GoFastr app — install guides, a live per-entity API reference, auth and error guides — plus download routes for the pregenerated SDK artifacts that `gofastr generate sdk` emits (see framework/sdk for the shared contract).
Package sdkdocs serves a public SDK documentation site for a GoFastr app — install guides, a live per-entity API reference, auth and error guides — plus download routes for the pregenerated SDK artifacts that `gofastr generate sdk` emits (see framework/sdk for the shared contract).
static
Package static implements static-site generation for a framework.App with a UIHost mounted on it.
Package static implements static-site generation for a framework.App with a UIHost mounted on it.
testkit
Package testkit provides PUBLIC test helpers for host apps that use the GoFastr framework.
Package testkit provides PUBLIC test helpers for host apps that use the GoFastr framework.
ui
Package ui is the framework's opinionated component layer on top of core-ui.
Package ui is the framework's opinionated component layer on top of core-ui.
ui/theme
Package theme is the canonical home for the framework's visual design system.
Package theme is the canonical home for the framework's visual design system.
uihost
Package uihost wires a core-ui application onto a framework.App's router.
Package uihost wires a core-ui application onto a framework.App's router.
uihost/internal/sessiontoken
Package sessiontoken mints and verifies the stateless HMAC-signed tokens that replace the uihost's in-memory session map.
Package sessiontoken mints and verifies the stateless HMAC-signed tokens that replace the uihost's in-memory session map.
uihost/uinoderender
Package uinoderender maps a validated ui.node.v1 tree (github.com/DonaldMurillo/gofastr/core-ui/uinodev1.Tree) to host-owned HTML by composing the framework's design-system primitives — github.com/DonaldMurillo/gofastr/framework/ui and github.com/DonaldMurillo/gofastr/core-ui/html.
Package uinoderender maps a validated ui.node.v1 tree (github.com/DonaldMurillo/gofastr/core-ui/uinodev1.Tree) to host-owned HTML by composing the framework's design-system primitives — github.com/DonaldMurillo/gofastr/framework/ui and github.com/DonaldMurillo/gofastr/core-ui/html.
internal
axetest
Package axetest is a shared axe-core accessibility-testing harness for GoFastr example apps and the framework's own chromedp suites.
Package axetest is a shared axe-core accessibility-testing harness for GoFastr example apps and the framework's own chromedp suites.
pgtest
Package pgtest provides a shared real-Postgres test harness usable from any package in the module (core/migrate, cmd/gofastr, …) without importing framework/internal/testdb, which is import-restricted to the framework tree.
Package pgtest provides a shared real-Postgres test harness usable from any package in the module (core/migrate, cmd/gofastr, …) without importing framework/internal/testdb, which is import-restricted to the framework tree.
kiln
agent
Package agent is Kiln's transport-agnostic LLM driver.
Package agent is Kiln's transport-agnostic LLM driver.
agent/acp
Package acp adapts Kiln to the Agent Client Protocol so external agent harnesses (Codex, Copilot, Pi, Claude Code) can drive Kiln as an attached agent server.
Package acp adapts Kiln to the Agent Client Protocol so external agent harnesses (Codex, Copilot, Pi, Claude Code) can drive Kiln as an attached agent server.
agent/mcp
Package mcp wraps Kiln's tool surface as a Model Context Protocol server.
Package mcp wraps Kiln's tool surface as a Model Context Protocol server.
chat
Package chat installs the in-app Kiln chat panel.
Package chat installs the in-app Kiln chat panel.
db
Package db owns the per-session ephemeral SQLite lifecycle for Kiln.
Package db owns the per-session ephemeral SQLite lifecycle for Kiln.
effect
Package effect runs declarative actions described by world.Action.
Package effect runs declarative actions described by world.Action.
expr
Package expr is Kiln's tiny expression evaluator.
Package expr is Kiln's tiny expression evaluator.
freeze
Package freeze emits canonical source artifacts from a Kiln world so the in-memory build-mode app can graduate to a regular GoFastr project.
Package freeze emits canonical source artifacts from a Kiln world so the in-memory build-mode app can graduate to a regular GoFastr project.
journal
Package journal is the append-only event log that backs every Kiln session.
Package journal is the append-only event log that backs every Kiln session.
live
Package live is the runtime that ties the Kiln components together during a session: it owns the current Session (world + chat + plans), the Journal that persists every edit, the framework.App that serves the live preview, and the SSE broadcaster that notifies the panel.
Package live is the runtime that ties the Kiln components together during a session: it owns the current Session (world + chat + plans), the Journal that persists every edit, the framework.App that serves the live preview, and the SSE broadcaster that notifies the panel.
noderender
Package noderender re-exports the first-party node renderer that now lives in core-ui/noderender.
Package noderender re-exports the first-party node renderer that now lives in core-ui/noderender.
protocol
Package protocol is Kiln's canonical agent tool surface.
Package protocol is Kiln's canonical agent tool surface.
render
Package render bridges the Kiln world IR to a runnable framework.App.
Package render bridges the Kiln world IR to a runnable framework.App.
world
Package world is the JSON-clean intermediate representation of a GoFastr application being built live by an agent inside Kiln.
Package world is the JSON-clean intermediate representation of a GoFastr application being built live by an agent inside Kiln.
Package sqlite provides a pure-Go SQLite implementation with zero external dependencies.
Package sqlite provides a pure-Go SQLite implementation with zero external dependencies.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL