npm: @powersync/kysely-driver

This package enables using Kysely with PowerSync React Native and web SDKs.

It gives JavaScript developers the flexibility to write queries in either JavaScript/TypeScript or SQL, and provides type-safe imperative APIs.

Setup

Set up the PowerSync Database and wrap it with Kysely.

JavaScript Setup

import { wrapPowerSyncWithKysely } from '@powersync/kysely-driver';
import { PowerSyncDatabase } from '@powersync/web';

// Define schema as in: https://docs.powersync.com/usage/installation/client-side-setup/define-your-schema
import { appSchema } from './schema';

export const powerSyncDb = new PowerSyncDatabase({
  database: {
    dbFilename: 'test.sqlite'
  },
  schema: appSchema
});

export const db = wrapPowerSyncWithKysely(powerSyncDb);

TypeScript Setup

import { wrapPowerSyncWithKysely } from '@powersync/kysely-driver';
import { PowerSyncDatabase } from "@powersync/web";

// Define schema as in: https://docs.powersync.com/usage/installation/client-side-setup/define-your-schema
import { appSchema, Database } from "./schema";

export const powerSyncDb = new PowerSyncDatabase({
  database: {
    dbFilename: "test.sqlite"
  },
  schema: appSchema,
});

// `db` now automatically contains types for defined tables
export const db = wrapPowerSyncWithKysely<Database>(powerSyncDb)

For more information on Kysely typing, see their documentation.

Usage Examples

Below are examples comparing Kysely and PowerSync syntax for common database operations.

Select Operations

const result = await db.selectFrom('users').selectAll().execute();

// [{ id: '1', name: 'user1' }, { id: '2', name: 'user2' }]

Insert Operations

await db.insertInto('users').values({ id: '1', name: 'John' }).execute();
const result = await db.selectFrom('users').selectAll().execute();

// [{ id: '1', name: 'John' }]

Delete Operations

await db.insertInto('users').values({ id: '2', name: 'Ben' }).execute();
await db.deleteFrom('users').where('name', '=', 'Ben').execute();
const result = await db.selectFrom('users').selectAll().execute();

// []

Update Operations

await db.insertInto('users').values({ id: '3', name: 'Lucy' }).execute();
await db.updateTable('users').where('name', '=', 'Lucy').set('name', 'Lucy Smith').execute();
const result = await db.selectFrom('users').select('name').executeTakeFirstOrThrow();

// 'Lucy Smith'

Watched Queries

For watched queries with Kysely it’s recommended to use the watch() function from the wrapper package which takes in a Kysely query.

const query = db.selectFrom('users').select();

db.watch(query, {
  onResult(results) {
    console.log(results);
  },
});

// [{ id: '1', name: 'John' }]

Transactions

await db.transaction().execute(async (transaction) => {
  await transaction.insertInto('users').values({ id: '4', name: 'James' }).execute();
  await transaction.updateTable('users').where('name', '=', 'James').set('name', 'James Smith').execute();
});
const result = await db.selectFrom('users').select('name').executeTakeFirstOrThrow();

// 'James Smith'