tRPC Integration
Schema-aware transformer with fingerprinting for tRPC
fatline provides a transformer for tRPC that preserves your types and enables schema-aware serialization.
Setup
Server
import { transformer } from 'fatline/trpc'
const t = initTRPC.create({ transformer })
// Dates, Sets, Maps work automatically
export const appRouter = t.router({
getUser: t.procedure.query(() => ({
id: '1',
createdAt: new Date(),
roles: new Set(['admin']),
})),
})Client
import { transformer } from 'fatline/trpc'
const trpc = createTRPCClient<AppRouter>({
transformer,
links: [
httpBatchLink({ url: '/api/trpc' }),
],
})Schema Registry
For type-safe procedures with shared schemas, use a registry:
// packages/schemas/index.ts
import { createRegistry } from 'fatline'
import { z } from 'zod'
export const registry = createRegistry()
export const UserSchema = z.object({
id: z.string(),
createdAt: z.date(),
tags: z.set(z.string()),
})
export const UserCodec = registry.register('user.get', UserSchema)Each registered schema gets a content-based hash:
UserCodec.hash // "a3f2c1b8"Same schema = same hash, regardless of when or where it was compiled. This enables schema verification between client and server.
// Verify schemas match
registry.verify('user.get', 'a3f2c1b8') // true
// Export manifest for distribution
const manifest = registry.export()Custom Types
Register custom types that work across all your tRPC procedures:
import { registerType } from 'fatline'
import Decimal from 'decimal.js'
// Register before creating tRPC context
registerType({
name: 'Decimal',
test: (v): v is Decimal => v instanceof Decimal,
encode: (v) => v.toString(),
decode: (v) => new Decimal(v),
})Now any procedure can return Decimal values and they'll serialize correctly.
oRPC
Similar API for oRPC:
import { FatlineSerializer } from 'fatline/orpc'
const handler = new RPCHandler(router, {
serializer: new FatlineSerializer(),
})Migrating from SuperJSON
- import superjson from 'superjson'
+ import { transformer } from 'fatline/trpc'
const t = initTRPC.create({
- transformer: superjson,
+ transformer,
})Your existing procedures work unchanged.