CLI Commands
The Grit CLI is a single binary that scaffolds projects, generates full-stack resources, and syncs types between Go and TypeScript. Install it once and use it across all your Grit projects.
Installing the CLI
Install the Grit CLI globally using Go:
This installs the grit binary to your $GOPATH/bin. Make sure that directory is in your system PATH.
grit new
Scaffold a new Grit project. This creates the full monorepo directory structure, initializes all configuration files, and sets up the Go API, Next.js frontends, shared package, and Docker infrastructure.
Syntax
grit new <project-name> [flags]
Flags
| Flag | Description |
|---|---|
| (no flag) | Default. Creates API + web app + admin panel + shared package + Docker |
| --api | Go API only. No Next.js frontends, no shared package. Ideal for pure backend projects |
| --expo | Include an Expo (React Native) mobile app alongside the web and admin apps |
| --mobile | API + Expo mobile app only. No web or admin frontends |
| --full | Everything including a documentation site app |
| --style <variant> | Admin panel style variant (default, modern, minimal, glass). Default: default |
Only one mode flag can be used at a time. Using multiple flags together (e.g.,--api --expo) will produce an error.
Project Name Validation
The project name must follow these rules:
- ✓Lowercase letters, numbers, and hyphens only
- ✓Must start with a letter
- ✓Cannot end with a hyphen
- ✓No consecutive hyphens
- ✓Minimum 2 characters, maximum 64 characters
What Gets Created
With the default flags (no --api), the following files and directories are scaffolded:
| Category | Files |
|---|---|
| Root | .env, .env.example, .gitignore, turbo.json, pnpm-workspace.yaml, README.md, docker-compose.yml, docker-compose.prod.yml |
| Go API | go.mod, main.go, config, database, models (User), handlers (auth, user), services (auth), middleware (auth, cors, logger), routes, Dockerfile |
| Web App | package.json, next.config, tailwind.config, layout, auth pages (login, register, forgot-password), dashboard, sidebar, hooks, api-client, Dockerfile |
| Admin Panel | package.json, layout, dashboard with stats, users management page, sidebar, navbar, data table, hooks, resource definitions |
| Shared | package.json, schemas (user.ts), types (user.ts, api.ts), constants (index.ts) |
Examples
grit generate resource
Generate a complete full-stack CRUD resource. This is the most powerful command in the Grit CLI. It creates 8 new files and modifies up to 10 existing files to wire everything together automatically.
Syntax
grit generate resource <Name> [flags] # Shorthand alias grit g resource <Name> [flags]
Flags
| Flag | Description |
|---|---|
| --fields | Inline field definitions as comma-separated name:type pairs |
| --from <file> | Load field definitions from a YAML file |
| -i, --interactive | Define fields interactively in the terminal, one at a time |
| --roles <ROLE1,ROLE2> | Restrict resource routes to specific roles |
You must provide exactly one of --fields,--from, or-i. Running the command without any of these flags prints a usage example.
Field Syntax
Fields are defined as name:type pairs. The name should be a simple identifier (e.g., title,due_date,is_active). The generator automatically converts names to the appropriate case for each language.
Field Type Reference
| Type | Go Type | TS Type | Zod Type | Form |
|---|---|---|---|---|
| string | string | string | z.string().min(1) | text input |
| text | string | string | z.string() | textarea |
| int | int | number | z.number().int() | number input |
| uint | uint | number | z.number().int().nonnegative() | number input |
| float | float64 | number | z.number() | number input |
| bool | bool | boolean | z.boolean() | toggle |
| datetime | *time.Time | string | null | z.string().nullable() | datetime picker |
| date | *time.Time | string | null | z.string().nullable() | date picker |
| slug | string | string | z.string() | auto-generated |
| belongs_to | uint (FK) | number | z.number().int().min(1) | relationship select |
| many_to_many | []uint (IDs) | number[] | z.array(z.number().int()) | multi-select |
| richtext | string | string | z.string() | Rich text editor (Tiptap) |
| string_array | datatypes.JSONSlice[string] | string[] | z.array(z.string()) | Multi-image upload |
The string type maps to a GORM column with size:255 and is required by default. The text type maps to a GORM type:text column and is optional by default. Both datetime anddate use Go pointer types (*time.Time) to allow null values. The slug type is auto-generated from a source field, has a unique index, and is excluded from forms.
Slug Fields
The slug field type auto-generates a URL-friendly slug from another field. Use the syntax name:slug to derive from the first string field, or name:slug:source_field to specify the source explicitly.
Relationship Fields
Use belongs_to to create a foreign key relationship, and many_to_many for junction table relationships. Both generate the Go model associations, handler Preloads, Zod schemas, TypeScript types, and admin form components automatically.
For belongs_to, the related model is inferred from the field name (category → Category). Use the three-part syntax name:belongs_to:Model when the field name differs from the model name. For many_to_many, the related model name is always required. See the Relationships page for full details.
Using --from (YAML Definition)
For resources with many fields or complex configurations, use a YAML definition file:
name: Post
fields:
- name: title
type: string
required: true
unique: true
- name: content
type: text
- name: excerpt
type: string
- name: published
type: bool
default: "false"
- name: views
type: int
- name: published_at
type: datetimeUsing -i (Interactive Mode)
Interactive mode prompts you for fields one at a time. Enter each field as name:type and press Enter. Press Enter on an empty line when done.
$ grit generate resource Invoice -i Defining fields for Invoice Enter fields as name:type (e.g., title:string) Valid types: string, text, int, uint, float, bool, datetime, date, slug, belongs_to, many_to_many Press Enter with no input when done. > number:string ✓ Added number (string) > amount:float ✓ Added amount (float) > status:string ✓ Added status (string) > due_date:date ✓ Added due_date (date) > paid:bool ✓ Added paid (bool) >
More Examples
grit remove resource
Remove a previously generated resource. This deletes the Go model, service, handler, Zod schemas, TypeScript types, React hooks, resource definition, and admin page. It also cleans up all injection markers that were added when the resource was generated.
Syntax
grit remove resource <Name> # Shorthand alias grit rm resource <Name>
The resource name should be the singular PascalCase name (e.g., Post, Product, BlogCategory) — the same name you used with grit generate resource.
grit add role
Add a new role to your project. This command updates all relevant files across the stack in one step — Go model constants, TypeScript types, Zod schemas, shared constants, and admin panel resource definitions (badge, filter, and form options).
This single command updates 7 locations across your project:
- Go model constants (RoleModerator = "MODERATOR")
- Zod schema enum validation
- TypeScript union type
- ROLES constants object
- Admin badge configuration
- Admin table filter options
- Admin form select options
The role name is automatically uppercased. Multi-word roles use underscores:grit add role CONTENT_MANAGER
grit start
Start development servers for your Grit project. Use subcommands to launch the frontend client apps or the Go API server individually.
grit start client
Runs pnpm dev from the project root, which starts all frontend apps (web, admin, expo, docs) via Turborepo.
grit start server
Runs go run cmd/server/main.go from the apps/api directory to start the Go API server.
Both commands auto-detect the project root by looking for docker-compose.yml or turbo.json, so you can run them from any subdirectory within your project.
grit sync
Parse all Go model files and regenerate the corresponding TypeScript types and Zod schemas in the shared package. Use this command whenever you manually modify a Go model and want the frontend types to stay in sync.
How It Works
- Finds the project root by walking up directories looking for docker-compose.yml or turbo.json
- Scans all .go files in apps/api/internal/models/
- Parses each file using Go's AST (Abstract Syntax Tree) parser to extract struct definitions
- For each struct, reads field names, Go types, JSON tags, and GORM tags
- Maps Go types to TypeScript types and Zod validators
- Writes TypeScript interface files to packages/shared/types/
- Writes Zod schema files to packages/shared/schemas/
- Skips the User model (which has custom hand-written schemas)
When to Use It
- ✓After manually adding or removing fields from a Go model
- ✓After changing a field's type in a Go struct
- ✓After modifying GORM tags (e.g., adding type:text)
- ✓After adding a completely new model file manually (without using grit generate)
Note: You do not need to run grit sync after using grit generate resource. The generator already creates the TypeScript types and Zod schemas for the new resource.
grit update
Update the Grit CLI itself to the latest version. This removes the current binary and installs the newest release from GitHub using go install.
Note: grit update updates the CLI tool itself. To update your project's scaffold files (admin panel, configs, web app), use grit upgrade instead.
grit version
Print the current version of the Grit CLI.
Quick Reference
| Command | Description |
|---|---|
| grit new <name> | Scaffold a new full-stack project |
| grit new <name> --api | Scaffold Go API only |
| grit new <name> --full | Scaffold everything including docs |
| grit generate resource <Name> | Generate full-stack CRUD resource |
| grit g resource <Name> | Shorthand for generate resource |
| grit remove resource <Name> | Remove a generated resource and clean up markers |
| grit add role <ROLE> | Add a new role across all project files |
| grit start client | Start frontend apps via pnpm dev |
| grit start server | Start Go API server |
| grit sync | Sync Go models to TypeScript + Zod |
| grit migrate | Run GORM AutoMigrate for all models |
| grit migrate --fresh | Drop all tables then re-migrate |
| grit seed | Populate database with initial data |
| grit upgrade | Update project scaffold files to latest |
| grit update | Remove old CLI and install latest version |
| grit version | Print CLI version |