Core Concepts

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:

terminal
$ go install github.com/MUKE-coder/grit/cmd/grit@latest

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.

terminal
$ grit new my-saas-app

Syntax

usage
grit new <project-name> [flags]

Flags

FlagDescription
(no flag)Default. Creates API + web app + admin panel + shared package + Docker
--apiGo API only. No Next.js frontends, no shared package. Ideal for pure backend projects
--expoInclude an Expo (React Native) mobile app alongside the web and admin apps
--mobileAPI + Expo mobile app only. No web or admin frontends
--fullEverything 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:

CategoryFiles
Root.env, .env.example, .gitignore, turbo.json, pnpm-workspace.yaml, README.md, docker-compose.yml, docker-compose.prod.yml
Go APIgo.mod, main.go, config, database, models (User), handlers (auth, user), services (auth), middleware (auth, cors, logger), routes, Dockerfile
Web Apppackage.json, next.config, tailwind.config, layout, auth pages (login, register, forgot-password), dashboard, sidebar, hooks, api-client, Dockerfile
Admin Panelpackage.json, layout, dashboard with stats, users management page, sidebar, navbar, data table, hooks, resource definitions
Sharedpackage.json, schemas (user.ts), types (user.ts, api.ts), constants (index.ts)

Examples

terminal
# Full-stack monorepo (default)
$ grit new my-crm
# Go API only (no frontend)
$ grit new billing-service --api
# Full stack with Expo mobile app
$ grit new my-app --expo
# Everything including docs site
$ grit new my-framework --full

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.

terminal
$ grit generate resource Post --fields "title:string,content:text,published:bool"

Syntax

usage
grit generate resource <Name> [flags]

# Shorthand alias
grit g resource <Name> [flags]

Flags

FlagDescription
--fieldsInline field definitions as comma-separated name:type pairs
--from <file>Load field definitions from a YAML file
-i, --interactiveDefine 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

TypeGo TypeTS TypeZod TypeForm
stringstringstringz.string().min(1)text input
textstringstringz.string()textarea
intintnumberz.number().int()number input
uintuintnumberz.number().int().nonnegative()number input
floatfloat64numberz.number()number input
boolboolbooleanz.boolean()toggle
datetime*time.Timestring | nullz.string().nullable()datetime picker
date*time.Timestring | nullz.string().nullable()date picker
slugstringstringz.string()auto-generated
belongs_touint (FK)numberz.number().int().min(1)relationship select
many_to_many[]uint (IDs)number[]z.array(z.number().int())multi-select
richtextstringstringz.string()Rich text editor (Tiptap)
string_arraydatatypes.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.

terminal
# Auto-detect source (uses first string field, e.g. "title")
$ grit g resource Post --fields "title:string,slug:slug,content:text"
# Explicit source field
$ grit g resource Post --fields "title:string,headline:string,slug:slug:title"

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.

terminal
# belongs_to — infer related model from field name
$ grit g resource Product --fields "name:string,category:belongs_to,price:float"
# belongs_to — explicit related model
$ grit g resource Post --fields "title:string,author:belongs_to:User,content:text"
# many_to_many — requires related model name
$ grit g resource Product --fields "name:string,tags:many_to_many:Tag,price:float"

For belongs_to, the related model is inferred from the field name (categoryCategory). 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:

post.yaml
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: datetime
terminal
$ grit generate resource Post --from post.yaml

Using -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.

terminal
$ 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

terminal
# Blog post with title, content, and published flag
$ grit g resource Post --fields "title:string,content:text,published:bool"
# Product with name, price, and stock
$ grit g resource Product --fields "name:string,description:text,price:float,stock:uint"
# Event with title, date, and description
$ grit g resource Event --fields "title:string,description:text,start_date:datetime,end_date:datetime"
# Category with just a name
$ grit g resource Category --fields "name:string,description:text"
# Article with an auto-generated slug
$ grit g resource Article --fields "title:string,slug:slug,body:text,published:bool"

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.

terminal
$ grit remove resource Post

Syntax

usage
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).

terminal
$ grit add role MODERATOR

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.

terminal
$ grit start client

grit start server

Runs go run cmd/server/main.go from the apps/api directory to start the Go API server.

terminal
$ grit start 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.

terminal
$ grit sync

How It Works

  1. Finds the project root by walking up directories looking for docker-compose.yml or turbo.json
  2. Scans all .go files in apps/api/internal/models/
  3. Parses each file using Go's AST (Abstract Syntax Tree) parser to extract struct definitions
  4. For each struct, reads field names, Go types, JSON tags, and GORM tags
  5. Maps Go types to TypeScript types and Zod validators
  6. Writes TypeScript interface files to packages/shared/types/
  7. Writes Zod schema files to packages/shared/schemas/
  8. 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.

terminal
$ grit update
→ Removing old binary: /home/user/go/bin/grit
→ Installing latest version...
✓ Grit CLI updated successfully!

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.

terminal
$ grit version
grit version 0.13.0

Quick Reference

CommandDescription
grit new <name>Scaffold a new full-stack project
grit new <name> --apiScaffold Go API only
grit new <name> --fullScaffold 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 clientStart frontend apps via pnpm dev
grit start serverStart Go API server
grit syncSync Go models to TypeScript + Zod
grit migrateRun GORM AutoMigrate for all models
grit migrate --freshDrop all tables then re-migrate
grit seedPopulate database with initial data
grit upgradeUpdate project scaffold files to latest
grit updateRemove old CLI and install latest version
grit versionPrint CLI version