Describe your data. Get the whole app.
Describe a resource. Get the Go model, the API, the migrations, the TypeScript types,
the React hooks and the admin screen. Auth, jobs, storage and deploy are already there.
Live demo · Install · 5-minute tutorial · Build with AI · Docs · Discussions · Community
curl -fsSL https://gritframework.dev/install.sh | sh # macOS, Linux, Git Bashirm https://gritframework.dev/install.ps1 | iex # Windows PowerShellNo Go toolchain needed. grit version to check, grit update to self-update.
Other ways to install
go install github.com/MUKE-coder/grit/v3/cmd/grit@latest # with a Go toolchain
GRIT_VERSION=v3.320.0 curl -fsSL https://gritframework.dev/install.sh | sh # pin a releaseYou need Go 1.21+, Node 20+, pnpm, and Docker for Postgres, Redis, MinIO and Mailhog. Full prerequisites
grit new myapp --triple --next # Web + Admin + API
cd myapp
docker compose up -d # Postgres, Redis, MinIO, Mailhog
pnpm install
grit startOpen http://localhost:3000, register, and you are logged into an application that already has authentication, two-factor, an admin panel, a database browser and API docs.
Or skip the install: demo.gritframework.dev is a real
application built with Grit, running, and its whole source is in demo/ in this
repository. Multi-branch inventory, a point of sale, unit sales, loan schedules and
mobile-money collections, with the admin panel, the audit log and the job dashboard you
get in every project.
Cloned a teammate's project?
grit envwrites your.envfrom.env.exampleand generates every secret, so you skip the half hour of hand-making keys.No Docker, or low on RAM? Grit runs against free cloud tiers (Neon, Upstash, Cloudflare R2, Resend) with no local containers. Installing without Docker.
grit generate resource Invoice --fields "number:string:auto:INV,total:money,status:select:draft|sent|paid,customer:belongs_to:Customer,due:date"flowchart LR
CMD["grit generate resource Invoice"] --> API
CMD --> SHARED
CMD --> UI
subgraph API["apps/api · Go"]
M["models/invoice.go<br/>GORM model + hooks"]
S["services/invoice.go<br/>business logic"]
H["handlers/invoice.go<br/>thin HTTP layer"]
R["routes<br/>injected, not hand-wired"]
end
subgraph SHARED["packages/shared"]
Z["schemas/invoice.ts<br/>Zod"]
T["types/invoice.ts<br/>TypeScript"]
end
subgraph UI["apps/admin + apps/web"]
Q["hooks/use-invoices.ts<br/>React Query"]
P["resources/invoices<br/>table · form · filters"]
end
Run grit migrate and the admin has a working invoices screen: stat cards, search, date
filters, sortable columns, bulk actions, CSV import and export. The customer picker is
searchable. The total is money, not a float. The invoice number fills itself in from a
gap-free counter (INV-202609-0001). The API validates against the same Zod schema as the
form.
There is no runtime magic. No reflection, no hidden proxies, no framework internals you cannot read. Grit writes a normal Go API and a normal Next.js app into your repository. You read the files, change them, ship them. Stop using the CLI tomorrow and the project still builds.
It is real code, and it holds up: grit seed Contact --count 1000000 fills a table with a
million realistic rows in about fifty seconds on Postgres, batched and resumable, and the
admin still pages through them instantly.
One API, every client: web · admin · mobile (Expo) · desktop (Wails)
Grit is to Go + React what Laravel + Filament is to PHP: Rails' convention over configuration, Django's batteries and a Filament-style resource admin, on a backend that compiles to one static binary.
| Assemble it yourself | With Grit | |
|---|---|---|
| Day one | Choose a router, ORM, auth library, validator, mailer, queue, S3 client and admin kit, then wire them together | grit new |
| A new entity | Model, migration, service, handler, routes, DTOs, TS types, fetch hooks, table, form: nine files by hand | One grit generate resource |
| Types across the stack | Kept in sync by discipline | Go → Zod + TypeScript, via grit sync |
| Admin panel | Rebuilt for every project | Tables, forms, filters, bulk actions and widgets from the resource definition |
| Test data | A seed script you write and wait on | grit seed Contact --count 1000000: batched, resumable, realistic |
| Payments, push, video | A week of integration each | grit plugin add stripe · push · video |
| Security | A checklist for "later" | CSRF, strict CSP, WAF, rate limiting, 2FA, passkeys, IDOR-safe ownership checks and a verifiable audit log, in the scaffold |
| Deploy | Dockerfiles, reverse proxy, TLS, systemd | grit deploy --host user@server --domain myapp.com |
A support desk with customers, tickets, a filterable table, a form with a customer picker, a REST API and fifty rows of realistic data.
1. Scaffold and start the infrastructure.
grit new helpdesk --triple --next
cd helpdesk
docker compose up -d
pnpm install2. Model the domain. One command per noun. The field types decide the database column, the validation, the TypeScript type and the admin input, all at once.
grit generate resource Customer --fields "name:string,email:email,company:string:optional"
grit generate resource Ticket --fields "subject:string,body:richtext,priority:select:low=Low|normal=Normal|high=High,status:select:open=Open|closed=Closed,customer:belongs_to:Customer" --seed --faker --count 50Each of those writes nine files and injects the wiring: a GORM model, a service, a handler, the routes, a Zod schema shared by every frontend, TypeScript types, React Query hooks, an admin page and its resource definition.
3. Migrate, seed and run.
grit migrate
grit seed
grit start4. Look at what you have. At http://localhost:3001 there is a Tickets screen with
sorting, filtering, search, pagination and bulk selection; a create form with a rich-text
editor, two dropdowns and a searchable customer picker; and full CRUD behind role guards.
At http://localhost:8080/docs is the API reference for the endpoints that back it, and at
/studio a browser for the rows themselves.
5. Add a column later, without regenerating. It goes into the model, both Zod schemas,
the TypeScript type, the admin form and the table, and GORM adds the column on the next
grit migrate:
grit generate field Ticket resolved_at:datetimeScalar, select and toggle columns work this way. For a relationship, file, slug or array field, regenerate the resource.
6. Ship it.
grit deploy --host you@server.com --domain helpdesk.comSSH, systemd and Caddy with automatic TLS. Deployment guides for Railway, Render, Fly.io, Coolify, Dokploy and plain VPS.
Longer walkthroughs: a CRM · a storefront · an invoice app · a mobile app · a desktop app
Grit is a code generator, and agents that do not know that hand-write the nine files and wonder why nothing is reachable. So there is a skill that teaches them:
npx skills add MUKE-coder/grit --skill gritThen paste the build prompt, which sets out the whole job in nine steps, links every concept the agent needs, and tells it to ask you what you are building before it scaffolds anything:
curl -s https://gritframework.dev/promptOr copy it from gritframework.dev/docs/ai-integration, which also has a wizard that narrows the brief to your stack and plugins. The skill itself is readable at gritframework.dev/skill.md, and there is an MCP server for tools that speak it.
grit plugin add writes a feature into your project as code you own. grit plugin update
brings in fixes later without overwriting a file you have edited, and grit plugin remove
reverses every file and every injection.
grit plugin add stripe # one-off payments and subscriptions, webhook-verified
grit plugin add push # push notifications to iOS and Android via Expo
grit plugin add video # uploads converted to web-ready MP4 with posters
grit plugin add webhooks # outgoing webhooks, signed to the Standard Webhooks spec
grit plugin add multitenant # organisations, per-org roles, automatic query scoping
grit plugin add impersonate # sign in as a user, with an audit trail
grit plugin add command-palette # ⌘K across the admin
grit plugin add saved-views # per-user named table views
grit plugin add device-pairing # sign in a browser by scanning a QR from a signed-in phone| Mode | Command | What you get |
|---|---|---|
| Triple | grit new app --triple |
Web + Admin + API, Turborepo monorepo |
| Double | grit new app --double |
Web + API, no separate admin |
| Single | grit new app --single |
One Go binary, SPA embedded with go:embed |
| API | grit new app --api |
Go API only |
| Mobile | grit new app --mobile |
API + Expo React Native |
| Desktop | grit new-desktop app |
Wails + Go + React + SQLite |
Frontend: --next (App Router, default) or --vite (TanStack Router, SPA).
Database: --db postgres|mysql|sqlite|memory.
grit new . scaffolds into the current directory.
The field definition is the source of truth for the column, the validation, the type and the admin input.
| Type | Go | Notes |
|---|---|---|
string text richtext |
string |
required by default; richtext gets a Tiptap editor |
int uint float |
int uint float64 |
float for weights and ratings, never money |
bool / toggle |
bool |
|
date datetime time |
*time.Time |
|
money |
minor units + currency | use this for money |
email url domain tel country color percent rating |
string / number |
checked and normalised on write; tel:UG sets a default country |
slug |
string |
auto-unique from another field |
select radio check |
string / JSON |
status:select:draft=Draft|paid=Paid |
file files |
FileRef |
S3-backed; file:image limits what is accepted |
json string_array |
JSON column | |
belongs_to one_to_one |
string |
a UUID foreign key plus an index |
many_to_many |
[]string |
junction table and a picker |
Modifiers: :unique :optional :encrypted :slug:<source> :belongs_to:<Model>
:many_to_many:<Model> :select:a=A|b=B :file:image
CLI reference
# Scaffolding
grit new <name> # interactive
grit new <name> --triple --next # explicit
grit new-desktop <name> # desktop app (Wails)
# Generating
grit generate resource <Name> --fields "..." # also: grit g
grit generate resource <Name> --seed --faker --count 500
grit generate field <Resource> <name:type> # one column, in place
grit generate seeder <Resource>
grit generate form <Resource> # multi-step form
grit generate table <Resource>
grit remove resource <Name> # reverses every injection
grit add role <ROLE>
grit add variants --resource <Resource>
grit sync # Go types -> TypeScript + Zod
# Running
grit start # everything
grit start server | grit start client
grit studio # GORM Studio
grit routes # what is actually mounted
grit doctor # audit for silent security mistakes
# Database
grit migrate # run migrations
grit migrate --fresh | status | down
grit seed
grit backup | grit restore
# Plugins
grit plugin list | add <name> | remove <name> | update
# Operations
grit down # maintenance mode
grit up
grit deploy --host user@server --domain example.com
# Meta
grit version | grit update # the CLI
grit upgrade # this project's templatesTech stack
| Layer | Technology |
|---|---|
| Backend | Go 1.21+ · Gin · GORM |
| Frontend | Next.js 14+ (App Router) or TanStack Router (Vite) |
| Styling | Tailwind CSS · shadcn/ui |
| Database | PostgreSQL · MySQL 8+ / MariaDB · SQLite |
| Cache / queue | Redis · asynq |
| Storage | S3-compatible (MinIO, Cloudflare R2, AWS S3) |
| Resend | |
| AI | Vercel AI Gateway |
| Auth | JWT · TOTP · passkeys · OAuth2 · SSO (OIDC, SAML) |
| Validation | Zod, shared between apps |
| Data fetching | TanStack Query |
| Monorepo | Turborepo · pnpm |
| Security | Sentinel (WAF, rate limiting) |
| Observability | Pulse (tracing, metrics) |
| DB browser | GORM Studio |
| Desktop / mobile | Wails v2 · Expo |
| Deploy | SSH + systemd + Caddy (auto-TLS) |
Plugins
Two different things, often confused.
grit plugin add generates code into your project: models, routes, admin pages and
components, recorded in .grit/plugins.lock.json so grit plugin remove reverses every
file and injection. You own the result. grit plugin update carries a fix into projects
that already installed it.
grit plugin list
grit plugin add multitenant # organizations, per-org roles, query scoping
grit plugin add impersonate # sign in as another user, with an audit trail
grit plugin add command-palette # ⌘K navigation
grit plugin add saved-views # per-user named table views
grit plugin add stripe # checkout, subscriptions, webhooks
grit plugin add push | video | webhooks | device-pairingThe grit-plugins Go packages are ordinary modules you import and wire yourself, and
are not installed by grit plugin add. They are early (v0.3.0): they build, vet and
carry contract tests, but several still store user_id as uint while a Grit User.ID is
a UUID string. Check core first, since grit-websockets duplicates the realtime module a
scaffolded app already ships.
Grit ships almost daily. Every release scaffolds fresh projects in every shape, builds
them, lints them and runs their tests, then re-verifies against the published binary.
Fixes reach existing projects through grit upgrade, which never overwrites a file you
have edited: it tells you what it could not change, and why. Every release is explained in
plain language in the changelog.
Better to say this now than waste your weekend.
- Your core is an unusual data model or request lifecycle. Grit is at its best on CRUD-shaped products with an admin surface.
- Your team is all TypeScript, and one language everywhere matters more to you than a Go backend. AdonisJS or Nest will suit you better.
- Data science or ML is the product. Python's ecosystem wins there, and it is not close.
- You would rather depend on a library than own generated code. Grit's output is yours to maintain. Upgrades patch what they safely can; code you have rewritten is your own.
The full reasoning, including what each decision costs, is in Why Grit.
gritframework.dev has the guides, the tutorials, the API reference and the free 10-part course.
Start at /docs/start, which is one ordered route from nothing to deployed. What is stable and what is not. Changelog (CHANGELOG.md).
- WhatsApp community: questions, help, and the person who builds Grit. No question is too small.
- Discussions: ideas, and anything that needs more than a chat message.
- Issues: defects. The template asks for the version, the steps and the output, which is what decides whether a bug is fixed this week or waits for a reply.
- Star the repo if Grit saved you a week. It is how other developers find it.
Grit is free and MIT licensed. Sponsorship pays for the features, docs and releases everyone else gets for free, and puts your name in front of every developer who builds with Grit.
Grit has no sponsors yet. Be the first. Your logo goes here, on the home page, and inside the CLI.
Building with Grit? Add the badge:
[](https://gritframework.dev)Bug reports, fixes and documentation corrections are welcome and merged quickly. Anything larger is worth an issue first, because a change here lands in every project built afterwards. CONTRIBUTING.md has the setup, the layout of the repository and what gets merged quickly.
Questions and ideas belong in Discussions rather than the issue tracker.
Taking part in this project means agreeing to abide by its Code of Conduct.
If you find a security problem, please do not open an issue. SECURITY.md says how to report it privately, what is in scope, and how releases are signed and verified.
MIT









