Skip to content

Commit 3c029f6

Browse files
authored
Node.js encryption and updated notes (#273)
* Notes on using Node SDK with encryption * Complete paragraph
1 parent ecb9453 commit 3c029f6

File tree

2 files changed

+111
-8
lines changed

2 files changed

+111
-8
lines changed

client-sdk-references/node.mdx

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,96 @@ logger.setLevel(LogLevel.DEBUG);
204204

205205
## Supported Platforms
206206

207-
See [Supported Platforms -> Node.js SDK](/resources/supported-platforms#node-js-sdk).
207+
See [Supported Platforms -> Node.js SDK](/resources/supported-platforms#node-js-sdk).
208+
209+
## Encryption and custom SQLite drivers
210+
211+
The SDK has an optional dependency on `better-sqlite3` which is used as the default SQLite
212+
driver for that package.
213+
Because that dependency is optional, it can be replaced or removed to customize how SQLite
214+
gets loaded. This section lists common options.
215+
216+
### Encryption
217+
218+
To encrypt databases managed by the PowerSync SDK for Node.js, replace the `better-sqlite3`
219+
dependency with the [`better-sqlite3-multiple-ciphers`](https://www.npmjs.com/package/better-sqlite3-multiple-ciphers) fork.
220+
That package has the same API as `better-sqlite3` while bundling [SQLite3MultipleCiphers](https://github.com/utelle/SQLite3MultipleCiphers)
221+
instead of upstream SQLite.
222+
223+
<Tip>
224+
The [node example](https://github.com/powersync-ja/powersync-js/tree/main/demos/example-node) in the PowerSync
225+
repository can use both `better-sqlite3` and `better-sqlite3-multiple-ciphers` and may be a useful example here.
226+
</Tip>
227+
228+
Because PowerSync attempts to dynamically load `better-sqlite3` at runtime, using a different package
229+
requires patching the database worker. To do that, create a file (say `database.worker.js`) with the following
230+
contents:
231+
232+
```Typescript
233+
// This worker uses bindings to sqlite3 multiple ciphers instead of the original better-sqlite3 worker.
234+
import Database from 'better-sqlite3-multiple-ciphers';
235+
236+
import { startPowerSyncWorker } from '@powersync/node/worker.js';
237+
238+
async function resolveBetterSqlite3() {
239+
return Database;
240+
}
241+
242+
startPowerSyncWorker({ loadBetterSqlite3: resolveBetterSqlite3 });
243+
```
244+
245+
When opening the database, instruct PowerSync to use the custom worker.
246+
Also use the `initializeConnection` option to install an ecryption key:
247+
248+
```Typescript
249+
const encryptionKey = 'todo: generate encryption key and store it safely';
250+
251+
const db = new PowerSyncDatabase({
252+
schema: AppSchema,
253+
database: {
254+
dbFilename: 'app.db',
255+
openWorker: (_, options) => {
256+
return new Worker(new URL('./database.worker.js', import.meta.url), options);
257+
},
258+
initializeConnection: async (db) => {
259+
if (encryptionKey.length) {
260+
const escapedKey = encryptionKey.replace("'", "''");
261+
await db.execute(`pragma key = '${escapedKey}'`);
262+
}
263+
264+
// Make sure the database is readable, this fails early if the key is wrong.
265+
await db.execute('pragma user_version');
266+
}
267+
},
268+
logger
269+
});
270+
```
271+
272+
<Note>
273+
If you're using a custom compilation toolchain, for instance because you're compiling from TypeScript
274+
or are applying a bundler to your project, loading workers may require additional configuration on that
275+
toolchain.
276+
</Note>
277+
278+
### `node:sqlite`
279+
280+
Recent versions of Node.js contain an [experimental SQLite API](https://nodejs.org/api/sqlite.html).
281+
Using the builtin SQLite API can reduce code size and external native dependencies. To enable it,
282+
remove your dependency on `better-sqlite3` and configure PowerSync to use the builtin APIs:
283+
284+
```JavaScript
285+
const database = new PowerSyncDatabase({
286+
schema: AppSchema,
287+
database: {
288+
dbFilename: 'app.db',
289+
dbLocation: directory,
290+
// Use node:sqlite instead of better-sqlite3
291+
implementation: { type: 'node:sqlite' }
292+
}
293+
});
294+
```
295+
296+
<Danger>
297+
There are stability issues when using PowerSync with this API, and it's not recommended outside of
298+
testing purposes at the moment.
299+
</Danger>

snippets/node/installation.mdx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,43 @@ Add the [PowerSync Node NPM package](https://www.npmjs.com/package/@powersync/no
2020
</Tab>
2121
</Tabs>
2222

23-
**Required peer dependencies**
24-
25-
This SDK requires [`@powersync/better-sqlite3`](https://www.npmjs.com/package/@powersync/better-sqlite3) as a peer dependency:
23+
**Peer dependencies**
24+
25+
The PowerSync SDK for Node.js supports multiple drivers. More details are available under [encryption and custom drivers](/client-sdk-references/node#encryption-and-custom-sqlite-drivers),
26+
we currently recommend the `better-sqlite3` package for most users:
2627

2728
<Tabs>
2829
<Tab title="npm">
2930
```bash
30-
npm install @powersync/better-sqlite3
31+
npm install better-sqlite3
3132
```
3233
</Tab>
3334

3435
<Tab title="yarn">
3536
```bash
36-
yarn add @powersync/better-sqlite3
37+
yarn add better-sqlite3
3738
```
3839
</Tab>
3940

4041
<Tab title="pnpm">
4142
```bash
42-
pnpm install @powersync/better-sqlite3
43+
pnpm install better-sqlite3
4344
```
4445
</Tab>
4546
</Tabs>
4647

48+
<Warning>
49+
Previous versions of the PowerSync SDK for Node.js used the `@powersync/better-sqlite3` fork as a
50+
required peer dependency.
51+
This is no longer recommended. After upgrading to `@powersync/node` version `0.12.0` or later, ensure
52+
the old package is no longer installed by running `@powersync/better-sqlite3`.
53+
</Warning>
54+
4755
**Common installation issues**
4856

49-
The `@powersync/better-sqlite` package requires native compilation, which depends on certain system tools. This compilation process is handled by `node-gyp` and may fail if required dependencies are missing or misconfigured.
57+
The `better-sqlite` package requires native compilation, which depends on certain system tools.
58+
Prebuilt assets are available and used by default, but a custom compilation may be started depending on the Node.js
59+
or Electron version used.
60+
This compilation process is handled by `node-gyp` and may fail if required dependencies are missing or misconfigured.
5061

5162
Refer to the [PowerSync Node package README](https://www.npmjs.com/package/@powersync/node) for more details.

0 commit comments

Comments
 (0)