PowerSync SDK for Node.js
PowerSync is a sync engine for building local-first apps with instantly-responsive UI/UX and simplified state transfer. Syncs between SQLite on the client-side and Postgres, MongoDB or MySQL on the server-side.
This package (packages/node) is the PowerSync SDK for Node.js clients. It is an extension of packages/common.
Using this package is not necessary for PowerSync on servers, see our documentation for more details on that.
See a summary of features here.
Beta Release
The @powersync/node package is currently in a Beta release.
Installation
Install Package
npm install @powersync/node better-sqlite3
Both @powersync/node and the better-sqlite3 packages have install scripts that need to run to compile
or download sqlite3 and PowerSync binaries.
Common Installation Issues
The 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.
Node-gyp Version Conflicts
better-sqlite depends on node-gyp@^11, but some project configurations may introduce multiple versions of node-gyp, potentially causing build issues.
Python Dependency Issues
node-gyp requires Python for compilation. If your project uses node-gyp below version 10 and your system has Python 3.12 or later, you may encounter the following error:
ModuleNotFoundError: No module named 'distutils'
To resolve this, either:
- Upgrade
node-gypto version 10 or later. - Install Python setuptools, which includes
distutils.
Package better-sqlite3 not found errors
This package does not import better-sqlite3 statically (with unconditional require() or static import statements).
Instead, to allow users to use node:sqlite instead of that package, a dynamic require() / import expression is used.
This may prevent bundlers from detecting that better-sqlite3 is used by this package.
To fix this, ensure you have a dependency on better-sqlite3 (and, if you're using TypeScript, a dev-dependency on
@types/better-sqlite3).
In your project, create a PowerSync.worker.ts file with the following contents:
import Database from 'better-sqlite3';
import { startPowerSyncWorker } from '@powersync/node/worker.js';
async function resolveBetterSqlite3() {
return Database;
}
startPowerSyncWorker({ loadBetterSqlite3: resolveBetterSqlite3 });
Finally, when you open the PowerSyncDatabase, instruct PowerSync to use your custom worker:
const db = new PowerSyncDatabase({
schema: AppSchema,
database: {
dbFilename: 'test.db',
openWorker: (_, options) => {
return new Worker(new URL('./PowerSync.worker.js', import.meta.url), options);
}
},
logger
});
Getting Started
The Node.js SDK reference contains everything you need to know to get started implementing PowerSync in your project.
Examples
A simple example using @powersync/node is available in the demos/example-node/ directory.
Proxy Support
This SDK supports HTTP, HTTPS, and WebSocket proxies via environment variables.
HTTP Connection Method
Internally we probe the http environment variables and apply it to fetch requests (undici)
- Set the
HTTPS_PROXYorHTTP_PROXYenvironment variable to automatically route HTTP requests through a proxy.
WEB Socket Connection Method
Internally the proxy-agent dependency for WebSocket proxies, which has its own internal code for automatically picking up the appropriate environment variables:
- Set the
WS_PROXYorWSS_PROXYenvironment variable to route the webocket connections through a proxy.
Encryption
This package can be used with the better-sqlite3-multiple-ciphers fork of better-sqlite3 for encryption.
This requires a custom worker loading the forked package:
// encryption.worker.ts
import Database from 'better-sqlite3-multiple-ciphers';
import { startPowerSyncWorker } from '@powersync/node/worker.js';
async function resolveBetterSqlite3() {
return Database;
}
startPowerSyncWorker({ loadBetterSqlite3: resolveBetterSqlite3 });
Then, when opening the database, use that custom worker:
const db = new PowerSyncDatabase({
schema: AppSchema,
database: {
dbFilename: 'test.db',
openWorker: (_, options) => {
return new Worker(new URL('./PowerSync.worker.js', import.meta.url), options);
},
initializeConnection: async (db) => {
if (encryptionKey.length) {
const escapedKey = encryptionKey.replace("'", "''");
await db.execute(`pragma key = '${escapedKey}'`);
}
// Make sure the database is readable, this fails early if the key is wrong.
await db.execute('pragma user_version');
}
},
logger
});
Found a bug or need help?
- Join our Discord server where you can browse topics from our community, ask questions, share feedback, or just say hello :)
- Please open a GitHub issue when you come across a bug.
- Have feedback or an idea? Submit an idea via our public roadmap or schedule a chat with someone from our product team.
Thanks
The PowerSync Node.js SDK relies on the work contributors and maintainers have put into the upstream better-sqlite3 package. In particular, we'd like to thank @spinda for contributing support for update, commit and rollback hooks!