Skip to content

LensType-safe, real-time API framework

GraphQL-like power with automatic live queries and incremental transfer. No codegen required.

Quick Example

typescript
// Server: Define your API
const appRouter = router({
  user: {
    get: query()
      .input(z.object({ id: z.string() }))
      .resolve(({ input, ctx }) => ctx.db.user.find(input.id)),

    update: mutation()
      .input(z.object({ id: z.string(), name: z.string() }))
      .resolve(({ input, ctx }) => ctx.db.user.update(input)),
  },
})

// Client: One-time fetch
const user = await client.user.get({ id: '123' })

// Client: Subscribe to live updates
client.user.get({ id: '123' }).subscribe((user) => {
  console.log('User updated:', user)  // Called whenever data changes
})

The Lens Approach

Traditional frameworks require separate endpoints for queries and subscriptions. With Lens, every query is automatically a subscription:

PatternTraditionalLens
One-time fetchawait trpc.getUser({ id })await client.user.get({ id })
Real-timeSeparate subscription endpointSame endpoint with .subscribe()
Partial updatesManual implementationAutomatic with field selection

Released under the MIT License.