Courses/Grit Web/Your First Grit App
Course 1 of 8~30 min18 challenges

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

Framework: A framework is a pre-built foundation that provides structure, tools, and conventions so you don't have to build everything from scratch. Think of it like a house blueprint — it gives you the walls, plumbing, and wiring, and you add the furniture.
Full-stack: Full-stack means both the backend (server, database, API — the part users don't see) and the frontend (the website or app the user interacts with). Grit handles both.
  • 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)
CLI (Command Line Interface): A program you run in your terminal (like Terminal on Mac or Command Prompt on Windows). Instead of clicking buttons in a graphical interface, you type commands like grit new myapp.

Prerequisites

Before installing Grit, you need four tools on your computer:

ToolVersionWhat it doesCheck
Go1.21+Runs the backend API servergo version
Node.js18+Runs the frontend appsnode --version
pnpm8+Installs JavaScript packagespnpm --version
Docker20+Runs PostgreSQL, Redis, MinIOdocker --version
pnpm: A fast, disk-efficient package manager for JavaScript. It's like npm but faster and uses less disk space. Grit uses pnpm instead of npm because it handles monorepos better. Install it with: npm install -g pnpm
Docker: Docker runs applications in isolated containers. Instead of installing PostgreSQL, Redis, and MinIO directly on your computer, Docker runs them in lightweight virtual environments. This keeps your system clean and makes setup identical across all operating systems.
1

Challenge: 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.

Terminal
go install github.com/MUKE-coder/grit/v2/cmd/grit@latest

Command Explained

  • go install tells Go to download and compile a package
  • github.com/MUKE-coder/grit/v2/cmd/grit is the path to the Grit CLI on GitHub
  • @latest means get the newest version

After installation, verify it works:

Terminal
grit version
# Output: grit version 3.5.0
If you get "command not found", your Go bin directory is not in your PATH. Add export PATH=$PATH:$(go env GOPATH)/bin to your shell profile (~/.bashrc or ~/.zshrc), then restart your terminal.
2

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.

Terminal
grit new myapp

Question 1: Choose your architecture

Terminal
? 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: The structure of your project — how many apps it contains and how they're organized. Triple means three apps (web + admin + API). Double means two (web + API). Single means one Go binary that serves everything.
ArchitectureWhat you getBest for
TripleWeb + Admin + APISaaS apps, platforms
DoubleWeb + APISimple apps, blogs
SingleOne Go binaryMicroservices, internal tools
API OnlyGo backend onlyMobile backends, headless APIs
MobileAPI + ExpoReact Native apps

Question 2: Choose your frontend

Terminal
? Select frontend:
  > Next.js — SSR, SEO, App Router
    TanStack Router — Vite, fast builds, small bundle (SPA)

Select Next.js for this course.

SSR (Server-Side Rendering): The server generates the HTML before sending it to the browser. This is better for SEO because search engines can read the content immediately. Next.js does this by default.
SPA (Single Page Application): The browser downloads one HTML file and JavaScript handles all navigation. Faster page transitions but harder for SEO. TanStack Router with Vite creates SPAs.

Question 3: Choose your admin style

Terminal
? Select admin panel style:
  > Default — Clean dark theme
    Modern — Gradient accents
    Minimal — Ultra clean
    Glass — Glassmorphism

Select Default. You can always change this later.

You can skip the prompts by passing flags directly:grit new myapp --triple --next --style default
3

Challenge: Create a Project

Run grit new myapp and select Triple, Next.js, and Default style. Wait for it to finish.

4

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:

Project Structure
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 variables
Monorepo: A single Git repository that contains multiple projects (apps and libraries). Instead of having separate repos for your API and frontend, everything lives together. This makes it easy to share code and keep things in sync. Grit uses Turborepo to manage the monorepo.
ORM (Object-Relational Mapping): A tool that lets you interact with your database using Go structs instead of writing raw SQL. GORM is Go's most popular ORM. You define a User struct and GORM creates the users table automatically.

Structure Explained

FolderWhat's insideLanguage
apps/api/Go REST API — models, handlers, services, middleware, routesGo
apps/web/Main frontend — pages, components, hooksTypeScript + React
apps/admin/Admin dashboard — resource management, data tablesTypeScript + React
packages/shared/Shared Zod validation schemas and TypeScript typesTypeScript
.envAll configuration — database URL, API keys, secretsKey=Value
5

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/
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 authentication
API (Application Programming Interface): A set of endpoints (URLs) that your frontend calls to get or send data. For example,POST /api/auth/login logs a user in and returns a token. The frontend sends JSON, the API processes it, and returns JSON back.
REST API: A style of API that uses HTTP methods (GET, POST, PUT, DELETE) to perform actions. GET reads data, POST creates data, PUT updates data, DELETE removes data. Grit generates REST APIs automatically.

How a Request Flows Through the API

When a user does something (like clicking "Login"), here's what happens:

Request Flow
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
Middleware: Code that runs before your handler. Like a security guard at a building entrance — it checks your credentials before letting you in. Grit's auth middleware checks the JWT token on every protected request.
6

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?

7

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.

Container: A lightweight, isolated environment that runs an application. Think of it like a tiny virtual computer dedicated to running one thing (like PostgreSQL). Docker manages these containers for you.
Terminal
cd myapp
docker compose up -d

Command Explained

  • cd myapp — moves into your project folder
  • docker compose up — reads docker-compose.yml and starts all services
  • -d means "detached" — they run in the background so you get your terminal back
ServicePortWhat it does
PostgreSQL5432Main database — stores users, posts, everything
Redis6379Cache (fast temporary storage) and job queue
MinIO9000 / 9001File storage (S3-compatible, for uploads)
Mailhog8025Catches all emails locally (for testing)

Check if everything is running:

Terminal
docker compose ps
# All 4 services should show "running"
8

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:

Terminal
pnpm install
Dependencies: External libraries your project uses. For example, React, Tailwind CSS, and Zod are dependencies.pnpm install reads the package.json file and downloads everything your project needs.

Then start all apps at once:

Terminal
pnpm dev

This starts three servers simultaneously using Turborepo:

AppURLWhat you see
Web Apphttp://localhost:3000Main frontend with login/register/dashboard
Admin Panelhttp://localhost:3001Admin dashboard with user management
Go APIhttp://localhost:8080REST API (JSON responses)
If the Go API doesn't start with pnpm dev, open a separate terminal and run: cd apps/api && go run cmd/server/main.go
9

Challenge: Start Everything

Run pnpm install then pnpm dev. Open all three URLs in your browser.

10

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.

11

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:

ToolURLWhat it does
GORM Studiolocalhost:8080/studioBrowse database tables, view/edit records, run SQL
API Docslocalhost:8080/docsInteractive API documentation — test every endpoint
Pulselocalhost:8080/pulse/uiRequest tracing, performance metrics, database monitoring
Sentinellocalhost:8080/sentinel/uiSecurity dashboard — rate limits, blocked IPs, threats
Mailhoglocalhost:8025Email inbox — catches all emails sent during development
12

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.

13

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.

14

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?

15

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:

.env (partial)
# 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
Environment Variables: Configuration values that change between environments (development vs production). You use different database URLs locally vs on your server. The .env file keeps these values outside your code so you can change them without modifying any Go or TypeScript files.
Never commit your .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.
16

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:

CommandWhat it does
grit routesLists all API endpoints in a formatted table
grit migrateCreates or updates database tables from your Go models
grit seedFills the database with demo data (admin user, sample posts)
grit studioOpens the database browser in your browser
grit versionShows the installed Grit version
17

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
18

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?