Proxy generation
A frontend that calls your commands and queries through hand-written fetch calls drifts from the server the first time someone renames a field. The route changes, a required property becomes optional, and nothing fails until a user clicks the button.
arc-proxygenerator removes that drift. It reads your TypeScript project and writes typed proxies for the published @cratis/arc client: command and query classes, React hooks, models, and the client-safe part of your validators, all with the routes the server serves. Rename a field on the server, regenerate, and the frontend compiler shows you every place that needs to change.
How it works
Section titled “How it works”The generator reads source through the TypeScript compiler API. It never imports or runs your application, and it never talks to a running server. That makes it safe to run in CI and in watch mode, and it means everything it knows comes from your declarations: decorators, @field types, return types, and validator rules.
It walks the artifacts folder with the same rules as builder.discover(), so for_* and given folders, index.ts, and *.proxy.ts files are skipped there too. Route options such as --api-prefix and --segments-to-skip must match the server’s endpoint mapping, because the generator cannot ask the server which routes it chose.
What you receive
Section titled “What you receive”- Commands: a class per command with typed properties,
execute(), the route, client-side validation, and a Reactuse()hook. - Queries: a class per query method, snapshot or observable, with a parameters interface when the query takes arguments, sort helpers, and React hooks including paging.
- Models: classes with
@fieldmetadata, so the client can turn JSON intoGuidvalues, dates, and nested models. A concept arrives as its underlying type. - Identity details: the
detailsTypeof an identity details provider, ready foruseIdentity. - Barrels for separate output: an
index.tsper folder by default when proxies go to a dedicated output folder. Co-located output skips generated barrels. - Server metadata, optionally: with
--metadata, a module the server registers withuseGeneratedMetadatato infer service and argument bindings. See Generated artifact metadata.
What the generator writes shows each of these for the Library sample.
Compatibility
Section titled “Compatibility”The generated proxies target @cratis/arc and @cratis/arc.react 22.45.0 with @cratis/fundamentals, compiled in strict Bundler mode with skipLibCheck: false.
Imports between generated files are extensionless by default, which suits Vite and other bundlers. Use --js-import-specifiers for native Node ESM after compilation. NodeNext consumer compilation is not supported with the published client declarations.
Comparison with .NET 22.45.0
Section titled “Comparison with .NET 22.45.0”The repository’s paired-generator comparison captures actual Cratis.Arc.ProxyGenerator.Build 22.45.0 output for equivalent command, snapshot-query, observable-query, nested/derived model, enum and validation fixtures. Both outputs compile against the pinned browser client and exercise routes, descriptors, hydration, validation and hook signatures.
This is a compatibility check, not a byte-equality promise. Intentional differences include type-only imports, source enum member names (rather than .NET’s camel-cased names), formatting and provenance. The pinned .NET model-bound generator’s query-parameter sorting helpers are a known defect, not an intentional API difference: TypeScript follows the documented contract that sortBy names a read-model field.
TypeScript retains but deprecates sortBy helpers for record, nested-model, array, map, and polymorphic fields until the next major release: in-memory sorting rejects them, database providers apply their own ordering, and you should sort on a scalar field instead; scalar helpers (string, number, boolean, Date, Guid, DateOnly, TimeOnly, TimeSpan, enums, and concepts over those) are unchanged.
The inventory separates intentional differences, known defects and known limitations. Regeneration rejects unreviewed bytes, normalizing only the generated header’s timestamp; offline checks also reject changed C# fixture or .NET option fingerprints. See the contract-test guide for the inventory, behavioral sorting checks and recapture instructions.
Limits
Section titled “Limits”The analyzer keys generated models by namespace and class name, so two Item models in separate folders produce separate files, and generated references use aliased imports if those names collide in one file. An exported class marked @identityDetailsProvider() contributes its detailsType or concrete provide() result model without an HTTP endpoint. Source-only identity provider configuration outside the artifacts root is not analyzed.
For client preferences, @command({ treatWarningsAsErrors: true }) emits the command flag. @query({ httpMethod: QueryHttpMethod.Query, treatWarningsAsErrors: true }) emits setHttpMethod(QueryHttpMethod.Query) and the query flag; import the enum from @cratis/arc.core. Get and Auto are also supported. These settings affect the generated client, not the server’s acceptance of requests. The HTTP server still caps X-Allowed-Severity at Warning. Dynamic decorator options cannot be emitted safely and fail generation.
The output does not reproduce the .NET generator’s templates byte for byte: the file header and import layout differ. Nullable command types and interface-only model mode compile, but have not been compared against a live client. The capability reference tracks what is verified.
Choose your next step
Section titled “Choose your next step”- Set up proxy generation with proxies beside your backend slices; a separate frontend output folder remains an option.
- Use the proxies in React: commands, queries, paging, and live updates.
- Look up what the generator writes, type mapping, and validation rules.
- Adjust configuration when your routes or folder layout differ from the defaults.
For specialized output, see generated artifact metadata, file index tracking, and the low-level manifest for defineCommand and defineQuery.