Skip to content
latest
Getting Started / latest

Directory Structure

Andurel v2 separates application code, generated artifacts, and process boundaries. Everything outside the generated files is ordinary code you own.

Application layout

 1cmd/app/                  web process: load env, runtime.New, lifecycle.Run
 2cmd/queue/                River worker process: runtime.NewQueue
 3cmd/ssr/                  Inertia SSR runtime for production
 4cmd/migrate/              one-shot process that applies pending SQL
 5cmd/seeds/                one-shot process that runs a named seed set
 6config/                   typed, validated configuration
 7domains/                  business logic and persistence; one file per domain
 8domains/<entity>.sql      hand-written SQL colocated with its domain
 9domains/internal/queries/ narsilc output; imported only by domains/**
10services/                 cross-domain workflows, transactions, side effects
11handlers/                 flat HTTP package; func(ctx context.Context) error
12routes/                   route data: names, paths, URL builders
13middleware/               app HTTP policy and the session definition
14internal/runtime/         composition root and process lifecycle
15resources/root.templ      the Inertia root document
16resources/js/Pages/       Inertia page components
17resources/js/Layouts/     shared page layouts
18resources/js/Components/  reusable frontend components
19resources/js/routes.ts    generated TypeScript URL helpers
20resources/js/types/       generated TypeScript payload types
21email/                    templ email templates and send helpers
22queue/                    River workers and registration
23queue/jobs/               River argument types
24migrations/               embedded goose SQL migrations
25seeds/                    named seed sets
26css/                      Tailwind source and theme tokens
27assets/                   embedded static files and the Vite build in assets/dist
28bin/                      pinned tools downloaded by andurel tool sync
29andurel.toml              project metadata and pinned tool versions
30andurel.lock              platform hashes for those tools
31AGENTS.md                 instructions for agents working in this project

Processes

A project has three long-running process shapes and two one-shot ones:

  • cmd/app builds the web graph: HTTP server, renderer, handlers, and the queue insert client. It is the only process that serves requests.
  • cmd/queue builds the worker graph. It registers workers and periodic jobs and does not serve HTTP.
  • cmd/ssr runs the Node Inertia renderer in production.
  • cmd/migrate and cmd/seeds connect, do one task, and exit. Migrations are never applied from application start.

internal/runtime owns each graph. cmd/* only loads the environment, creates a signal context, and calls lifecycle.Run around the runtime's start and stop functions.

Dependency direction

Dependencies point inward:

  • handlers/ parse HTTP input, call a domain or service, and render. They never speak SQL.
  • services/ coordinate domains, own transactions, and call external side effects.
  • domains/ own entity rules, SQL, and generated queries. They import no HTTP, Inertia, routing, handler, middleware, or route package.
  • Only domains/** imports domains/internal/queries. Only domains, internal/runtime, cmd/, seeds/, and migrations/ name storage.Connection.
  • routes/ holds data only. The router itself belongs to pkg/anduin, not to the project.

andurel verify enforces these boundaries and reports a fix for each violation.

Generated files

These files are derived from a source of truth and should not be edited by hand:

Path Written by Refresh with
domains/internal/queries/** narsilc, from domains/**/*.sql andurel sync queries
resources/js/routes.ts the route manifest in routes/ andurel sync routes
resources/js/types/payloads.ts named handler payload structs and handler-owned inertia.FromStruct props andurel sync payloads
resources/root_templ.go, email/*_templ.go templ andurel run or andurel build
assets/css/**, assets/dist/** Tailwind and Vite andurel build

andurel verify fails when generated output is stale and names the command that refreshes it. Hand-written code that happens to live beside generated code, such as domains/<entity>.go and resources/js/Pages/**, is yours.

Project metadata

andurel.toml is the scaffold's own record: schemaVersion, the Andurel version, the project name, the Inertia adapter, the JavaScript package manager, the SSR runtime, the database engine and null type, and the pinned tool versions. andurel.lock records the platform hashes for those tool binaries.

Commit both files. Framework package versions live in go.mod and are refreshed by andurel upgrade or andurel packages update.

Next, read Frontend Options for the UI layer, or Routing for the HTTP side.