{"id":46471,"library":"sqlite-nas-sync","title":"sqlite-nas-sync","description":"SQLite database synchronization across multiple clients via NAS using changelog-based conflict resolution. Version 0.9.0, actively maintained. Each client operates on a local SQLite database and synchronizes changes through a shared NAS directory. Key differentiators: automatic table discovery using schema introspection (no manual table list), SQLite trigger-based changelog for incremental sync, Last Write Wins conflict resolution using a timestamp column, support for per-table configuration (timestamp column name, delete protection), heartbeat mechanism to extend changelog retention, and an event system for monitoring sync progress. Requires Node.js >=16 and peer dependency better-sqlite3 >=11.0.0. ESM-only with built-in TypeScript types.","status":"active","version":"0.9.0","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","sqlite","nas","sync","database","conflict-resolution","multi-client","changelog","typescript"],"install":[{"cmd":"npm install sqlite-nas-sync","lang":"bash","label":"npm"},{"cmd":"yarn add sqlite-nas-sync","lang":"bash","label":"yarn"},{"cmd":"pnpm add sqlite-nas-sync","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"peer dependency for SQLite database access","package":"better-sqlite3","optional":true}],"imports":[{"note":"Package is ESM-only; require() will fail. Use dynamic import() or ensure your project is ESM (type: module in package.json).","wrong":"const { setupSync } = require('sqlite-nas-sync')","symbol":"setupSync","correct":"import { setupSync } from 'sqlite-nas-sync'"},{"note":"discoverTables is a named export, not default. Named imports are available from v0.9.0.","wrong":"import discoverTables from 'sqlite-nas-sync'","symbol":"discoverTables","correct":"import { discoverTables } from 'sqlite-nas-sync'"},{"note":"SyncConfig is a TypeScript type; use import type to avoid runtime errors. Available as a type export in v0.9.0.","wrong":"import { SyncConfig } from 'sqlite-nas-sync'","symbol":"SyncConfig","correct":"import type { SyncConfig } from 'sqlite-nas-sync'"}],"quickstart":{"code":"import { setupSync } from 'sqlite-nas-sync';\n\nconst sync = setupSync({\n  dbPath: './data/local.sqlite',\n  nasPath: '/mnt/nas/shared-db/',\n  clientId: 'client-abc123',\n});\n\nawait sync.syncNow().then(result => {\n  console.log(`Inserted: ${result.inserted}, Updated: ${result.updated}`);\n});\n\nsync.start();\n\nsetTimeout(() => sync.stop(), 60000);","lang":"typescript","description":"Initializes a sync instance, performs a manual sync, starts periodic sync, and stops after 60 seconds."},"warnings":[{"fix":"Ensure the NAS filesystem supports O_DIRECT or use a local NAS mount with proper locking.","message":"Synchronization requires a NAS that supports atomic file copy operations. Non-atomic network filesystems may cause corruption.","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Add 'id' (TEXT) and 'updatedAt' columns to tables you want to sync, or use tableOptions to override column names.","message":"In v0.9.0, table discovery was redesigned: tables missing a TEXT primary key named 'id' and a timestamp column named 'updatedAt' are now excluded. Previously, any table with a primary key was included.","severity":"breaking","affected_versions":">=0.9.0"},{"fix":"Remove any autoDetect: false from config. If you need to exclude tables, use the 'excludeTables' option.","message":"The 'autoDetect' option was removed in v0.9.0. Table detection is now automatic and cannot be disabled.","severity":"deprecated","affected_versions":"<0.9.0"},{"fix":"Adjust intervalMs based on your change frequency; monitor disk usage.","message":"Periodic sync interval (intervalMs) default is 30 seconds. Shorter intervals may cause high I/O load on NAS and SQLite WAL file growth.","severity":"gotcha","affected_versions":">=0.0.0"}],"env_vars":null,"search_vec":"'0.9.0':20 '11.0.0':102 '16':95 'across':8 'activ':21 'automat':41 'base':16,54 'better':100 'better-sqlite3':99 'built':108 'built-in':107 'chang':33 'changelog':15,55,83,123 'changelog-bas':14 'client':10,24,122 'column':67,75 'configur':73 'conflict':17,62,118 'conflict-resolut':117 'databas':6,30,116 'delet':77 'depend':98 'differenti':40 'directori':38 'discoveri':43 'esm':104 'esm-on':103 'event':87 'extend':82 'heartbeat':79 'increment':57 'introspect':46 'javascript':112 'key':39 'last':59 'list':50 'local':28 'maintain':22 'manual':48 'mechan':80 'monitor':90 'multi':121 'multi-cli':120 'multipl':9 'name':76 'nas':3,12,37,114 'node.js':94 'oper':25 'peer':97 'per':71 'per-tabl':70 'progress':92 'protect':78 'requir':93 'resolut':18,63,119 'retent':84 'schema':45 'share':36 'sqlite':2,5,29,51,113 'sqlite-nas-sync':1 'sqlite3':101 'support':68 'sync':4,58,91,115 'synchron':7,32 'system':88 'tabl':42,49,72 'timestamp':66,74 'trigger':53 'trigger-bas':52 'type':111 'typescript':110,124 'use':13,44,64 'version':19 'via':11 'win':61 'write':60","created_at":"2026-06-07T13:00:05.399025+00:00","updated_at":"2026-06-07T13:00:05.399025+00:00","problems":[{"fix":"Add proper columns: ALTER TABLE your_table ADD COLUMN id TEXT NOT NULL PRIMARY KEY; ALTER TABLE your_table ADD COLUMN updatedAt TEXT; or set tableOptions for custom column names.","cause":"No table in the database meets the automatic discovery criteria (TEXT primary key 'id' and timestamp column 'updatedAt').","error":"Error: No synchronous tables found in database."},{"fix":"Change to ESM: use import { setupSync } from 'sqlite-nas-sync' or use dynamic import: const { setupSync } = await import('sqlite-nas-sync')","cause":"Using CommonJS require() instead of ESM import. The package is ESM-only and returns undefined when required.","error":"TypeError: Cannot read properties of undefined (reading 'syncNow')"},{"fix":"Run: npm install better-sqlite3","cause":"Missing peer dependency better-sqlite3.","error":"Error: better-sqlite3 is not installed. Please install better-sqlite3 as a dependency."},{"fix":"Ensure the NAS directory exists and is writable: mkdir -p /mnt/nas/shared-db && chmod 755 /mnt/nas/shared-db","cause":"The provided nasPath does not exist or is not writable by the current user.","error":"Error: NAS path is not a directory or not writable."},{"fix":"Drop the existing changelog table: DROP TABLE IF EXISTS _changelog; than re-run setupSync. Note: this will lose pending changes.","cause":"The local changelog table schema does not match the current package version's expected schema.","error":"Error: Changelog table '_changelog' incompatible with version X. Expected schema version Y."}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":null,"github":null,"docs":null,"changelog":null,"pypi":null,"npm":"sqlite-nas-sync","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database","storage"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-07","next_check":"2026-09-05","install_tag":null}}