No More Duplicate Queries
Write the query once. fromTanDbWhere converts TanStack DB expressions, toDrizzle executes them — zero duplication.
TanStack DB on the client, Drizzle on the server. The same user action — search, filter, paginate — produces LoadSubsetOptions on one end and needs Drizzle conditions on the other. agnostic-query bridges them with a portable QuerySchema.
TanStack DB ──fromTanDb──> QuerySchema ──toDrizzle──> Drizzleaq builder ──.toJSON()──> QuerySchema ──toKysely──> KyselyKysely query ──fromKysely──> QuerySchema ──toSql──────> Raw SQLRuntime-agnostic — plain data that work in clients, servers, and edge runtimes. Serialize to JSON, transmit over HTTP, consume on any platform.
Database-agnostic — the same QuerySchema drives Drizzle, Kysely, raw SQL (PostgreSQL), or any future adapter.
Zero dependencies, tree-shakeable — the core has no runtime dependencies; optional peer deps are only loaded when you import that adapter. Unused adapters are eliminated by your bundler.
No More Duplicate Queries
Write the query once. fromTanDbWhere converts TanStack DB expressions, toDrizzle executes them — zero duplication.
Fluent Builder
Chain .where(), .orderBy(), .limit(), .offset() with full TypeScript type safety.
WHERE System
Comparison operators, logical nesting with and/or/not, raw QueryWhere objects, and standalone newWhere() builder.
Database Adapters
Drizzle, Kysely, raw SQL (PostgreSQL), db0, TanStack DB — all from the same QuerySchema.
Runtime Validation
Optional Zod or Valibot schemas for validating QuerySchema at runtime boundaries.
Type Safety
Recursive field paths, operator-dependent value types, and full generic inference across the entire API.
bun add agnostic-queryimport { aq } from 'agnostic-query'
interface User { name: string age: number status: string}
const schema = aq<User>() .where('name', '=', 'Alice') .where('age', '>=', 18) .orderBy('name', 'asc') .limit(20) .toJSON()