grit setup creates a new project the way an installer does. It asks for a starter and for the services the project will use, then runs the steps that make the result runnable: dependencies, local services, migrations, sample data, the first commit.
grit new is the fast, scriptable scaffold and its behaviour is frozen, so a build script that runs it keeps working. grit setup is the guided path, and it can ask questions and change what the project starts with. Keeping them apart is why a change to one cannot surprise somebody relying on the other. Setup only creates new projects; use grit upgrade on one that exists.Quick start
$grit setup myapp
The wizard asks for:
- the architecture: single, double, triple, desktop, api, mobile or full
- the frontend: Next.js or TanStack Router, when the shape has one
- the starter: blank or blog
- the database: Postgres, MySQL, SQLite or in-memory
- Redis, storage and mail: local, external or off
- the built-in plugins that fit the chosen shape
- whether to run
grit startat the end
Starters
A starter is the example content the project begins with. Both are the same scaffold:blank is that scaffold with the built-in Blog example removed, and blog keeps it exactly as grit new writes it. There is no separate template repository, so a starter cannot fall behind the scaffold.
An api or mobile project always starts blank: it has no web or admin pages for the Blog's screens to live on.
grit upgrade leaves them alone and reports them. That is deliberate: the templates still contain the Blog, so an upgrade that rewrote them would put the Blog links back, pointing at pages the starter removed. The trade is a handful of files that stop receiving framework fixes, and grit upgrade --diff shows what you are missing in them.Non-interactive use
Pass --yes with the answers as flags. This is the shape for CI and scripts, and a project name is required. Setup refuses to prompt when it has no terminal, rather than hanging.
$grit setup myapp --yes \$ --arch triple --frontend next --starter blank \$ --db sqlite --redis off --storage local --mail log \$ --no-docker --no-git --no-start
Services
Redis, storage and mail are written into .env. Each one can point at a local container, at an external provider, or be off.
# Local, started with docker compose$grit setup myapp --redis local --storage minio --mail mailhog# External$grit setup myapp --redis external --redis-url redis://...$grit setup myapp --storage s3 --storage-endpoint ... --storage-access-key ... --storage-secret-key ...$grit setup myapp --mail resend --mail-api-key ...# Off$grit setup myapp --redis off --storage local --mail log
Credentials go into .env, which setup writes with owner-only permissions because it now holds real values rather than placeholders. No external secret is printed back to the terminal.
What it runs
- Scaffolds the project with the chosen architecture, frontend and theme.
- Applies the starter.
- Configures
.envfor Redis, storage and mail. - Installs the built-in plugins that fit the shape.
- Installs dependencies and tidies the Go module.
- Starts local services with Docker, unless
--no-docker. - Migrates the database and seeds sample data.
- Initialises git and makes the first commit.
- Offers to run
grit start.
Every step after the scaffold is a command you could run by hand, and when one fails setup prints that command rather than stopping with nothing to do next. A failed pnpm install does not cost you the migration or the first commit: neither needs node.
Flags
| Flag | Meaning |
|---|---|
--arch | single, double, triple, desktop, api, mobile or full |
--frontend | next or tanstack |
--starter | blank or blog |
--db | postgres, mysql, sqlite or memory |
--theme | atlas, aurora, pulse, coral, amber, sky, mono or emerald |
--redis | local, external or off |
--redis-url | External Redis URL |
--storage | minio, s3, r2, local or off |
--storage-* | S3 or R2 endpoint, keys, bucket, region and public URL |
--mail | mailhog, log, resend, mailgun, postmark, sendgrid, ses or smtp |
--mail-* | From address, API key, domain, endpoint and stream |
--smtp-* | SMTP host, port, username, password and encryption |
--ses-region, --aws-* | Amazon SES region and credentials |
--plugin | A built-in plugin to install; repeat or comma-separate |
--i18n | Add internationalisation |
--yes | Use the flags and defaults, with no prompts |
--here | Scaffold into the current directory |
--force | Allow scaffolding into a directory that is not empty |
--no-install | Skip pnpm install |
--no-docker | Do not start local services |
--no-migrate | Skip migrations |
--no-seed | Skip sample data |
--no-git | Skip git init and the first commit |
--star | Star MUKE-coder/grit without asking |
--start, --no-start | Run, or do not run, grit start at the end |
The logins it prints
The closing summary lists what the project exposes, with the login for each:
GORM Studio http://localhost:8080/studio | admin / <generated>Sentinel http://localhost:8080/sentinel/ui | admin / <generated>Admin http://localhost:3001 | admin@example.com / admin123
GORM Studio and Sentinel get a generated local password each. The admin password is admin123 in development unless SEED_ADMIN_PASSWORD is set, and when it is set setup says so rather than echoing it. All of these are development credentials. Change them before production.
If the seed step was skipped, no admin login is shown: run grit seed to create it.
Something wrong, unclear, or missing on this page?
Open an issue: your feedback shapes Grit, and we fix docs fast.
