Core Concepts · Reference
Generated File Map
Exactly what grit generate resource writes, for every app in your project — the definitive index of paths, what each file is, and which are yours to edit versus regenerated. Filenames use the resource name (singular for Go, kebab-plural for routes/hooks).
One command, the whole stack
From a single field spec, Grit fans out a working, end-to-end feature. Here are the four files at the heart of it — switch tabs to see the same resource across Go and TypeScript:
One commandGo backendShared (Zod/TS)Frontend + admin
One command writes a working feature across every layer that exists in your projecttype Product struct {ID string `gorm:"primaryKey;size:36" json:"id"`Name string `gorm:"size:255;not null" json:"name" binding:"required"`Price float64 `gorm:"not null" json:"price"`CategoryID string `gorm:"size:36;not null;index" json:"category_id"`Category Category `gorm:"foreignKey:CategoryID" json:"category,omitempty"`CreatedAt time.Time `json:"created_at"`UpdatedAt time.Time `json:"updated_at"`DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`}func (p *Product) BeforeCreate(tx *gorm.DB) error {if p.ID == "" {p.ID = uuid.New().String()}return nil}
Excerpts, abbreviated for clarity — the real files are complete and runnable.
Backend + shared (always)
These are written for every architecture that has an API and a shared package.
| Path | What it is |
|---|---|
| apps/api/internal/models/<name>.go | GORM model (UUID PK, BeforeCreate, relations) |
| apps/api/internal/services/<name>.go | Service layer — your custom business logic goes here |
| apps/api/internal/handlers/<name>.go | Gin CRUD handler (list/get/create/update/delete) |
| apps/api/internal/handlers/<name>_import.go | CSV/Excel bulk-import handler |
| packages/shared/schemas/<name>.ts | Zod Create/Update schemas |
| packages/shared/types/<name>.ts | TypeScript types (regenerated by grit sync) |
Web app (if present)
| Path | What it is |
|---|---|
| apps/web/hooks/use-<plural>.ts | React Query hooks (Next.js) — src/hooks/ for the Vite kit |
Admin panel (if present)
| Path | What it is |
|---|---|
| apps/admin/resources/<name>.ts | Resource definition (table + form + widgets) — src/resources/ on Vite |
| apps/admin/app/(dashboard)/resources/<plural>/page.tsx | Admin CRUD page — src/routes/_dashboard/resources/ on Vite |
Mobile — Expo (if present)
| Path | What it is |
|---|---|
| apps/expo/hooks/use-<plural>.ts | Typed React Query hook |
| apps/expo/app/<plural>/index.tsx | List screen |
| apps/expo/app/<plural>/[id].tsx | Detail screen |
| apps/expo/app/<plural>/new.tsx | Create screen |
| apps/expo/app/<plural>/edit/[id].tsx | Edit screen |
| apps/expo/components/resource-forms/<plural>-form.tsx | Shared form component |
Desktop — Wails (if present)
| Path | What it is |
|---|---|
| apps/desktop/frontend/src/hooks/use-<plural>.ts | React Query hook (calls Wails bindings) |
| apps/desktop/frontend/src/routes/_app/<plural>.index.tsx | List route |
| apps/desktop/frontend/src/routes/_app/<plural>.new.tsx | Create route (+ detail / edit routes) |
Files it edits (marker injection)
Rather than overwrite shared files, Grit injects at // grit:* markers. Keep the markers in place — they're how generation and seeding stay idempotent.
| Path | What it is |
|---|---|
| apps/api/internal/models/user.go | Model registered in Models() at // grit:models |
| apps/api/internal/routes/routes.go | Routes registered at // grit:routes:* |
| packages/shared/schemas/index.ts | Schema re-exported at // grit:schemas |
| apps/admin/resources/index.ts | Resource registered at // grit:resources |
Yours vs regeneratedEverything above is your code once generated — edit models, add service methods, restyle screens freely. The one exception is
packages/shared/types/*, which grit sync regenerates from your Go structs; put custom logic in the service layer (which regeneration never touches), not in the types.Escape hatchNeed to pull a resource back out?
grit generate remove resource <Name> deletes exactly these files and unwinds the marker injections — a clean inverse of generation.