Introduction
What nice-code is — five TypeScript libraries for reliable, type-safe applications.
nice-code is a collection of TypeScript libraries that share a single goal: keep your types intact at every boundary your program crosses — the network, the worker, the storage layer, the catch block.
The packages
Section titled “The packages”| Package | What it does |
|---|---|
@nice-code/action | Transport-agnostic, bi-directional action system with full inference. The headline. |
@nice-code/error | Typed, serializable errors with domain hierarchies and pattern matching. |
@nice-code/state | Immer-backed state container with fine-grained selectors and reactions. |
@nice-code/common-errors | Standard Schema validation errors + Hono middleware. |
@nice-code/util | Typed storage adapters and WebCrypto utilities. |
Start with @nice-code/action — it’s the centre of gravity. The rest compose around it: actions declare the errors they throw using error domains, secure channels use the crypto link from util, validation failures surface as common-errors. But each one stands on its own.
How they fit together
Section titled “How they fit together”// An action declares its input, output, AND the errors it can throw —// all in one shared definition both client and server import.export const userDomain = appRoot.createChildDomain({ domain: "user", actions: { getUser: actionSchema() .input({ schema: v.object({ userId: v.string() }) }) .output({ schema: v.object({ id: v.string(), name: v.string() }) }) .throws(err_user, ["not_found"]), // ← @nice-code/error domain },});
// Call it from anywhere. Output is typed; thrown errors are typed and narrowable.const user = await userDomain.action.getUser .request({ userId: "u_1" }) .runToOutput();What nice-code is not
Section titled “What nice-code is not”- Not a validator. Bring Valibot, Zod, or any Standard Schema library for boundary validation.
- Not an HTTP framework. Actions ride carriers (WebSocket, HTTP, in-memory, WebRTC) and plug into Hono, Workers, Node, Bun, Durable Objects.
- Not magic. Each library is small, readable, and dependency-light.
Continue to the Quick start →