Getting Started

Project Structure

A complete guide to the Grit monorepo layout. Every Grit project follows this exact structure, so any developer (or AI assistant) can jump in and know exactly where everything lives.

Source of truthSharedConsumersgrit syncimportapps/apiGo modelspackages/sharedtypes · schemasapps/webNext.jsapps/adminadmin panelapps/mobileExpo
Go API (types source)Shared packageFrontend apps
The Go API is the source of truth; grit sync feeds shared types to every frontend

Overview

Grit uses a Turborepo-powered monorepo with three applications and one shared package. The Go API, Next.js web app, Next.js admin panel, and shared TypeScript package all live in a single repository with shared configuration.

myapp/
.envEnvironment variables
.env.exampleTemplate with documentation
.env.cloud.exampleCloud-only setup (no Docker)
.gitignoreGit ignore rules
docker-compose.ymlDev: PostgreSQL, Redis, MinIO, Mailhog
docker-compose.prod.ymlProduction: multi-stage builds
grit.config.tsGrit framework configuration
package.jsonRoot package.json (workspace scripts)
pnpm-workspace.yamlpnpm workspace definition
turbo.jsonTurborepo task configuration
README.mdProject documentation

Root Files

The root of the monorepo contains configuration files that apply to the entire project:

.env

All environment variables for the project -- database URL, JWT secret, Redis, storage, email, AI config. This file is gitignored.

.env.example

Documented template of all environment variables with sensible defaults. Committed to git so new developers know what variables are needed.

docker-compose.yml

Development services: PostgreSQL 16, Redis 7, MinIO (S3-compatible storage), and Mailhog (email testing). Run with docker compose up -d.

docker-compose.prod.yml

Production setup with multi-stage Docker builds for the Go API and Next.js apps.

grit.config.ts

Grit framework configuration -- project name, API URL, and other framework-level settings.

turbo.json

Turborepo configuration defining build, dev, and lint tasks with dependency relationships and caching.

pnpm-workspace.yaml

Defines the pnpm workspace: apps/* and packages/* directories are included.

package.json

Root package.json with workspace-level scripts like dev, build, and lint.

Go API (apps/api/)

The Go backend is a Gin web server with GORM ORM. It follows Go conventions with an internal/ directory for private packages and cmd/ for the entry point.

apps/api/
go.modGo module definition
go.sumDependency checksums
DockerfileMulti-stage production build
.air.tomlHot reload configuration
main.goEntry point: init config, DB, router, start server
config.goLoad .env, parse config struct
database.goGORM connection, auto-migration
user.goUser model (built-in)
post.goGenerated models go here
auth.goAuth endpoints (login, register, etc.)
user.goUser CRUD endpoints
post.goGenerated handlers go here
auth.goJWT generation, token validation
user.goUser business logic
post.goGenerated services go here
auth.goJWT validation, role-based access
cors.goCORS configuration
logger.goStructured JSON logging
routes.goRoute registration (all endpoints)
cache.goRedis caching service
storage.goS3/R2/MinIO file storage
mailer.goResend email service
jobs.goAsynq background job queue
cron.goAsynq cron scheduler
ai.goAI integration (Vercel AI Gateway — one key, many models)

Key Conventions

  • Models define GORM structs with json, gorm, and binding tags. One file per model.
  • Handlers are thin HTTP controllers. They parse requests, call services, and return responses. No business logic in handlers.
  • Services contain business logic. They interact with the database through GORM and are called by handlers.
  • Middleware runs before handlers. Auth, CORS, and logging are pre-configured.
  • Routes are registered in a single file. Each resource group is clearly separated.

Web App (apps/web/)

The main Next.js frontend application. Uses the App Router with route groups for auth and dashboard sections.

apps/web/
package.json
next.config.ts
tailwind.config.ts
Dockerfile
layout.tsxRoot layout with providers
page.tsxLanding page
login/page.tsx
register/page.tsx
forgot-password/page.tsx
layout.tsxDashboard layout (sidebar + navbar)
dashboard/page.tsxMain dashboard
use-auth.tsAuth hooks (login, register, logout, me)
use-posts.tsGenerated resource hooks
api-client.tsAxios instance with JWT interceptor
auth.tsAuth utilities (token storage)
utils.tsUtility functions

Key Conventions

  • Route groups (auth) and (dashboard) organize pages without affecting the URL structure.
  • Hooks wrap React Query mutations and queries. All data fetching goes through hooks, never raw fetch calls in components.
  • API client is a pre-configured Axios instance that automatically injects JWT tokens and handles token refresh.
  • UI components come from shadcn/ui. Add more with pnpm dlx shadcn@latest add button.

Admin Panel (apps/admin/)

The Filament-like admin panel. A separate Next.js app that provides resource management with data tables, forms, and dashboard widgets.

apps/admin/
package.json
next.config.ts
tailwind.config.ts
layout.tsxAdmin layout with sidebar
page.tsxDashboard with widgets
users/page.tsxUser management page
posts/page.tsxGenerated resource pages
admin-layout.tsxAdmin shell
sidebar.tsxCollapsible sidebar
navbar.tsxTop navigation bar
data-table.tsxServer-side paginated table
columns.tsxColumn definitions
filters.tsxTable filters
form-builder.tsxDynamic form renderer
form-modal.tsxModal form wrapper
stats-card.tsxStat number + trend
chart-widget.tsxRecharts wrapper
recent-activity.tsxActivity feed
use-auth.tsAdmin auth hooks
use-posts.tsGenerated resource hooks
index.tsResource registry
users.tsUser resource config
posts.tsGenerated resource configs

Key Conventions

  • Resource definitions in resources/ define the table columns, form fields, filters, and actions for each resource. This is how the admin panel generates its UI.
  • Data tables are server-side paginated. They communicate directly with the Go API for sorting, filtering, and searching.
  • Form builder renders forms dynamically from resource definitions. Field types include text, number, select, date, toggle, and file upload.
  • Widgets are dashboard components that fetch data from the API and display stats, charts, and activity feeds.

Shared Package (packages/shared/)

The shared package contains TypeScript types, Zod validation schemas, and constants used by both the web app and admin panel. This is the glue that keeps the frontend in sync with the Go backend.

packages/shared/
package.json
user.tsUser create/update schemas
post.tsGenerated schemas
index.tsRe-exports all schemas
user.tsUser type + API response types
post.tsGenerated types
api.tsPagination, error, response types
index.tsRe-exports all types
index.tsRoles, API routes, config constants

Key Conventions

  • Schemas are Zod validation schemas that match the Go model struct tags. They are the source of truth for frontend validation.
  • Types are TypeScript interfaces that mirror Go structs. Generated by grit sync from the Go model definitions.
  • Constants include role strings, API route paths, and configuration values shared between all frontend apps.
  • Both apps/web and apps/admin import from @shared/schemas, @shared/types, and @shared/constants.

Where Things Go

A quick reference for where to put different types of code:

WhatWhere
New database modelapps/api/internal/models/<name>.go
API endpoint handlerapps/api/internal/handlers/<name>.go
Business logicapps/api/internal/services/<name>.go
Auth middlewareapps/api/internal/middleware/auth.go
API route registrationapps/api/internal/routes/routes.go
Environment configapps/api/internal/config/config.go
Background jobapps/api/internal/jobs/jobs.go
Email templateapps/api/internal/mail/templates/
Zod validation schemapackages/shared/schemas/<name>.ts
TypeScript typepackages/shared/types/<name>.ts
React Query hookapps/web/hooks/use-<names>.ts
Admin resource pageapps/admin/app/resources/<names>/page.tsx
Admin resource definitionapps/admin/resources/<names>.ts
Reusable UI componentapps/web/components/shared/
shadcn/ui componentapps/web/components/ui/
Dashboard widgetapps/admin/components/widgets/

Generated vs. Hand-Written Code

When you run grit generate resource, the CLI creates files in all the locations listed above. These generated files are yours to modify. The CLI uses marker comments like // grit:inject-routes and // grit:inject-models to know where to inject new code into existing files (like routes.go and database.go).

Do not remove these marker comments. They are how the CLI knows where to add new routes and model registrations when you generate additional resources.