This document breaks the Grit framework development into 5 phases. Each phase builds on the previous one. AI agents (Claude Code) should complete one phase fully before moving to the next.
Goal: A working monorepo that scaffolds via CLI, with a Go API (auth included), Next.js frontend with login/register, shared schemas, Docker setup, and GORM Studio.
Success Criteria: Run grit new myapp, then cd myapp && docker compose up, open the browser, register a user, log in, see a dashboard, and browse the database via GORM Studio.
- Create the
gritCLI tool in Go usingcobralibrary -
grit new <project-name>command that:- Creates the full monorepo folder structure (see GRIT.md for structure)
- Initializes
go.modfor the API - Initializes
package.jsonfiles for web, admin, and shared packages - Creates
pnpm-workspace.yaml - Creates
turbo.json - Creates
.envand.env.examplewith sensible defaults - Creates
docker-compose.yml(PostgreSQL, Redis, MinIO, Mailhog) - Creates
.gitignorefiles - Runs
go mod tidyandpnpm install - Prints success message with next steps
-
grit new <project-name> --apiflag (scaffolds only the Go API, no frontend) - Colored CLI output with ASCII art logo
- Validate project name (lowercase, alphanumeric, hyphens only)
- Entry point:
apps/api/cmd/server/main.go - Configuration loading from
.envusinggodotenv - Database connection setup with GORM + PostgreSQL driver
- Auto-migration on startup
- Gin router setup with middleware:
- CORS middleware (configured for frontend origins)
- JSON logging middleware
- Recovery middleware
- Route registration in
internal/routes/routes.go - Health check endpoint:
GET /api/health - Graceful shutdown handling
- User model (
internal/models/user.go):- ID, Name, Email, Password (hashed), Role, Avatar, Active, CreatedAt, UpdatedAt, DeletedAt
- Password hashing with bcrypt on BeforeCreate hook
CheckPassword()method
- Role constants: admin, editor, user (as string constants on User model)
- Auth handlers (
internal/handlers/auth.go):POST /api/auth/register— Register with name, email, passwordPOST /api/auth/login— Login with email + password, returns JWT tokensPOST /api/auth/refresh— Refresh access token using refresh tokenPOST /api/auth/logout— Invalidate refresh tokenGET /api/auth/me— Get current user profilePOST /api/auth/forgot-password— Send password reset emailPOST /api/auth/reset-password— Reset password with token
- Auth middleware (
internal/middleware/auth.go):- JWT validation middleware
- Role-based access middleware (
RequireRole("admin")) - Extracts user from token and attaches to Gin context
- JWT service (
internal/services/auth.go):- Generate access token (15 min expiry)
- Generate refresh token (7 day expiry)
- Validate and parse tokens
- Token secret from environment variable
- User handlers (
internal/handlers/user.go):GET /api/users— List users (admin only, paginated)GET /api/users/:id— Get user by IDPUT /api/users/:id— Update userDELETE /api/users/:id— Soft delete user
- Embed GORM Studio in the API
- Mount at
/studioroute - Pass all registered models to GORM Studio
- Enable by default in development, configurable in
.env
- Next.js 14+ with App Router
- Tailwind CSS + shadcn/ui setup
- Dark theme as default (matching GORM Studio aesthetic)
- API client (
lib/api-client.ts):- Axios instance pointed at Go API
- Automatic JWT token injection from cookies/localStorage
- Token refresh interceptor
- Error handling wrapper
- React Query setup (
lib/query-client.ts) - Auth hooks (
hooks/use-auth.ts):useLogin(),useRegister(),useLogout(),useMe()- Store tokens securely
- Redirect on 401
- Auth pages:
/login— Email + password form, dark themed/register— Name + email + password form/forgot-password— Email input
- Protected layout (
(dashboard)/layout.tsx):- Auth guard — redirect to login if not authenticated
- Sidebar navigation
- Top navbar with user avatar + logout
- Dashboard page (
(dashboard)/dashboard/page.tsx):- Welcome message with user name
- Placeholder stats cards
- Placeholder recent activity
- Responsive design (mobile-friendly)
-
packages/shared/schemas/user.ts— Zod schema for user registration/login -
packages/shared/types/user.ts— TypeScript User type -
packages/shared/types/api.ts— API response types (pagination, error format) -
packages/shared/constants/index.ts— Roles, API routes, config
-
docker-compose.ymlfor development:- PostgreSQL 16 with persistent volume
- Redis 7
- MinIO (S3-compatible, for local file storage testing)
- Mailhog (local email testing)
-
docker-compose.prod.ymlfor production:- Multi-stage Go build (small final image)
- Next.js standalone build
- PostgreSQL + Redis
-
Dockerfilefor Go API (multi-stage build) -
Dockerfilefor Next.js web app -
.dockerignorefiles
- Sensible
.env.examplewith all required variables documented - README.md with quick start instructions
- Working
gritCLI that scaffolds the full project - Go API with JWT auth and role-based access
- Next.js app with login, register, and protected dashboard
- GORM Studio at
/studio - Docker Compose for dev and prod
- Shared Zod schemas and TypeScript types
- Hot reload development setup
Goal: grit generate resource <Name> creates a full-stack resource — Go model, handler, React Query hook, Zod schema, and admin panel page — all wired together.
Success Criteria: Run grit generate resource Post, then immediately browse Posts in the admin panel with full CRUD, pagination, sorting, and filtering.
- Template engine for Go and TypeScript file generation (strings.NewReplacer with named placeholders)
-
grit generate resource <Name>command:- Prompts for fields (name, type, required, unique) interactively (
-i) - Or accepts a definition file:
grit generate resource --from post.yaml - Or inline fields:
--fields "title:string,content:text,published:bool"
- Prompts for fields (name, type, required, unique) interactively (
- Template functions for each generated artifact
- Smart pluralization (Post → posts, Category → categories)
- Marker-based code injection into existing files
- Automatic route registration (inject into routes.go)
- Model (
internal/models/<name>.go):- GORM struct with proper tags
- Timestamps and soft deletes
- Handler (
internal/handlers/<name>.go):GET /api/<names>— List with pagination, sorting, filtering, searchGET /api/<names>/:id— Get by IDPOST /api/<names>— Create with validationPUT /api/<names>/:id— Update with validationDELETE /api/<names>/:id— Soft delete
- Service (
internal/services/<name>.go):- Business logic layer between handler and model
- Reusable query scopes (pagination, filtering, sorting)
- Automatic migration registration (AutoMigrate + GORM Studio injection)
- Zod schema (
packages/shared/schemas/<name>.ts):- Create schema, update schema
- Proper Zod types matching Go types
- TypeScript types (
packages/shared/types/<name>.ts):- Full type with all fields
- Create/Update input types inferred from Zod
- React Query hooks (
apps/admin/hooks/use-<names>.ts+apps/web/hooks/):use<Names>()— Paginated list query with sorting/filteringuseGet<Name>(id)— Single item queryuseCreate<Name>()— Create mutationuseUpdate<Name>()— Update mutationuseDelete<Name>()— Delete mutation- Automatic cache invalidation on mutations
- Admin page (
apps/admin/app/resources/<names>/page.tsx):- DataTable with search, pagination, delete actions
- Auto-injected into admin sidebar navigation
-
grit synccommand:- Reads all Go models in
internal/models/using Go AST parser - Generates corresponding TypeScript types and Zod schemas
- Maps Go types → TypeScript types (uint → number, time.Time → string, etc.)
- Skips User model (has custom schemas)
- Reads all Go models in
- Working
grit generate resourcecommand - Full-stack resource generation (Go + TypeScript)
grit syncfor Go → TypeScript type generation- Generated code is clean, readable, and editable
Goal: A Filament-like admin panel where developers define resources in TypeScript and get beautiful, functional admin pages with data tables, forms, dashboards, and widgets.
Success Criteria: Define a resource with 10+ columns, 8+ form fields, 3+ filters, and 2+ widgets. The resulting admin page should look like a premium CRM — not a generic CRUD tool.
- Collapsible sidebar with:
- Logo/brand area
- Navigation items auto-generated from registered resources
- Icon support (Lucide icons)
- Active state highlighting
- User profile section at bottom
- Dark/light theme toggle
- Top navbar:
- Breadcrumbs
- Search (global search across resources)
- User menu (profile, settings, logout)
- Responsive layout (sidebar collapses on mobile)
-
defineResource()API (see GRIT.md for example) - Resource registry (
resources/index.ts) - Auto-generated routes from resources
- Resource configuration:
- Name, endpoint, icon
- Table columns, filters, actions
- Form fields, validation
- Dashboard widgets
- Permissions (which roles can access)
- Server-side pagination (communicates with Go API)
- Column sorting (click header to sort)
- Column filtering:
- Text search (global and per-column)
- Select/dropdown filters
- Boolean toggle filters
- Column features:
- Show/hide columns toggle
- Custom cell renderers (badge, currency, date, relative time, image, boolean)
- Row actions (edit, delete, view, custom)
- Empty state with illustration
- Loading skeleton
- Export to CSV / JSON
- Responsive (horizontal scroll on mobile)
- Form modal and full-page form views
- Field types:
- Text input
- Textarea
- Number (with min/max, step)
- Select
- Date picker
- Toggle / Switch
- Checkbox
- Radio group
- Validation:
- Zod-based validation from shared schemas
- Real-time validation (on blur and on change)
- Server-side error display
- Form layout:
- Single column, two column
- Section groups with headers
- Create and edit modes from the same form definition
- Auto-populated defaults
- Dashboard page as the admin home
- Widget types:
- Stats card — Number + label + change percentage + icon
- Line chart — Time series data
- Bar chart — Categorical data
- Recent activity — List of recent events
- Widget grid layout (responsive, configurable)
- Widgets fetch data from the Go API
- Charting library: Recharts
- Dark theme (default) matching GORM Studio:
- Background:
#0a0a0f,#111118,#1a1a24 - Accent:
#6c5ce7 - Fonts: Onest + JetBrains Mono
- Background:
- Light theme option
- Theme toggle in sidebar
- CRM-inspired aesthetic:
- Generous spacing
- Professional data density
- Beautiful empty states
- Polished loading states
- Complete admin panel layout shell
- Resource definition system
- DataTable with server-side pagination, sorting, filtering
- Form builder with all field types
- Dashboard with widgets (stats, charts, activity)
- Dark/light theme
- Beautiful, CRM-quality aesthetic
Goal: Add file storage, email, background jobs, cron, Redis caching, and AI integration. All pre-configured and wired to the admin panel.
- Storage abstraction layer (
internal/storage/storage.go):- Interface:
Upload(),Download(),Delete(),GetURL(),GetSignedURL() - S3 driver (AWS S3, Cloudflare R2, Backblaze B2)
- Local driver (MinIO in dev)
- Configuration via
.env(STORAGE_DRIVER, S3_BUCKET, S3_REGION, etc.)
- Interface:
- Upload handler:
POST /api/uploads- File size limits, allowed MIME types (configurable)
- Returns file URL and metadata
- Image processing on upload:
- Thumbnail generation (via background job)
- Resize to max dimensions
- File upload in admin panel:
- Drag and drop
- Image previews
- Multiple file support
- File management in admin panel:
- Browse uploaded files (grid view)
- Delete files
- View file details
- Mail service (
internal/mail/mailer.go):- Resend client integration (raw net/http, no SDK)
- Send method:
Send(ctx, SendOptions) - HTML templates using Go
html/template
- Built-in email templates:
- Welcome email
- Password reset
- Email verification
- Notification
- Template preview in admin panel
- Email configuration via
.env
- Job queue system (
internal/jobs/):- Redis-backed queue using
asynqlibrary - Enqueue:
client.EnqueueSendEmail(),client.EnqueueProcessImage() - Job priorities (critical, default, low)
- Retry with configurable max attempts
- Redis-backed queue using
- Built-in jobs:
- Send email job
- Process image job (thumbnail generation)
- Cleanup expired tokens job
- Job dashboard in admin panel:
- Queue stats (pending, active, completed, failed)
- View jobs by status with error details
- Retry failed jobs
- Clear queues
- Cron service (
internal/cron/cron.go):- asynq Scheduler for cron-like scheduling
- Built-in tasks: cleanup expired tokens (hourly)
// grit:cron-tasksmarker for injection
- Cron status in admin panel (list registered tasks)
- Cache service (
internal/cache/cache.go):Get(key),Set(key, value, ttl),Delete(key),DeletePattern(),Flush()- JSON serialization for complex values
- Cache middleware for API GET responses (
CacheResponse())
- AI service (
internal/ai/ai.go):- Anthropic Claude API client (raw net/http)
- OpenAI API client (raw net/http)
- Simple interface:
ai.Complete(ctx, req),ai.Stream(ctx, req, handler)
- Streaming support (SSE via Gin)
- API endpoints:
/api/ai/complete,/api/ai/chat,/api/ai/stream - Configuration via
.env(AI_PROVIDER, AI_API_KEY, AI_MODEL)
- File storage with S3/R2/MinIO
- Email system with Resend + templates
- Background job queue with Redis
- Cron scheduler
- Redis caching
- AI integration (Anthropic + OpenAI)
- All features visible/manageable in admin panel
Goal: Documentation site, testing, performance optimization, and public launch.
- Documentation website (Nextra or Mintlify or custom)
- Pages:
- Getting Started (5-minute quick start)
- Installation
- Project Structure
- Configuration
- Authentication & Authorization
- Admin Panel (resource definitions, tables, forms, widgets)
- Code Generator (CLI commands, templates)
- File Storage
- Background Jobs
- Cron
- Caching
- AI Integration
- GORM Studio
- Deployment (Docker, VPS, cloud)
- API Reference
- Contributing Guide
- FAQ
- Interactive examples
- Copy-paste code blocks
- Search functionality
- Dark theme docs site
- Go CLI/generator tests:
- Unit tests for
internal/generatepackage (pluralize, field types, definition parsing) - 31 test cases covering GoType, TSType, ZodType, GORMTag, field helpers, FKColumnName, RelatedModelName, UIHelpers, ParseInlineFields, LoadFromYAML, ValidFieldTypes
- Unit tests for
- Go CLI/scaffold tests:
- 13 tests for
internal/scaffoldpackage — ValidateProjectName, ValidateStyle, ShouldInclude* helpers, createDirectories (api-only/default/full modes), writeAPIFiles (module substitution, key files exist), writeFile helper - Fixed pre-existing build errors:
%3CURL-encoding infmt.Sprintftemplate, trailing\nincolor.Printlncalls
- 13 tests for
- Go CLI/generator inject + sync tests:
inject_test.go: injectBefore (inserts before marker, marker-not-found, idempotent, missing file), injectInline (inserts inline, errors), guessLucideIcon (12 name→icon cases)sync_test.go: goTypeToTS (15 type mappings), goTypeToZod (10 type+tag combos), extractTag (7 cases incl. omitempty), isAutoField, buildTSType, buildZodSchema (auto fields excluded, .optional() in update schema), parseGoStructs (simple struct, multiple structs, invalid Go file, missing file), round-trip test- 68 total test cases (including subtests) — all passing
- Go CLI/generator integration tests:
generator_test.go: Names() (simple, compound, irregular plurals), writeGoModel (basic fields, slug + helpers.go, belongs_to), writeGoService (module substitution, search where), writeGoHandler (CRUD methods, no placeholders), writeZodSchema (Create/Update/type exports), writeTSTypes (interface fields)- Full
Generator.Run()integration: basic resource (all files created + all 8 injections verified), idempotent (markers preserved), compound names (BlogPost → blog_post.go), role-restricted routes remove_test.go: removeLinesContaining (removes matching, error on missing), removeInlineText, removeLineBlock (handler init blocks), removeSchemaExportBlock (multi-line export blocks), generate+remove round-trip (user.go and types/index.ts restored to original)- 56 total passing tests across both packages — 100%
go vetclean
- Go API tests:
- Integration tests for handlers
- Auth flow tests
- Database tests (SQLite in-memory)
- Frontend tests:
- Component tests (React Testing Library + Vitest) scaffolded into web + admin apps
- Utility unit tests (cn, formatCurrency, truncate)
- E2E tests (Playwright) for auth flow and admin panel navigation
- CI/CD:
- GitHub Actions
ci.yml— test + race detector + coverage + cross-platform build (linux/darwin/windows × amd64/arm64) - GitHub Actions
release.yml— tag-triggered release with binaries + auto release notes
- GitHub Actions
- Go API:
- Connection pooling:
SetMaxIdleConns(10),SetMaxOpenConns(100),SetConnMaxLifetime(30m)in scaffoldeddatabase.go - Response compression:
Gzip()middleware (gzip.BestSpeed + Vary header) in all scaffolded APIs - Request ID tracing:
RequestID()middleware for log correlation across requests - Rate limiting: Sentinel — per-IP (100 req/min) + per-route limits on auth endpoints
- Benchmarks: 7
BenchmarkXxxfunctions ininternal/generate/bench_test.go— run withgo test -bench=.
- Connection pooling:
- Frontend:
- Image optimization (Next.js
<Image>— already in web app template) - Bundle analysis and code splitting (admin lazy routes + @next/bundle-analyzer)
- Image optimization (Next.js
- Additional benchmarks:
- API response time benchmarks (httptest-based)
- BenchmarkHealthCheck, BenchmarkAuthLogin, BenchmarkAuthRegister in scaffolded API
- README.md with GIF demo
- Landing page at
gritframework.dev - YouTube tutorial: "Build a SaaS in 10 Minutes with Grit"
- Blog post: "Why I Built Grit — Go + React Framework with Admin Panels"
- Product Hunt listing
- Dev.to article
- Twitter/X thread
- LinkedIn post
- TikTok demo video
- Reddit posts (r/golang, r/reactjs, r/webdev)
- Hacker News: Show HN
- Go Weekly / React Newsletter submission
- Discord community server
- Documentation website
- Comprehensive test suite
- Performance optimized
- Public launch across all channels
- Community infrastructure (Discord, GitHub Discussions)
| Phase | Duration | Focus | Key Deliverable |
|---|---|---|---|
| Phase 1 | Weeks 1-3 | Foundation | CLI + Go API with auth + Next.js + Docker + GORM Studio |
| Phase 2 | Weeks 4-6 | Code Generator | grit generate resource full-stack code generation |
| Phase 3 | Weeks 7-12 | Admin Panel | Filament-like resource-based admin panel with tables, forms, widgets |
| Phase 4 | Weeks 13-16 | Batteries | File storage, email, jobs, cron, cache, AI |
| Phase 5 | Weeks 17-20 | Launch | Docs, tests, performance, public launch |
- Complete one phase fully before moving to the next. Do not start Phase 2 until every checkbox in Phase 1 is done.
- Test every feature as you build it. Don't just write code — verify it works.
- Follow the folder structure exactly. The conventions in GRIT.md are non-negotiable.
- Generated code must be clean and readable. A developer should be able to understand and modify any generated file.
- The dark theme aesthetic is mandatory. Every UI component must match the GORM Studio design language.
- Commit frequently with conventional commit messages (feat:, fix:, docs:, refactor:, test:).
- If something is unclear, refer to GRIT.md. That document is the source of truth.
When building with Claude Code, always read CLAUDE.md first for project context.