Compile Go backends with less wiring.

Anvil turns typed Go declarations into routing, dependency wiring, validation, OpenAPI, manifests, and deterministic testbeds. Review the handwritten API. Commit the generated glue.

~/portal anvil generate
$ anvil generate
config anvil.yaml
scan cmd/api, internal/...
routes 38 routes
policy 9 middleware chains
providers 27 resolved
cycles 0 dependency cycles
emit anvil_autogenerated.go
spec openapi.json
fixtures testbeds generated
generated Go, OpenAPI, manifest, and testbeds

Run generate. Watch wiring appear.

Anvil reads the controllers, policies, providers, and validation tags in your repo, resolves the graph, then writes the Go, specs, manifests, and testbeds that should not be maintained by hand.

Readable source in. Readable Go out.

The controller stays small. The generated wiring is not a hidden runtime registry, it is Go your team can inspect, diff, and debug.

api/projects.go source
type Projects struct {
    sdk.Controller `path:"/projects"`
    Store project.Store

    Routes struct {
        Create sdk.POSTWith[WritePolicy] `path:"/"`
        Get    sdk.GET                   `path:"/:projectId"`
    }
}
internal/anvil/anvil_autogenerated.go generated
return transport.RegisterHTTP(sdk.HTTPRoute{
    Method:     "GET",
    Path:       "/projects/:projectId",
    Controller: "Projects",
    Endpoint:   "Get",
    Handler: func(ctx sdk.Ctx) (any, error) {
        req, err := bindGetProject(ctx)
        if err != nil { return nil, err }
        return c.projects.Get(ctx, req)
    },
})

The framework surface stays human. The wiring becomes mechanical.

Run Anvil during development, in CI, or as a pre-commit check. The same pass catches mistakes and emits the artifacts your docs, tests, and transports need.

Go

Describe the backend in Go.

Controllers, request structs, providers, route marker types, and policies live where your team already reviews code.

source
Generate

Let Anvil resolve the graph.

The compiler walks tags, bindings, middleware, validation, providers, custom rules, and transport adapters with type information.

anvil generate
Commit

Ship the deterministic output.

Readable Go, API specs, manifests, diagnostics, and testbed fixtures stay tied to the application model that produced them.

generated
~/portal anvil generate
$ anvil generate
config anvil.yaml
scan cmd/api, internal/...
routes 38 routes
policy 9 middleware chains
providers 27 resolved
cycles 0 dependency cycles
emit anvil_autogenerated.go
spec openapi.json
fixtures testbeds generated
generated Go, OpenAPI, manifest, and testbeds
Manifest

route and provider graph

OpenAPI

generated operation data

Testbeds

deterministic fixtures

Rules

repository-owned checks

Specs, tests, and rules come from the same model.

Generate OpenAPI, deterministic test scenarios, manifest data, and custom diagnostics from the same declarations that register your app.

Manifest

Every compiler run can produce deterministic JSON that describes routes, bindings, validations, middleware, source locations, and protocol metadata.

Manifest reference
{
  "schema": "anvil.manifest.v1",
  "http": {
    "routes": [
      {
        "method": "GET",
        "path": "/projects/:projectId",
        "controller": "Projects",
        "endpoint": "Get",
        "operationId": "Projects.Get",
        "request": {"package": "example.com/portal/project", "name": "GetProjectRequest"},
        "bindings": [{"field": "ProjectID", "source": "param", "key": "projectId"}],
        "source": {"file": "api/projects.go", "line": 19}
      }
    ]
  }
}

Built for Go teams that care about the shape of the codebase.

Anvil does not ask you to hide your service graph behind magic. It takes the boring repeat work out of the repository and leaves the architecture visible.

Keep the architecture you chose.

Use CQRS, layered services, hexagonal boundaries, or a small package layout. Anvil reads the contracts and builds around them.

Fail before the branch lands.

Bad params, missing providers, invalid tags, policy gaps, and custom rule violations show up during generation with source locations.

Review one model, not five copies.

Routes, policies, OpenAPI, manifests, test data, and generated Go come from the same declarations instead of drifting across files.

Run Anvil against your own Go package.

Generate the wiring, inspect the diff, and keep the pieces that make the repository easier to maintain.