Overview — what GoFastr is, and everything it does
GoFastr is a full-stack Go framework where AI agents are first-class
authors. You describe a domain — entities, fields, relations — as a typed
declaration, and the framework generates the database schema, a REST API, MCP
tools for agents, OpenAPI, and a typed Go model from that one source. Everything
else is regular, readable Go you can grep, debug, and step through. No
reflection magic, no opaque runtime.
The promise: opinionated input, boring output, small runtime, easy escape
hatches. GoFastr is a code-generation platform for CRUD-heavy and AI-authored
apps — not a universal framework that owns your control flow. Start with one
entity and add only what you need; when the framework is in your way, drop to
core/ and write plain net/http. And because an agent often writes the code,
the output is built to be more inspectable, not less — plain Go on disk, no
reflection injection or hidden registries.
This page is the map. It explains the shape of the framework and links every
feature to its reference doc. If you're new, read this top-to-bottom once, then
jump to the section that matches what you're building.
New to the framework? Pair this with
UI getting started for the
cold-machine-to-running-app path, and the
Project structure guide for how a real app
is laid out and grows.
The one idea
Most frameworks assume a human hand-writes every route, query, validator,
migration, and form. Agents already generate that code — but no framework treats
their output as the canonical source. GoFastr inverts that: the entity
declaration is the source, and the database, API, agent tools, and admin UI
are generated from it. The agent writes the declaration; so does the human; the
framework is what they both write to.
app := framework.NewApp()app.Entity("posts", entity.EntityConfig{ Fields: []schema.Field{ {Name: "title", Type: schema.String, Required: true}, {Name: "body", Type: schema.Text}, {Name: "published", Type: schema.Bool}, },})app.Start(":8080")
That declaration alone gives you migrated tables, a full CRUD REST API with
filtering/sorting/pagination, MCP tools an agent can call, OpenAPI, and a typed
Go model — see Entity declarations.
Two layers
Two packages, no more:
core/— eighteen dependency-light primitives (router, query, schema,
mcp, openapi, render, markdown, middleware, static, stream, upload, …), each
independently usable. All are stdlib-only exceptcore/middleware, which
pulls in OpenTelemetry for tracing. When the framework is in your way, you
drop down tocoreand write plain Go.framework/— the opinionated entity layer composed on top: entities,
CRUD, hooks, migrations, plugins, and the batteries below.
There is no third layer of hidden magic. Generated code is regular, owned Go
scaffolded straight into an idiomatic module-root layout (main.go,
entities/, blueprint/) — yours to read, edit, and commit — see
Code generation and Blueprints.
Modeling your domain
One typed declaration fans out into every surface.
- Entity declarations — JSON or Go; both
produce the same tables, routes, and tools. SetOwnerFieldfor per-user data. - Filter DSL —
?status=published&views_gte=10&sort=-created_at
parses to a typedWhere. - Eager loading —
?include=author.profileflattens the N+1. - Cursor pagination — keyset paging, opt-in.
- Hooks & transactions —
BeforeCreate/
AfterUpdatehooks share the parent transaction. - Batch endpoints — create/update/delete many in one
request. Migrations — versioned, ordered, reversible. - Multi-tenant scope — automatic
tenant_idfiltering.
Serving HTTP
Everything between the wire and your handler is on by default.
- Auth — login, OAuth, magic-link, 2FA, password reset; each a
plugin. Access control — roles, permissions, policies. - Security defaults — CSP, CSRF, rate limit, headers.
- Idempotency — an
Idempotency-Keyheader replays
mutations safely. Webhooks — signed outbound delivery with
retry. Notifications — multi-channel fan-out. - Health checks · Plugins — the
lifecycle every battery plugs into.
Building UI
Server-rendered with islands: every page is fully SSR on first load; the runtime
hydrates handlers onto the existing DOM; in-page state changes are island RPCs
that swap just one fragment — no hard refreshes, no client re-render.
- Getting started (UI) — scaffold → theme →
screen → custom component. - New components — the minimal-register +
SSR-inline + hydrate contract. Widget builder — islands
that hydrate against a registered handler. - Interactive patterns · Signal store —
client state that fans out to many consumers from one declaration. - Forms — server-validated, island-swapped error states.
- Image pipeline — pure-Go resize + WebP. Print documents —
chrome-free print/PDF. Runtime modules —
carved per-feature so a page ships only the JS it uses. - Browse every primitive live in the component gallery.
Persisting & migrating
SQLite and Postgres, dialect-aware.
- Audit log — a row per Create/Update/Delete.
- Isolation — per-worktree isolated local DBs.
- Factories — fixtures for tests. Full-text search.
- Uploads — file/image fields with pluggable storage.
- Env / .env — auto-loaded by
NewApp.
Working with agents
- Kiln — the agent-driven build-mode binary: mutate an
in-memory IR over HTTP, no Go/JS/SQL by hand. - Embed — local semantic search via brute-force cosine, no API
key. Audit deps — flag packages an agent shouldn't import. - Blueprints — reusable bundles of entities + screens an
agent can apply. Agent notes — append-only review log.
Operations
Reference & internals
- Benchmarks · Performance results —
how it performs and how that's measured. - Codegen — what the scaffold emits (owned Go at the module root) and how to read it.
- The full A–Z index lists every embedded doc — nothing is hidden.
Where to go next
- Get started — running app in four minutes.
- Entity declarations — the heart of the model.
- Examples — six reference apps, smallest first.
- Components — every UI primitive, one page each.
Every doc is grounded in the actual code, and every guide doc ends with a
"common mistakes" callout (data/index artifacts like the benchmark results
and the risk register are exempt — a test in framework/docs enforces the
split). This same content is browsable offline with gofastr docs.