Your First Grit App
In this course, you will install Grit, create your first full-stack project, understand every folder and file it generates, and run all the development servers. By the end, you will have a working app with authentication, admin panel, and database.
What is Grit?
Grit is a full-stack framework that combines Go (for the backend) with React (for the frontend).
- • Grit uses Go with the Gin web framework and GORM ORM for the API
- • Grit uses React with Next.js or TanStack Router for the frontend
- • Grit generates a complete project with authentication, admin panel, and more
- • Grit has a CLI (Command Line Interface) that helps you generate code, run migrations, and deploy
- • Grit is open source and free to use (MIT license)
grit new myapp.Prerequisites
Before installing Grit, you need four tools on your computer:
| Tool | Version | What it does | Check |
|---|---|---|---|
| Go | 1.21+ | Runs the backend API server | go version |
| Node.js | 18+ | Runs the frontend apps | node --version |
| pnpm | 8+ | Installs JavaScript packages | pnpm --version |
| Docker | 20+ | Runs PostgreSQL, Redis, MinIO | docker --version |
npm install -g pnpmChallenge: Check Your Tools
Open your terminal and run all four check commands from the table above. Write down the version of each tool. All four must return a version number before you continue.
Install Grit
Grit is installed using Go's go install command. This downloads the Grit CLI binary and puts it in your Go bin directory.
go install github.com/MUKE-coder/grit/v2/cmd/grit@latestCommand Explained
- •
go installtells Go to download and compile a package - •
github.com/MUKE-coder/grit/v2/cmd/gritis the path to the Grit CLI on GitHub - •
@latestmeans get the newest version
After installation, verify it works:
grit version
# Output: grit version 3.5.0export PATH=$PATH:$(go env GOPATH)/bin to your shell profile (~/.bashrc or ~/.zshrc), then restart your terminal.Challenge: Install Grit
Run the install command, then run grit version to verify. You should see "grit version 3.5.0" (or newer).
Create Your First Project
The grit new command creates a new project. When you run it without flags, it enters interactive mode and asks you questions.
grit new myappQuestion 1: Choose your architecture
? Select architecture:
> Triple — Web + Admin + API (Turborepo)
Double — Web + API (Turborepo)
Single — Go API + embedded React SPA (one binary)
API Only — Go API (no frontend)
Mobile — API + Expo (React Native)For this course, select Triple. This gives you the full experience: a web app, an admin panel, and a Go API — all in one project.
| Architecture | What you get | Best for |
|---|---|---|
| Triple | Web + Admin + API | SaaS apps, platforms |
| Double | Web + API | Simple apps, blogs |
| Single | One Go binary | Microservices, internal tools |
| API Only | Go backend only | Mobile backends, headless APIs |
| Mobile | API + Expo | React Native apps |
Question 2: Choose your frontend
? Select frontend:
> Next.js — SSR, SEO, App Router
TanStack Router — Vite, fast builds, small bundle (SPA)Select Next.js for this course.
Question 3: Choose your admin style
? Select admin panel style:
> Default — Clean dark theme
Modern — Gradient accents
Minimal — Ultra clean
Glass — GlassmorphismSelect Default. You can always change this later.
grit new myapp --triple --next --style defaultChallenge: Create a Project
Run grit new myapp and select Triple, Next.js, and Default style. Wait for it to finish.
Challenge: Create with Flags
Delete the myapp folder (rm -rf myapp). Now create the same project using flags instead of interactive mode: grit new myapp --triple --next. Same result, no prompts.
Understanding the Project Structure
Grit created a folder called myapp/. Let's look inside:
myapp/
├── apps/
│ ├── api/ ← Go backend (Gin + GORM)
│ ├── web/ ← Next.js frontend
│ └── admin/ ← Next.js admin panel
├── packages/
│ └── shared/ ← Zod schemas + TypeScript types
├── docker-compose.yml ← PostgreSQL, Redis, MinIO, Mailhog
├── turbo.json ← Monorepo task runner config
├── package.json ← Root package.json
├── pnpm-workspace.yaml ← Workspace definition
└── .env ← Environment variablesUser struct and GORM creates the users table automatically.Structure Explained
| Folder | What's inside | Language |
|---|---|---|
| apps/api/ | Go REST API — models, handlers, services, middleware, routes | Go |
| apps/web/ | Main frontend — pages, components, hooks | TypeScript + React |
| apps/admin/ | Admin dashboard — resource management, data tables | TypeScript + React |
| packages/shared/ | Shared Zod validation schemas and TypeScript types | TypeScript |
| .env | All configuration — database URL, API keys, secrets | Key=Value |
Challenge: Explore the Folders
Open the myapp folder in VS Code (code myapp). Look at each folder in the table above. Can you find the Go API entry point at apps/api/cmd/server/main.go?
Inside the Go API
The Go API is the brain of your application. It lives in apps/api/:
apps/api/
├── cmd/
│ ├── server/main.go ← Entry point (starts the API)
│ ├── migrate/main.go ← Database migration runner
│ └── seed/main.go ← Database seeder
└── internal/
├── config/ ← Reads .env variables
├── database/ ← Connects to PostgreSQL
├── models/ ← Database tables (User, Upload, Blog...)
├── handlers/ ← HTTP request handlers
├── services/ ← Business logic
├── middleware/ ← Auth, CORS, logging, rate limiting
├── routes/ ← Route definitions
├── cache/ ← Redis caching
├── storage/ ← File uploads (S3/MinIO)
├── mail/ ← Email service (Resend)
├── jobs/ ← Background jobs (asynq)
├── ai/ ← AI service (Vercel AI Gateway)
└── totp/ ← Two-factor authenticationPOST /api/auth/login logs a user in and returns a token. The frontend sends JSON, the API processes it, and returns JSON back.How a Request Flows Through the API
When a user does something (like clicking "Login"), here's what happens:
Browser → HTTP Request → Middleware → Handler → Service → Database
↓ ↓
(Auth check) (GORM query)
↓ ↓
Handler ← Service ← Database Response
↓
JSON Response → Browser- • Middleware runs first — checks if the user is logged in, logs the request, applies rate limits
- • Handler receives the request — validates input data, then calls the service
- • Service contains business logic — talks to the database, processes data, applies rules
- • Model defines the database table — what columns exist, their types, and relationships
Challenge: Read the Entry Point
Open apps/api/cmd/server/main.go and read through it. Can you find where: (1) the database connects, (2) the router is set up, and (3) the server starts listening?
Challenge: Find the User Model
Open apps/api/internal/models/user.go. List all the fields the User model has. Can you identify the GORM tags (gorm:"...") and JSON tags (json:"...")?
Start Docker Services
Your app needs a database (PostgreSQL), cache (Redis), file storage (MinIO), and a mail catcher (Mailhog). All of these run inside Docker containers.
cd myapp
docker compose up -dCommand Explained
- •
cd myapp— moves into your project folder - •
docker compose up— readsdocker-compose.ymland starts all services - •
-dmeans "detached" — they run in the background so you get your terminal back
| Service | Port | What it does |
|---|---|---|
| PostgreSQL | 5432 | Main database — stores users, posts, everything |
| Redis | 6379 | Cache (fast temporary storage) and job queue |
| MinIO | 9000 / 9001 | File storage (S3-compatible, for uploads) |
| Mailhog | 8025 | Catches all emails locally (for testing) |
Check if everything is running:
docker compose ps
# All 4 services should show "running"Challenge: Start Docker Services
Run docker compose up -d inside your project. Then run docker compose ps to verify all 4 services are running. If any service failed, run docker compose logs to see what went wrong.
Start the Development Servers
Install JavaScript dependencies first:
pnpm installpnpm install reads the package.json file and downloads everything your project needs.Then start all apps at once:
pnpm devThis starts three servers simultaneously using Turborepo:
| App | URL | What you see |
|---|---|---|
| Web App | http://localhost:3000 | Main frontend with login/register/dashboard |
| Admin Panel | http://localhost:3001 | Admin dashboard with user management |
| Go API | http://localhost:8080 | REST API (JSON responses) |
pnpm dev, open a separate terminal and run: cd apps/api && go run cmd/server/main.goChallenge: Start Everything
Run pnpm install then pnpm dev. Open all three URLs in your browser.
Challenge: Register an Account
Go to http://localhost:3000 and click "Register". Create an account with your email and password. You should be redirected to the dashboard after registration.
Challenge: Log Into the Admin Panel
Go to http://localhost:3001 and log in with the same credentials. Explore the sidebar — click on Users, Dashboard, and System pages.
Built-in Tools
Your API comes with five built-in tools, each with its own web interface:
| Tool | URL | What it does |
|---|---|---|
| GORM Studio | localhost:8080/studio | Browse database tables, view/edit records, run SQL |
| API Docs | localhost:8080/docs | Interactive API documentation — test every endpoint |
| Pulse | localhost:8080/pulse/ui | Request tracing, performance metrics, database monitoring |
| Sentinel | localhost:8080/sentinel/ui | Security dashboard — rate limits, blocked IPs, threats |
| Mailhog | localhost:8025 | Email inbox — catches all emails sent during development |
Challenge: Visit GORM Studio
Open http://localhost:8080/studio. Log in (default: admin/studio). Find the "users" table and look for the account you just registered.
Challenge: Test the API Docs
Open http://localhost:8080/docs. Find the "POST /api/auth/login" endpoint. Click it, fill in your email and password, and click "Send". You should get a JSON response with a token.
Challenge: Check Pulse
Open http://localhost:8080/pulse/ui. Refresh your web app a few times, then check Pulse again. Can you see the requests being logged with their response times?
Challenge: Check Mailhog
Open http://localhost:8025. Is there a welcome email from when you registered? Open it and look at the HTML template.
The .env File
Every Grit project has a .env file at the root. This file stores all your configuration as key-value pairs:
# Core
APP_NAME=myapp
APP_ENV=development
APP_PORT=8080
DATABASE_URL=postgres://postgres:postgres@localhost:5432/myapp?sslmode=disable
JWT_SECRET=your-secret-key
REDIS_URL=redis://localhost:6379
# Storage (MinIO for local development)
STORAGE_DRIVER=minio
STORAGE_ENDPOINT=localhost:9000
# Email
RESEND_API_KEY=
MAIL_FROM=noreply@localhost
# AI (Vercel AI Gateway)
AI_GATEWAY_API_KEY=
AI_GATEWAY_MODEL=anthropic/claude-sonnet-4-6.env file keeps these values outside your code so you can change them without modifying any Go or TypeScript files..env file to Git — it contains secrets like API keys and database passwords. Grit adds it to .gitignore automatically. Use .env.example as a template for other developers.Challenge: Read the .env File
Open the .env file. Find: (1) What database name is it using? (2) What port does the API run on? (3) What is the JWT_SECRET set to?
Essential CLI Commands
Here are commands you'll use every day:
| Command | What it does |
|---|---|
| grit routes | Lists all API endpoints in a formatted table |
| grit migrate | Creates or updates database tables from your Go models |
| grit seed | Fills the database with demo data (admin user, sample posts) |
| grit studio | Opens the database browser in your browser |
| grit version | Shows the installed Grit version |
Challenge: List Your Routes
Run grit routes in your project folder. How many routes does your app have? Can you find the login endpoint? The register endpoint? Which routes are "protected" (require authentication)?
What You Learned
- What Grit is — a full-stack Go + React framework
- How to install Grit with
go install - How to scaffold a project with
grit new(interactive and with flags) - The monorepo project structure (apps/api, apps/web, apps/admin, packages/shared)
- How the Go API is organized (middleware → handler → service → database)
- How to start Docker services and development servers
- The 5 built-in tools (GORM Studio, API Docs, Pulse, Sentinel, Mailhog)
- How the .env file works and why you never commit it to Git
Challenge: Final Challenge: Start Fresh
Delete the myapp folder completely. Now create a new project called bookstore using Triple architecture but with TanStack Router (Vite) instead of Next.js: grit new bookstore --triple --vite. Start everything and verify it works. Notice any differences from the Next.js version?
Enjoying the course?
Help us grow — star us on GitHub, subscribe on YouTube, and follow on LinkedIn.