How It Works
If you want to understand why the composition model exists before diving into how it works, start with Why verikt exists.
The Composition Model
Section titled “The Composition Model”Most service scaffolding gives you files. verikt gives you a structure your agents understand, your team can reason about, and your CI can enforce. It does that through two building blocks composed together.
Architecture + Capabilities = Your ServiceArchitecture
Section titled “Architecture”An architecture defines your project’s structure and dependency rules:
- Directory layout (where domain, ports, adapters, etc. live)
- Base files (go.mod, Makefile, Dockerfile, .gitignore)
- Component definitions with dependency constraints
- A fallback
main.go
| Architecture | Structure | Best For |
|---|---|---|
| Hexagonal | domain/ → port/ → service/ → adapter/ | Production APIs, microservices |
| Layered | handler/ → service/ → repository/ → model/ | Standard CRUD APIs |
| Clean | entity/ → usecase/ → interface/ → infrastructure/ | Complex business logic |
| Flat | Single package | CLIs, scripts, prototypes |
Capabilities
Section titled “Capabilities”Capabilities are modular features that plug into your architecture. Each capability provides:
- Template files that get rendered into your project
- Partials — code snippets that inject into the bootstrap wiring (imports, init, shutdown hooks)
- A
capability.yamlmanifest with metadata, requirements, and suggestions
How Composition Works
Section titled “How Composition Works”When you run verikt new, here’s what happens:
-
Load architecture — Read the manifest, set up base variables
-
Detect version — Run
go env GOVERSIONto detect the installed Go version (or use--set GoVersion=X.XX) -
Resolve features — Compare the detected version against
features.yamlto produce a boolean feature map (e.g.,os_root: true,log_slog: true). See the Feature Matrix. -
Load capabilities — Read each capability manifest, validate requirements, conflicts, and
requires_featuresgates -
Collect partials — Gather code snippets from each capability’s
_partials/directory -
Render architecture files — Lay down the base project structure, applying
conditionalrules based on resolved features -
Render capability files — Add capability-specific files with feature-gated conditional file inclusion
-
Inject partials — Capability partials get injected into
bootstrap.goat marked points -
Run hooks —
go mod tidy,git init, etc. -
Generate metadata —
verikt.yamlanddocs/PROJECT.md
Partial Injection Points
Section titled “Partial Injection Points”The bootstrap pattern provides four injection points where capabilities wire themselves in:
| Partial | Purpose | Example |
|---|---|---|
main_imports | Import statements | "github.com/org/svc/adapter/httphandler" |
main_init | Initialize connections | db, err := mysqlrepo.NewConnection(...) |
main_register | Register with lifecycle | app.Register("http", httpServer) |
main_shutdown | Cleanup hooks | app.OnShutdown("mysql", ...) |
Capability Relationships
Section titled “Capability Relationships”Capabilities can declare relationships with each other:
requires— Must be selected together.bootstraprequiresplatform.suggests— Recommended but optional. verikt prompts you in the wizard.conflicts— Cannot coexist.
Smart Suggestions
Section titled “Smart Suggestions”After you select capabilities, verikt checks 18 suggestion rules with cross-referencing and recommends what you might be missing:
Based on your selections, you might also want: [x] platform Production services need config, logging, and lifecycle management [x] bootstrap Bootstrap pattern provides testable dependency wiring [ ] rate-limiting HTTP APIs benefit from rate limiting to prevent abuse [ ] cors Cross-origin resource sharing for browser clientsArchitecture Enforcement
Section titled “Architecture Enforcement”Every scaffolded project includes an verikt.yaml that defines component boundaries:
components: - name: domain in: ["domain/**"] may_depend_on: [] - name: ports in: ["port/**"] may_depend_on: [domain] - name: service in: ["service/**"] may_depend_on: [domain, ports] - name: adapters in: ["adapter/**"] may_depend_on: [ports, domain]Run verikt check at any time to validate these rules. It uses 11 AST-based detectors to catch dependency violations, missing directories, function complexity issues, and anti-patterns.
Ready to try it? Start with AI Agents — set up your project without leaving your agent session. Or go to the CLI Quick Start if you prefer the terminal wizard.