> ## Documentation Index
> Fetch the complete documentation index at: https://docs.powersync.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kysely

> Use the Kysely query builder with PowerSync's JavaScript and React Native SDKs.

<Card title="npm: @powersync/kysely-driver" icon="npm" href="https://www.npmjs.com/package/@powersync/kysely-driver" horizontal />

This package enables using [Kysely](https://kysely.dev/) 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

```js theme={null}
import { wrapPowerSyncWithKysely } from '@powersync/kysely-driver';
import { PowerSyncDatabase } from '@powersync/web';

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

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

export const db = wrapPowerSyncWithKysely(powerSyncDb);
```

### TypeScript Setup

```js theme={null}
import { wrapPowerSyncWithKysely } from '@powersync/kysely-driver';
import { PowerSyncDatabase } from "@powersync/web";

// Define schema as in: https://docs.powersync.com/intro/setup-guide#define-your-client-side-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](https://kysely.dev/docs/getting-started#types).

## Usage Examples

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

### Select Operations

<CodeGroup>
  ```js Kysely theme={null}
  const result = await db.selectFrom('users').selectAll().execute();

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

  ```js PowerSync theme={null}
  const result = await powerSyncDb.getAll('SELECT * from users');

  // [{ id: '1', name: 'user1' }, { id: '2', name: 'user2' }]
  ```
</CodeGroup>

### Insert Operations

<CodeGroup>
  ```js Kysely theme={null}
  await db.insertInto('users').values({ id: '1', name: 'John' }).execute();
  const result = await db.selectFrom('users').selectAll().execute();

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

  ```js PowerSync theme={null}
  await powerSyncDb.execute('INSERT INTO users (id, name) VALUES(1, ?)', ['John']);
  const result = await powerSyncDb.getAll('SELECT * from users');

  // [{ id: '1', name: 'John' }]
  ```
</CodeGroup>

### Delete Operations

<CodeGroup>
  ```js Kysely theme={null}
  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();

  // []
  ```

  ```js PowerSync theme={null}
  await powerSyncDb.execute('INSERT INTO users (id, name) VALUES(2, ?)', ['Ben']);
  await powerSyncDb.execute(`DELETE FROM users WHERE name = ?`, ['Ben']);
  const result = await powerSyncDb.getAll('SELECT * from users');

  // []
  ```
</CodeGroup>

### Update Operations

<CodeGroup>
  ```js Kysely theme={null}
  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'
  ```

  ```js PowerSync theme={null}
  await powerSyncDb.execute('INSERT INTO users (id, name) VALUES(3, ?)', ['Lucy']);
  await powerSyncDb.execute('UPDATE users SET name = ? WHERE name = ?', ['Lucy Smith', 'Lucy']);
  const result = await powerSyncDb.get('SELECT name FROM users WHERE name = ?', ['Lucy Smith'])

  // 'Lucy Smith'
  ```
</CodeGroup>

### 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.

<CodeGroup>
  ```js Kysely theme={null}
  const query = db.selectFrom('users').selectAll();

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

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

  ```js PowerSync theme={null}
  powerSyncDb.watch("select * from users", [], {
    onResult(results) {
      console.log(results.rows?._array);
    },
  });

  // [{ id: '1', name: 'John' }]
  ```
</CodeGroup>

### Transactions

<CodeGroup>
  ```js Kysely theme={null}
  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'
  ```

  ```js Kysely with Raw SQL theme={null}
  await db.transaction().execute(async (transaction) => {
    await sql`INSERT INTO users (id, name) VALUES ('4', 'James');`.execute(transaction)
    await transaction.updateTable('users').where('name', '=', 'James').set('name', 'James Smith').execute();
  });
  const result = await db.selectFrom('users').select('name').executeTakeFirstOrThrow();

  // 'James Smith'
  ```

  ```js PowerSync theme={null}
  await powerSyncDb.writeTransaction((transaction) => {
    await transaction.execute('INSERT INTO users (id, name) VALUES(4, ?)', ['James']);
    await transaction.execute("UPDATE users SET name = ? WHERE name = ?", ['James Smith', 'James']);
  })
  const result = await powerSyncDb.get('SELECT name FROM users WHERE name = ?', ['James Smith'])

  // 'James Smith'
  ```
</CodeGroup>
