Grit is the framework for building one business product across web, admin, mobile and desktop, with the API, background jobs, realtime, security and deployment underneath, without rebuilding the machinery for every client. You define a resource once, in Go, and it reaches every surface.
Why Grit exists
Every business product we built meant building the same things again: auth and sessions, roles, an admin panel, file uploads, background jobs, email, audit logs, realtime. Then a mobile app, and sometimes a desktop app, talking to the same API.
Each client needed the same model defined again: in Go, in TypeScript, in the validation, in the forms, in the tables. The copies drifted apart. A field added on the backend went missing on mobile; a rule enforced in the form was not enforced by the API. Most of the time went into plumbing, not the product.
Grit exists so that work is done once, correctly, and reaches every client from a single definition.
The machinery tax
Before you write the feature that matters, you re-solve the problems you solved on the last project, and the one before that. None of it is hard. All of it is slow, and with every extra client you pay for it again.
That is months of work that produces zero product differentiation. Grit treats all of it as solved: generated, wired, and hardened the moment you scaffold.
What sets it apart
One command writes the resource everywhere it needs to exist, and every piece agrees with every other, because they all come from the same fields. Add a field later with grit generate field and it reaches the model, the validation, the types and the admin form and table in one step.
$grit generate resource Invoice \$ --fields "number:string:unique,customer:belongs_to:Customer,total:money,due:date,status:select:draft=Draft|paid=Paid"
Model, service and handler with pagination, search, filters, soft delete and optimistic locking, routes registered.
The model registered for migration, indexes from the field definitions, and a seeder that writes realistic data in batches.
Zod schemas and TypeScript types generated from the same fields, so the frontend and the API validate the same rules.
React Query hooks for list, detail, create, update and delete, typed end to end.
A table with sorting, filters and bulk actions, a form with the right input for each field, Excel export and bulk import.
Expo screens for the list, the detail and the form, talking to the same API with the same types.
Screens in the Wails desktop app, with the same relations, the same validation and the same API client.
The endpoints added to the interactive API docs, so the contract is published the moment it exists.
Where the database fits
Underneath, Grit uses GORM, like much of the Go world, and Postgres, MySQL or SQLite. We did not reinvent the data layer, and the database is not the headline. What Grit adds is everything that usually sits around it by hand:
Field types that mean something from the column to the form. money is stored as exact minor units, tel is checked as a real phone number, email, date, country, select and encrypted fields are validated the same way in Go, in Zod and in the input the form renders.
Constraints that answer properly. A duplicate in a unique field comes back as 409 naming the field, a stale edit as a version conflict, a broken rule as 422 with its message. Not a 500 the form cannot explain.
Seeding built for real volumes. Most frameworks assume a seeder writes a few rows. Real work means seeding a million to find where your infrastructure breaks, or loading years of records buried in Excel files. Grit generates batched seeders with realistic data, and bulk import in the admin.
The data layer is one example of the pattern, not the point of it. The point is that none of this is yours to rebuild, on any client.
How it compares
Gin, Echo, Fiber, Chi
A router and your choice of ORM.
Auth, admin, uploads, jobs, email, the frontend and every client are yours to build and keep in step.
batteries-included web frameworks
The batteries, conventions and generators.
For the web app. The mobile and desktop apps are separate projects with their own copy of the model.
Go + React, one monorepo
The batteries, across web, admin, mobile, desktop, jobs, realtime and deployment.
From one definition, in Go. You build the product; the machinery is already there, on every client.
Compress the work
$grit new my-app --triple --desktop$grit generate resource Product \$ --fields "name:string,price:money,stock:int"
What Grit stands for
Every one of these costs something. A preference that costs nothing is not a principle, it is a feature list, so each one below names what you give up.
Grit writes real files into your repo: the model, service, handler, routes, hooks and screens. Not a runtime dependency that does it invisibly at boot.
You give up a small repo. You get code you can read, edit, delete, and debug with a stack trace that points at your own file. There is no fighting the framework, because there is no framework in the way: just Go and TypeScript you own.
Gin, GORM, Next.js, Postgres, Redis. Every one has years of production behind it and its answers already written down somewhere.
You give up novelty. We are not going to invent a router or an ORM. The interesting part of your project should be your product, not the stack underneath it.
One way to do auth. One queue. One storage layer. Escape hatches where you need them, not a menu where you do not.
You give up the pleasure of choosing. You get a codebase where every Grit project looks the same, onboarding takes an afternoon, and an AI agent never has to guess which of six patterns you picked.
A resource is not a Go model or a TypeScript type. It is both, plus the handler, the Zod schema, the hooks, the admin page and the mobile and desktop screens, generated together from one definition.
You give up picking a different stack per client. You get surfaces that cannot drift apart, because one command writes all of them from the same fields.
CSRF, strict CSP, rate limiting, SSRF defence, IDOR-safe ownership checks, field-level encryption, server-side sessions and a tamper-evident audit log, in the scaffold.
You give up the option to skip it. That is the point: security is the work that never wins a prioritisation meeting against a feature, so it ships before the meeting happens.
Every release scaffolds fresh projects in several shapes, including mobile and desktop, then installs, builds, type-checks, lints and tests them, and upgrades a project from the previous release.
You give up a faster release cadence. Claims in a changelog are cheap; we would rather find the bug than describe the feature.
What the trades buy you
Because there is one way to do each thing, an AI assistant has nothing to guess. Grit ships a SKILL.md, and grit mcp serve hands an agent the real route table and model definitions over MCP, parsed from your source, read-only.
The hardening in every scaffold is work no one budgets for: SSRF defence, IDOR-safe ownership checks, GDPR export and erasure, SSO with SAML, field-level encryption. Already there, already tested.
Embed a SPA in the Go binary, split web, admin and API into a monorepo, go API-only, or add mobile and desktop. The generators and conventions do not change; only the shape does.
Your next project
Grit pays off when you are building a real business product, and most of all when it has more than one client.
Honest limits
A framework that fits everything fits nothing. Better to find out on this page than three weeks into a rewrite.
Grit is Go on the backend, and that is not configurable. If you are TypeScript end to end, AdonisJS or Nest will make you happier, and we would rather you were happy than converted.
You can swap them: it is your code. But you would be working against the generators, and that cost compounds with every resource you add.
The batteries become weight you never use. `--api` trims a lot of it, but a plain Gin and GORM binary may genuinely be the simpler answer.
Grit is young. Fewer Stack Overflow answers, fewer third-party plugins, fewer people who have hit your exact bug. What you get instead is a maintainer who ships weekly and answers questions directly.
Everything Grit generates is ordinary code in your repo, which means the framework can never become the thing standing between you and a fix.
It is MIT licensed, developed in the open, and supported by sponsors rather than a sales team. Releases are public, versioned, and shipped weekly. For the longer story, why Go, why React, and what Grit borrows from Laravel and Rails, read the philosophy doc.
Join the WhatsApp community for questions, tutorials, and guidance from people shipping Grit apps, and from the person who builds it. No question is too small.
Install the CLI and scaffold a production-ready Go + React product, web, admin, mobile and desktop, in minutes.
$curl -fsSL https://gritframework.dev/install.sh | sh
Grit v3.362.2 · MIT licensed · Go + React