Electron
Electron · Tauri · Qt · Flutter · React Native · Capacitor and Ionic · .NET MAUI
Electron applications use the Node package in the main process. The renderer reaches the database through IPC and a preload script. The package, selected runtime and API are those of the Node installation page. No integration is specific to Electron.
Requirements
Section titled “Requirements”Electron 29 or newer, whose main process runs Node 20 or newer, on macOS, GNU/Linux or Windows. Package the application with the runtime package for each target that it ships for. electron-builder and electron-forge include the optional dependencies for the platform that they build for. Those dependencies select the runtime package.
What ships
Section titled “What ships”The JavaScript column of the compatibility matrix, packaged for Electron. Each release runs the quickstart on the platforms in this table. Other platforms have no verification for this integration.
| Platform | Targets | Package |
|---|---|---|
| macOS | macos-arm64, macos-x86_64 | @potluckdb/potluckdb |
| Linux | linux-x86_64-gnu, linux-arm64-gnu | @potluckdb/potluckdb |
| Windows | windows-x86_64, windows-arm64 | @potluckdb/potluckdb |
Install
Section titled “Install”npm install @potluckdb/potluckdbOnly the main process loads the addon in this arrangement. A renderer with nodeIntegration enabled could also load it. Each release tests only the main-process arrangement.
Quickstart
Section titled “Quickstart”The main process opens the database in Electron’s application data directory and creates the table. It answers two IPC calls, which the preload script exposes as window.notes.
- Save both files beside your own
index.html. - Run
electron main.js.
The main process prints quickstart: ok once the window loads.
// potluckdb in the Electron main process: one database, opened where the application keeps its data.// The renderer never loads the addon; it reaches the database through the two IPC calls below.
const path = require("node:path");const { app, BrowserWindow, ipcMain } = require("electron");const potluckdb = require("@potluckdb/potluckdb");
let remote;let db;let quitting = false;let closed = false;let closing = null;
async function openNotes() { const data = app.getPath("userData"); remote = potluckdb.Remote.fromDirectory(path.join(data, "remote")); // a bucket replaces this in production; see the Node installation page db = await potluckdb.open(path.join(data, "notes.potluckdb"), remote); await db.execute("CREATE TABLE IF NOT EXISTS note(id INTEGER PRIMARY KEY, body TEXT NOT NULL)");}
ipcMain.handle("notes:add", (_event, body) => db.execute("INSERT INTO note(body) VALUES(?)", [body]));ipcMain.handle("notes:list", async () => (await db.query("SELECT id, body FROM note ORDER BY id")).rows);
const ready = app.whenReady().then(async () => { await openNotes(); if (quitting) return; const window = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, "preload.js") }, }); await window.loadFile(path.join(__dirname, "index.html")); console.log("quickstart: ok");});
ready.catch((error) => { console.error(error); app.quit();});
app.on("window-all-closed", () => { app.quit(); });
app.on("before-quit", (event) => { if (closed) return; event.preventDefault(); quitting = true; if (closing !== null) return; closing = (async () => { await ready.catch(() => {}); await db?.close(); await remote?.close(); closed = true; app.quit(); })().catch((error) => { // Keep the owners alive; another quit request retries their cleanup. console.error("Database shutdown failed:", error); }).finally(() => { closing = null; });});// The renderer's view of the database: two functions, forwarded to the main process.
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("notes", { add: (body) => ipcRenderer.invoke("notes:add", body), list: () => ipcRenderer.invoke("notes:list"),});Verified by the release
Section titled “Verified by the release”Each release runs this application on macOS, Linux and Windows, writes a note through IPC, and reads the note.