Four ways to add something
Grit has four mechanisms for adding to a project, and they are not alternatives to each other. Each one has a unit: a noun, a feature, a component, an application. Picking the right one is mostly a matter of naming the unit.
The short answer
| Mechanism | The unit | Reach for it when |
|---|---|---|
| Resource | A noun in your domain | The thing you are adding is a kind of record: an invoice, a patient, a shipment. |
| Plugin | A feature, across every layer it touches | The thing you are adding is a capability rather than a record, and more than one project would want it. |
| Grit UI block | A component | You need something to look right, and the data behind it already exists. |
| Blueprint | A whole application | You are starting something, and something close to it already exists. |
What they have in common
All four write ordinary code into your repository. None of them installs a runtime library that reaches into your app and registers itself. After any of them runs, what you have is files you can read, edit, step through in a debugger and delete.
That is the property that makes the choice between them low-stakes. Picking the wrong one costs you a refactor, not a migration off a dependency.
Resource: a noun in your domain
grit generate resource Invoice --fields "number:string,total:money,due:date,client:belongs_to:Client"
This is the one you use most, and the one the framework is built around. One definition produces the Go model and migration, the service and handler, the routes, the shared Zod schema, the TypeScript types, the React Query hooks and the admin screen. They agree with each other because they came from the same description.
The test is whether the thing is a kind of record. If you would put it in a table and list it, it is a resource.
Plugin: a feature, packaged
grit plugin add kanban
Some things are not nouns. Multi-tenancy is not a record. Neither is a command palette, or signing in as another user, or a board you drag cards around on. They cut across models, routes, pages and dependencies at once, and the pieces only make sense together.
A plugin is that bundle. It writes files, patches existing ones at named markers, declares the dependencies it needs, and records every one of those actions in a lockfile. Removal replays the lockfile backwards, which is why grit plugin remove leaves a project that still compiles rather than a project with half a feature in it.
The kanban plugin is the worked example: it is the smallest feature that needs every part of the system at once, so the authoring guide is written around it.
Grit UI: a component, nothing behind it
grit ui listgrit ui add pricing-table
Grit UI is a component library in the shadcn format: the command downloads the source and writes it into your frontend, into the right app for your architecture. It is a file from that point on.
The thing to be clear about is what it does not do. A block is presentation. It has no model, no endpoint and no migration. If you add a board component this way you will have a board that displays nothing and saves nothing, which is a worse place to be than having no board, because it looks finished.
So: a UI block when the data already exists and you need it to look right. A plugin when the data does not exist yet.
Blueprint: a whole application
grit blueprint listgrit blueprint info whatsapp
A blueprint is not installed. It is a complete application in its own repository, built with Grit, that you clone and work from. A plugin adds a feature to your project; a blueprint is a project.
They exist for two reasons. One is a starting point: if you are building a storefront, starting from a storefront beats starting from an empty project. The other is that each blueprint is a load test for the framework. Every gap one finds gets fixed in Grit first, released, and then the blueprint upgrades into it, so its code stays Grit's own rather than drifting into a fork.
How to tell which one you need
Two questions settle almost every case.
Is it a kind of record? If yes, it is a resource. Stop here.
Would a second project want it? If yes, it is a plugin. If no, it is just code you write in your project, and that is fine. Not everything needs a mechanism.
A UI block is the answer to a narrower question: the feature exists and the screen looks wrong.
Worked examples
| You want | Use | Because |
|---|---|---|
| Invoices | Resource | An invoice is a record. |
| A Kanban board | Plugin | Three models plus a reordering endpoint plus a drag-and-drop screen, useless apart. |
| A chat feature | Plugin, and read the WhatsApp blueprint | Same shape as a board, with realtime delivery and read state on top. |
| A nicer pricing page | Grit UI block | The plans already exist; this is presentation. |
| Per-organisation data isolation | Plugin | It changes how every query is scoped, which is not a record. |
| A shop to start from | Blueprint | You are starting a project, not adding to one. |
When none of them fits
Sometimes the answer is that the thing belongs in the framework rather than on top of it. The test Grit applies to itself: is this machinery a team would otherwise rebuild for every client target, and can one definition drive it everywhere? Ordered lists that survive two people reordering at once is machinery. A Kanban board is not; it is one screen that happens to need that machinery.
If you hit something in that first category, that is worth saying so. Most of what is in Grit got there because building something real ran into its absence.
