Project layout
What Your first API leaves in your app folder.
notes-app/ seampact.config.yaml what to generate and check contract/api.yaml your contract openapi/notes.yaml generated OpenAPI document <generated folder>/ generated code, never edit <your code> your handlers and your app- Edit
contract/,seampact.config.yamland your own files. - The generated folder is the
outDirof the config. Whether you commit it depends on the stack: see Generated files.seampact checkcompares a committed folder andopenapi/with the contract. - Add the
baselinefolder (from diff) to.gitignore.
Node: NestJS, Express, Fastify, Hono, AdonisJS
notes-app/ src/ __generated__/ generated code: types/ validators/ server/ notes-controller.ts your handlers main.ts your appCommit src/__generated__ and openapi/.
Java: Spring Boot
notes-app/ build/generated/sources/seampact/main/ generated code (Maven: target/generated-sources/seampact) src/main/java/... your controllersThe build writes the generated folder: do not commit it.
PHP: Laravel, Symfony
notes-app/ app/Generated/ Laravel (Symfony: src/Generated) app/Http/... your controllersCommit the generated folder and openapi/.
Python: FastAPI, Django REST Framework, Django Ninja
notes-app/ generated/notes/ generated code main.py your app (Django: your project files)Commit generated/ and openapi/.
Repository layouts
Section titled “Repository layouts”Layouts mix freely, and each app picks its own stack.
- One monorepo with services, frontends and contracts: a root config lists the apps, each reads its contract as a
pathsource. See monorepo. - Services in a monorepo, frontends apart: the monorepo publishes bundles; each frontend repository pins one with a
package,gitorreleasesource. - One repository per app: the contracts live in a contract repository that publishes bundles, and each app pins the ones it uses. See sharing contracts.
- A shared core contract: pin it as a bundle (npm package, git tag, release URL, or Maven for the JVM plugins), or add it as a git submodule read as a
pathsource. Apathmay point anywhere, inside the repository or not; it is a local source, soallowLocal: falserefuses it.
Next: work with an AI agent, or write more of the contract.