gofasta new
Creates a brand-new Gofasta project from scratch. By default, this generates a REST-only Postgres-backed project with database migrations, authentication, dependency injection, background jobs, email support, Docker configuration, and CI/CD pipelines. Two flags adjust what gets generated: --driver picks the database engine, and --graphql adds a GraphQL layer alongside REST.
Usage
gofasta new <name> [flags]The <name> can be a simple name like myapp or a full Go module path like github.com/myorg/myapp. When a simple name is used (no / in the argument), the module path defaults to the project name. When a full path is provided, it is used as the Go module path and the last segment becomes the project directory name.
Flags
| Flag | Default | Description |
|---|---|---|
--driver | postgres | Database driver: postgres | mysql | sqlite | sqlserver | clickhouse. See --driver for the full per-driver breakdown. |
--graphql | false | Include GraphQL support (gqlgen schema, resolvers, /graphql endpoint, playground). See --graphql / --gql. |
--gql | false | Alias for --graphql |
--layout | layered | Project layout: layered | feature. Persisted to config.yaml’s project.layout; read by every subsequent gofasta g * and gofasta refactor command. See --layout below. |
--layout
Picks the project layout the scaffold writes — layered (the historical default) or feature (the feature-package layout). The choice is persisted to config.yaml’s project.layout field so every subsequent generator emits files in the right shape automatically.
gofasta new my-app # layered (default)
gofasta new my-app --layout=layered # same as above, explicit
gofasta new my-app --layout=feature # feature-packageBoth produce a project that compiles, runs, and passes its tests out of the box. The two ship the same packages, the same wire bindings, the same HTTP routes — they differ only in how files are organized on disk.
Layered (--layout=layered) puts each layer in its own directory. All controllers under app/rest/controllers/, all services under app/services/, all models under app/models/. Adding a Subscription resource touches one file in each of those directories.
app/
├── models/user.model.go
├── dtos/{aliases.go, user.dtos.go}
├── repositories/{interfaces/, user.repository.go}
├── services/{interfaces/, user.service.go, user_errors.go, user_inputs.go, password_generator.go}
├── rest/{controllers/user.controller.go, routes/user.routes.go, routes/index.routes.go}
├── validators/{app_validator.go, user.validators.go, register.go, ...}
├── di/{container.go, wire.go, providers/{core.go, user.go}}
├── jobs/
└── tasks/Feature-package (--layout=feature) groups files by business domain. Everything the User feature needs is in app/user/. Adding a Subscription resource creates one directory.
app/
├── models/user.model.go # ← stays layered (model never moves)
├── shared/dtos/aliases.go # ← shared envelopes relocated here
├── user/ # ← per-feature directory
│ ├── dtos.go
│ ├── repository.go + repository_iface.go
│ ├── service.go + service_iface.go
│ ├── errors.go
│ ├── inputs.go
│ ├── controller.go
│ ├── routes.go # exports RegisterRoutes(...)
│ ├── wire.go # exports UserSet
│ └── password_generator.go # only consumer is User
├── validators/ # ← per-resource validators stay (shared infra)
├── di/{container.go, wire.go, providers/core.go}
├── rest/routes/index.routes.go
├── jobs/
└── tasks/The feature-package layout is a hybrid — most per-resource files collapse into the feature directory, but a few categories stay in their layered locations for technical reasons (models, shared validator infrastructure, cross-cutting wiring). See Project structure → What moves and what doesn’t for the full breakdown.
Picking a layout
| Use layered if… | Use feature if… |
|---|---|
| Your project has <10 resources | Your project has 15+ resources |
| Team comes from layered MVC backgrounds | You’re planning to extract microservices later |
| You haven’t felt pain from the current shape | Multiple teams step on each other in shared layer dirs |
| You prefer dense, flat directory listings | You want ls app/ to read like a domain model |
Both layouts are legitimate. You can switch later with gofasta refactor — it works bidirectionally.
What the scaffold persists
Both --layout values write a project section to the generated config.yaml:
project:
layout: layered # or: featureDon’t edit this field by hand after creation. It must agree with the filesystem shape. The CLI reads it on every gofasta g * invocation to know how to emit new resources, and gofasta refactor is the only command that should write to it (the refactor changes both the value and the on-disk shape together).
After scaffolding
Every generator is layout-aware — you never specify --layout again:
# In a layered project
gofasta g scaffold Product name:string price:float
# → app/models/product.model.go
# → app/services/product.service.go
# → app/repositories/product.repository.go
# → app/rest/controllers/product.controller.go
# → ... etc.
# In a feature project — same command, different output shape
gofasta g scaffold Product name:string price:float
# → app/models/product.model.go (model stays layered)
# → app/product/service.go
# → app/product/repository.go
# → app/product/controller.go
# → app/product/routes.go
# → app/product/wire.go
# → ... etc.See Code Generation for the per-generator path matrix.
Flag references
Each flag has a dedicated reference page with examples, edge cases, and per-driver details:
--driver— pick the database engine (5 supported drivers; defaultpostgres)--graphql/--gql— add GraphQL alongside REST
Without --graphql, the generated project is REST-only — no GraphQL files, no gqlgen dependency, and no /graphql routes. Without --driver, the project is wired for Postgres — compose.yaml ships postgres:18-alpine, config.yaml is preset to driver: postgres, and db/migrations/ contains the Postgres-flavored foundational migrations.
Examples
Create a project with a simple name:
gofasta new myappCreate a project with a full Go module path:
gofasta new github.com/myorg/myappCreate a project with GraphQL support:
gofasta new myapp --graphqlCreate a MySQL-backed project:
gofasta new myapp --driver mysqlCombine flags (a SQLite + GraphQL project):
gofasta new myapp --driver sqlite --graphqlWhat It Does
When you run gofasta new myapp, the CLI performs the following steps in order:
- Create project directory — creates the
myapp/directory - Initialize Go module — runs
go mod initwith the appropriate module path - Copy skeleton files — writes template files into the project, including a starter User resource
- Install Gofasta and Cobra — runs
go getfor the gofasta library at the exact version pinned by the CLI release (the version its templates were tested against) andgo get github.com/spf13/cobra@latestto add them togo.mod - Install tools — runs
go getto add tool dependencies (wire, air, swag) andgo mod edit -toolfor each. If--graphqlis passed, gqlgen is also installed. - Tidy modules — runs
go mod tidyto synchronize dependencies - Generate Wire DI code — runs
go tool wire ./app/di/to generate the dependency injection container - Generate GraphQL code (only with
--graphql) — runsgo tool gqlgen generateto create Go types and resolvers from the GraphQL schema - Initialize Git — runs
git initand creates an initial commit
What It Generates
Running gofasta new myapp produces the following project structure. Items marked (—graphql only) are only included when the --graphql flag is passed:
myapp/
cmd/
serve.go # HTTP server entry point
app/
models/ # GORM database models
user.model.go
repositories/ # Data access layer
interfaces/
user_repository.go
user.repository.go
services/ # Business logic layer
interfaces/
user_service.go
auth_service.go
user.service.go
auth.service.go
rest/
controllers/ # REST API controllers
user.controller.go
auth.controller.go
routes/ # Route definitions
index.routes.go
user.routes.go
auth.routes.go
middlewares/ # HTTP middlewares
auth.middleware.go
casbin.middleware.go
dtos/ # Request/response DTOs
user.dtos.go
auth.dtos.go
di/ # Dependency injection (Google Wire)
container.go
wire.go
providers/
user.go
auth.go
graphql/ # GraphQL schema and resolvers (--graphql only)
schema/ # .gql schema files (common, user, server.health)
resolvers/ # resolver.go + per-schema *.resolvers.go + helpers
jobs/ # Background jobs
tasks/ # Scheduled tasks (cron)
emails/ # Email templates
db/
migrations/ # SQL migration files (up/down)
seeders/ # Database seed files
config/
config.yaml # Application configuration
docker-compose.yml # Docker Compose for app + database
Dockerfile # Multi-stage Docker build
Makefile # Common development commands
.github/
workflows/ # CI/CD pipeline definitions
.air.toml # Air hot reload configuration
.env.example # Environment variable template
gqlgen.yml # gqlgen GraphQL configuration (--graphql only)
go.mod
go.sumArchitecture
The generated project’s request flow is identical regardless of --layout — every request travels the same chain of objects:
Controller --> Service --> Repository --> Database- Controllers parse the HTTP request, validate input, delegate to services, and shape the response.
- Services hold business logic, translate between wire DTOs and domain inputs, and call repositories.
- Repositories handle data access via GORM with optimistic locking baked into update operations.
- DI Container wires the dependencies at compile time via Google Wire — there are no runtime reflection-based DI lookups.
The two --layout values differ in how the per-resource Go files are organized on disk, not in the request flow:
--layout=layered(default) — files grouped by technical role.app/models/,app/services/,app/repositories/,app/rest/controllers/,app/rest/routes/, etc. One file per resource in each directory.--layout=feature— files grouped by business domain.app/user/contains the user feature’s service, repository, controller, routes, DTOs, and Wire provider. Per Project structure → What stays put in feature-package layout, four categories stay in their layered locations even in feature mode (models, per-resource validators, validator infrastructure, theValidatorinterface) — see that section for the full rationale.
Both layouts ship the same Wire dependency graph, the same HTTP middleware stack, the same migration model, and the same generated tests. You can switch between them at any time with gofasta refactor feature or gofasta refactor layered.