Skip to content

Configuration

Typra is configured from the @typra/emitter options in tspconfig.yaml.

emit:
- "@typra/emitter"
options:
"@typra/emitter":
emitter-output-dir: "{cwd}/generated"
root-object: "Typra.Fixtures.FixtureRoot"
deterministic-output: true
emit-targets:
- type: TypeScript
output-dir: "generated/typescript"
test-dir: "generated/typescript/tests"
import-path: "../index"
outputs:
- kind: models
- kind: native-serialization
provider: zod
- type: Java
output-dir: "generated/java"
test-dir: "generated/java/tests"
package-name: "typra.fixtures"
- type: Python
output-dir: "generated/python/typra/fixtures"
test-dir: "generated/python/tests"
import-path: "typra.fixtures"
outputs:
- kind: server
provider: fastapi
Option groupOptions
Root selectionroot-object, root-namespace, root-alias, additional-roots, omit-models
Review and safetydeterministic-output, protected-paths, hydration-zones, allow-unsupported-typespec-version
Output shapeemit-targets, namespace-output

root-object is the required anchor for generation. Use a fully qualified model name.

root-namespace is the semantic contract root. When set, Typra resolves models, callables, vectors, and transports from that TypeSpec namespace and preserves nested namespaces under it in the shared IR. root-alias is a naming override for generated root-owned type names; it does not replace target package options.

schema-output-dir is accepted but reserved for future manifest-based cleanup of omitted models. It does not change generated output today.

Typra separates TypeSpec contract identity from target packaging:

ConceptExamplePurpose
Semantic rootroot-namespace: "Typra.Prompty"TypeSpec namespace Typra treats as the durable contract root.
Semantic aliasroot-alias: "Prompty"Optional generated type-name alias for the semantic root name.
Target namespace/packagenamespace, package-name, import-pathRuntime packaging and import ergonomics for a specific target.

Nested TypeSpec namespaces below root-namespace remain part of the lowered model/callable/transport identity. Target renderers then project the semantic namespace through runtime-specific rules. namespace-output defaults to structural, which means targets with module/folder support place nested namespaces in nested output folders. Set namespace-output: flat globally or on a target to keep a flat generated file layout while preserving semantic namespace metadata.

TargetDefault projection
TypeScriptUses the TypeSpec namespace as target metadata, trimming a trailing .Core; nested namespaces emit nested ESM folders and generated tests default to ../src/index.
PythonLowercase dotted package/import path, overrideable with package-name or import-path; nested namespaces emit nested packages.
C#Preserves the TypeSpec namespace unless namespace is configured; nested namespaces emit nested folders.
JavaLowercase dotted package, sanitized for Java package syntax; package-name wins over namespace.
GoFlat lowercase package name because Go has one package per directory; package-name or import-path can override ergonomics.
RustRoot crate import path defaults to crate; nested namespaces emit nested Rust modules.
SwiftRoot namespace becomes a PascalCase module name, overrideable with package-name; nested namespaces emit nested source folders.

The rule of thumb is: TypeSpec namespaces express contract ownership, while target options express runtime packaging. Prefer target overrides when a language ecosystem needs a different package name, not when changing the contract identity.

Each emit-targets entry has a required type and can set target-specific options.

OptionTypical use
output-dirGenerated source output.
test-dirGenerated target tests.
formatBoolean toggle (default true). Runs the target formatter on emitted files when a formatter is available.
namespace-output"structural" or "flat". Defaults to structural and can override the global emitter setting per target.
import-pathImport path used by generated tests or target modules.
package-nameGo, Java, and Swift package or module naming.
namespaceC# namespace, and the Java package when package-name is unset.
aliasTarget aliasing when supported by the emitter.
enum-parsingRust enum parsing mode.
protocol-scaffoldsCompile-only protocol scaffold generation.
outputsInternal output contributor requests identified by kind and optional provider. Existing target generation remains compatible with top-level options.
native-serializationOpt-in native interop surface. TypeScript supports "none" or "zod"; "standard-schema" is reserved and fails fast. Python supports "none" or "pydantic", Java supports "none" or "jackson", Rust supports "none" or "serde", and Swift supports "none" or "codable". Rust keeps its default cfg-gated serde surface when omitted; set "none" to opt out.
cancellation-token-pathFull runtime-native cancellation token symbol path for generated runtimeCancellable method parameters. Rust uses :: paths; Python uses dotted module paths.

protocol-scaffolds: "compile-only" emits test-only implementations that prove generated protocols compile. They intentionally throw or reject when called and are not runtime fakes.

Native serialization is additional interop, not a replacement for Typra’s generated contract. Generated load/save methods remain authoritative for diagnostics, wire names, optional/default semantics, and raw payload preservation.

Native serialization mode support is validated per target. Unsupported combinations emit a TypeSpec diagnostic instead of silently falling back to plain generated output.

outputs is the projection seam for optional surfaces. It validates internal contributor requests and deduplicates compatibility options such as native-serialization. Python supports kind: server with provider: fastapi or provider: starlette, which emits route factories plus generated transport vector tests from TypeSpec HTTP metadata. Python also supports kind: consumer / provider: httpx, which emits contract-specific clients backed by an injected async transport. TypeScript supports kind: consumer / provider: fetch, which emits contract-specific fetch clients and generated consumer vector tests that can call any equivalent HTTP server projection. Unsupported target/kind/provider combinations fail with clear diagnostics instead of silently falling back.

Transport outputs share the same IR semantics: path/query/header/cookie/body bindings come from TypeSpec HTTP decorators, auth requirements are metadata-only, exact declared success statuses select success hydration, and non-matching or non-2xx responses stay on the error seam with their original status/body.