This repo contains the templates used by the webrpc-gen cli to code-generate
webrpc Typescript server and client code.
This generator, from a webrpc schema/design file will code-generate:
-
Client -- an isomorphic/universal Typescript client to speak to a webrpc server using the provided schema. This client is compatible with any webrpc server language (ie. Go, nodejs, etc.). As the client is isomorphic, means you can use this within a Web browser or use the client in a server like nodejs -- both without needing any dependencies. I suggest to read the generated TS output of the generated code, and you shall see, its nothing fancy, just the sort of thing you'd write by hand.
-
Server -- a nodejs Typescript server handler. See examples.
The generated client includes a queryKey property with type-safe query key generators for each endpoint. This makes it easy to use with popular data-fetching libraries:
import { useQuery } from '@tanstack/react-query'
import { Example } from './client.gen'
const client = new Example('http://localhost:3000', fetch)
function UserProfile({ userId }) {
const { data } = useQuery({
queryKey: client.queryKey.getUser({ userId }),
queryFn: ({ signal }) => client.getUser({ userId }, undefined, signal)
})
return <div>{data?.user.name}</div>
}The query keys follow the pattern [ServiceName, methodName, request?] and are fully type-safe with as const assertions.
TypeScript best practices are moving away from enum declarations — they emit runtime
code that can't be erased, which is incompatible with the erasableSyntaxOnly tsconfig
option and tooling that expects type-only syntax to disappear at build time.
The -enumStyle option lets you choose how schema enums are code-generated:
-enumStyle value |
Output |
|---|---|
enum (default) |
Traditional TypeScript export enum |
union |
as const object + union type (erasable, no runtime enum) |
Given this schema:
enum Kind: uint32
- USER
- ADMIN
enum Intent: string
- openSession
- closeSession
-enumStyle=enum (default) generates:
export enum Kind {
USER = 'USER',
ADMIN = 'ADMIN'
}
export enum Intent {
openSession = 'openSession',
closeSession = 'closeSession'
}-enumStyle=union generates:
export const Kind = {
USER: 'USER',
ADMIN: 'ADMIN',
} as const
export type Kind = (typeof Kind)[keyof typeof Kind]
export const Intent = {
openSession: 'openSession',
closeSession: 'closeSession',
} as const
export type Intent = (typeof Intent)[keyof typeof Intent]The union style produces a value (the const object) and a type that share the same
name, so it's mostly a drop-in replacement anywhere the enum was used — function
parameters, interface fields, and client/server code all reference the type by the same
identifier. You still get autocompletion and access to members via Kind.USER, and
nothing is left behind at runtime beyond a plain object.
There are two behavioral differences from a real enum to be aware of:
- No reverse mapping for numeric enums. A numeric TypeScript
enumlets you look up a member name by its value (WebrpcErrorCodes[1000]→'Unauthorized'). Aconstobject has no reverse entries, soWebrpcErrorCodes[1000]isundefined. Consumer code that maps an error code back to its name this way must be updated. (Schema enums are unaffected — they are generated with string values regardless of their backing type.) - Members can't be used directly as types. With an
enumyou can writetype T = Kind.USER. In theunionstyleKind.USERis a value, so usetype T = typeof Kind.USERinstead.
Passing any value other than enum or union (e.g. -enumStyle=foo) prints an error and exits.
webrpc-gen -schema=example.ridl -target=typescript -server -client -out=./example.gen.ts
or
webrpc-gen -schema=example.ridl -target=github.com/webrpc/gen-typescript@v0.7.0 -server -client -out=./example.gen.ts
or
webrpc-gen -schema=example.ridl -target=./local-templates-on-disk -server -client -out=./example.gen.ts
As you can see, the -target supports default typescript, any git URI, or a local folder :)
Change any of the following values by passing -option="Value" CLI flag to webrpc-gen.
| webrpc-gen -option | Description | Default value | Version |
|---|---|---|---|
-client |
generate client code | false |
v0.0.1 |
-server |
generate server code | false |
v0.0.1 |
-webrpcHeader |
send Webrpc header in all HTTP requests | true |
v0.15.0 |
-schemaHash=false |
don't emit schema hash + version consts | true |
v0.28.0 |
-enumStyle |
enum codegen style: enum or union |
enum |
v0.29.0 |
Note: Generated code requires ES2022+ runtime environment.