skills/powersync/references/sdks/powersync-js-orm.md

98 lines
3.0 KiB
Markdown

---
name: powersync-js-orm
description: Drizzle and Kysely ORM integration with PowerSync JavaScript SDK — type-safe queries, schema definition, and CompilableQuery usage
metadata:
tags: javascript, typescript, drizzle, kysely, orm, powersync
---
> **Load this when** the project uses Drizzle or Kysely ORM with PowerSync. Always load `powersync-js.md` first.
# Drizzle & Kysely ORM Integration
PowerSync provides official drivers for both Drizzle and Kysely. These let you write type-safe queries that work with PowerSync's reactive hooks (`useQuery`, `useSuspenseQuery`) via the `CompilableQuery` interface.
| ORM | Package | Docs |
|-----|---------|------|
| Drizzle | `@powersync/drizzle-driver` | [Drizzle Setup](https://docs.powersync.com/client-sdks/orms/javascript-web/drizzle.md) |
| Kysely | `@powersync/kysely-driver` | [Kysely Setup](https://docs.powersync.com/client-sdks/orms/javascript-web/kysely.md) |
## Drizzle
```bash
npm install @powersync/drizzle-driver@latest drizzle-orm
```
```ts
import { drizzle } from '@powersync/drizzle-driver';
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
import { eq } from 'drizzle-orm';
// Define Drizzle schema — separate from the PowerSync schema
export const todos = sqliteTable('todos', {
id: text('id').primaryKey(),
description: text('description').notNull(),
completed: integer('completed').notNull().default(0),
listId: text('list_id')
});
// Create Drizzle instance from the PowerSync database
const drizzleDb = drizzle(db);
// Type-safe queries
const activeTodos = await drizzleDb
.select()
.from(todos)
.where(eq(todos.completed, 0));
```
### Drizzle with useQuery
Drizzle queries implement `CompilableQuery`, so they work directly with PowerSync hooks:
```ts
const query = drizzleDb.select().from(todos).where(eq(todos.completed, 0));
const { data } = useQuery(query);
```
## Kysely
```bash
npm install @powersync/kysely-driver@latest kysely
```
```ts
import { wrapPowerSyncWithKysely } from '@powersync/kysely-driver';
// Define types for Kysely
interface Database {
todos: { id: string; description: string; completed: number; list_id: string };
lists: { id: string; name: string; owner_id: string };
}
// Create Kysely instance from the PowerSync database
const kyselyDb = wrapPowerSyncWithKysely<Database>(db);
// Type-safe queries
const activeTodos = await kyselyDb
.selectFrom('todos')
.selectAll()
.where('completed', '=', 0)
.execute();
```
### Kysely with useQuery
```ts
const query = kyselyDb.selectFrom('todos').selectAll().where('completed', '=', 0);
const { data } = useQuery(query);
```
## Both schemas are needed
You need **two** schemas when using an ORM:
1. **PowerSync schema** (`new Schema(...)`) — defines what data syncs. Required.
2. **ORM schema** (Drizzle `sqliteTable` or Kysely interface) — provides type safety for queries. Optional but recommended.
These must stay in sync — if you add a column to the PowerSync schema, add it to the ORM schema too.