Types from your typespecs
Input, output, and error types are read straight from your Elixir typespecs. No separate schema language, no TypeScript types to keep in sync.
Define procedures in Elixir with ordinary @spec typespecs and a small router DSL. The fully typed TypeScript client is generated from them. No separate schema language, no hand-written TypeScript.
Status: early release (
0.0.1), pre-1.0. APIs may change before 1.0. The HTTP Plug transport and TypeScript codegen are working and tested end-to-end. Realtime transports and framework adapters are not built yet.
Write a handler with a classic @spec:
@spec get_user(%{id: integer()}, RpcElixir.Context.t()) ::
{:ok, %{id: integer(), name: String.t()}} | {:error, :not_found}
def get_user(%{id: id}, _ctx), do: ...Run mix rpc.gen.ts, and call it from the browser with full inference and typed errors:
const user = await client.users.get({ id: 1 });
// ^? { id: number; name: string }That's the whole idea. Your Elixir typespecs are the contract.