Extending

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

MechanismThe unitReach for it when
ResourceA noun in your domainThe thing you are adding is a kind of record: an invoice, a patient, a shipment.
PluginA feature, across every layer it touchesThe thing you are adding is a capability rather than a record, and more than one project would want it.
Grit UI blockA componentYou need something to look right, and the data behind it already exists.
BlueprintA whole applicationYou 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 list
grit 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 list
grit 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 wantUseBecause
InvoicesResourceAn invoice is a record.
A Kanban boardPluginThree models plus a reordering endpoint plus a drag-and-drop screen, useless apart.
A chat featurePlugin, and read the WhatsApp blueprintSame shape as a board, with realtime delivery and read state on top.
A nicer pricing pageGrit UI blockThe plans already exist; this is presentation.
Per-organisation data isolationPluginIt changes how every query is scoped, which is not a record.
A shop to start fromBlueprintYou 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.