> ## Documentation Index
> Fetch the complete documentation index at: https://docs.varianz.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Build integration

> Keep VPoint schemas static and in sync with your source: varianz-scan for Python and TypeScript, varianz-gen for Go, and the JVM annotation processor.

Each SDK ships a build-time tool that derives VPoint schemas from source, without running your service. Wiring it into your build gives you:

* **Stages from the first request** — no lazy first-call schema resolution, no warmup requests in tests.
* **Early failures** — schema problems (untyped parameters, fields that can't cross the FFI boundary) fail the build instead of a test run.
* **A queryable catalog** — VPoints appear in the registry's catalog before the service even starts.

## Python

The `varianz-scan` CLI is installed with the `varianz` wheel. It imports your modules and extracts VPD schemas offline:

```bash theme={null}
varianz-scan src/myservice/ -o vpds/
# equivalently: python -m varianz.scanner src/myservice/ -o vpds/
```

Hook it into your build in whatever runner you use:

```toml theme={null}
# pyproject.toml (hatch)
[tool.hatch.envs.default.scripts]
scan = "varianz-scan src/myservice/ -o vpds/"
```

Because it imports your modules, the scanning environment needs your dependencies installed (grpcio, proto stubs, and so on). For Docker-based services, run it inside the container or install deps in the host virtualenv.

## TypeScript

`@varianz/scanner` provides a pure-static scanner built on the TypeScript compiler API — it never imports or executes your code. It derives a `VPointManifest` covering every `createVPoints` and `@vpoint` registration, including typed parameter, return, and struct schemas. The SDK auto-loads the manifest at module init, so undecorated registrations carry full schemas at runtime.

```bash theme={null}
npx varianz-scan            # scans the project, writes node_modules/.varianz/
npx varianz-scan --init     # adds a "prebuild": "varianz-scan" hook to package.json
npx varianz-scan --watch    # rescan on save; pair with tsc --watch
```

Configuration lives in `varianz.config.json` (all fields optional):

```json theme={null}
{
  "include": ["src"],
  "exclude": ["**/*.test.ts"],
  "followModules": [],
  "outputDir": "node_modules/.varianz"
}
```

`followModules` allow-lists npm packages whose types should resolve into struct schemas; everything else surfaces as `Unknown` (CEL field *access* on `Unknown` still works at runtime — only struct-literal *construction* needs a typed schema).

With the scanner in place, `@struct`/`@field` decorators become fine-grained overrides rather than requirements: reach for them when you need a canonical name different from the TS symbol, a specific numeric kind (`Kind.Int32` instead of the default `Float64` for `number`), or a registration with no static call site. Set `VARIANZ_DISABLE_AUTO_LOAD=1` to skip manifest auto-loading (useful in tests).

## Go

`varianz-gen` is a static-analysis tool that scans Go source for VPoint registrations — both the functional form (`varianz.VPoint(...)`) and the `Embed` service form — and generates optimized code:

```go theme={null}
//go:generate go run go.varianz.io/sdk/cmd/varianz-gen -output vpoints -out varianz_gen.go .
```

```bash theme={null}
go generate ./...
```

| Flag              | Output                   | Use case                                                                            |
| ----------------- | ------------------------ | ----------------------------------------------------------------------------------- |
| `-output json`    | VPD JSON                 | Registry pre-seeding, tooling                                                       |
| `-output go`      | `VarianzVPDs()` function | Schema-only compile-time registration                                               |
| `-output vpoints` | `init()` + typed proxies | Full codegen: no reflection at runtime, typed `RegisterPricingService(...)` proxies |

When the generated file is present the runtime uses it instead of reflection; when absent, reflection kicks in automatically — your code is unchanged either way. `varianz-gen` also acts as a build gate: it exits non-zero when a request/response type has a field that can't cross the FFI boundary (`chan`, `func`, `unsafe.Pointer`), so run it in CI.

## Java and Kotlin

The JVM SDKs need no separate scan step — the annotation processor (Java) or KSP processor (Kotlin) generates the `<ClassName>VPoints` aggregates and embeds VPD schemas during normal compilation. The Gradle and Maven plugins configure this for you.

To verify it ran: with Gradle, `./gradlew compileJava` logs `Note: [Varianz] Generated adapters...`; with Maven, the `varianz-maven-plugin:scan` goal reports discovered VPDs after compilation.

## Skipping codegen

`VARIANZ_SKIP_CODEGEN=true` makes the build-time tools emit nothing — useful for builds that must not touch generated output. It's independent of `VARIANZ_ENABLED`: skipping codegen doesn't disable the SDK at runtime, and vice versa. See [Configuration](/reference/configuration).
