WeSearch

Running SQLite in the browser with sql.js and WASM — a practical guide with Google Drive sync

·11 min read · 0 reactions · 0 comments · 1 view
Running SQLite in the browser with sql.js and WASM — a practical guide with Google Drive sync

Most tutorials on client-side data storage reach for IndexedDB, localStorage, or a third-party sync...

Original article
DEV Community
Read full at DEV Community →
Full article excerpt tap to expand

try { if(localStorage) { let currentUser = localStorage.getItem('current_user'); if (currentUser) { currentUser = JSON.parse(currentUser); if (currentUser.id === 546926) { document.getElementById('article-show-container').classList.add('current-user-is-article-author'); } } } } catch (e) { console.error(e); } Deeshan Sharma Posted on Apr 28 Running SQLite in the browser with sql.js and WASM — a practical guide with Google Drive sync #react #javascript #webdev #tutorial Privacy by Architecture (2 Part Series) 1 I tried to build a personal SaaS with zero backend. Here's where that strategy hits a wall. 2 Running SQLite in the browser with sql.js and WASM — a practical guide with Google Drive sync Most tutorials on client-side data storage reach for IndexedDB, localStorage, or a third-party sync service. This one goes somewhere different: a real SQLite database, running as WebAssembly in the browser, with the database file living on the user's own Google Drive. This is the setup behind OvertimeIQ — but everything in this article stands alone as a practical reference. You don't need to care about overtime tracking for any of this to be useful. By the end, you'll know how to: Initialize sql.js and run real SQL in the browser Persist the database across page reloads via localStorage Upload and download the database file from Google Drive Handle sync conflicts correctly Protect against data corruption on interrupted uploads Why SQLite in the browser? Before we write any code, it's worth asking why you'd reach for SQLite instead of IndexedDB or a cloud-synced store. The answer is portability. A SQLite database is a single binary file. You can open it on any device, in any SQLite-compatible tool, without installing anything. You can attach it to an email, drop it in Dropbox, or — as we'll do here — store it on Google Drive. The user owns a file, not a schema locked inside a browser's internal storage. For apps where user data portability matters — personal finance tools, health tracking, anything sensitive — this is a meaningful architectural choice, not just a curiosity. The trade-off: sql.js ships a ~1.5MB WASM binary. We'll deal with that below. Setting up sql.js Install the package: npm install sql.js Enter fullscreen mode Exit fullscreen mode The WASM binary needs to be accessible at a URL your code can load. Copy it into your public folder at build time: // vite.config.js import { defineConfig } from 'vite' import { viteStaticCopy } from 'vite-plugin-static-copy' export default defineConfig({ plugins: [ viteStaticCopy({ targets: [ { src: 'node_modules/sql.js/dist/sql-wasm.wasm', dest: '' } ] }) ] }) Enter fullscreen mode Exit fullscreen mode Now initialise sql.js. This is async — the WASM binary has to load before you can do anything: // lib/db.js import initSqlJs from 'sql.js' let db = null export async function initDB(existingBuffer = null) { const SQL = await initSqlJs({ locateFile: file => `/${file}` // points to /sql-wasm.wasm in public/ }) if (existingBuffer) { // Restore from a saved buffer (localStorage or Drive download) db = new SQL.Database(new Uint8Array(existingBuffer)) } else { // Fresh database db = new SQL.Database() } return db } Enter fullscreen mode Exit fullscreen mode Lazy loading matters here. Don't initialise the database on app load. Initialise it on first access. With a Service Worker caching the WASM binary after the first load, subsequent loads are instant — but you still don't want to block your UI render on a…

This excerpt is published under fair use for community discussion. Read the full article at DEV Community.

Anonymous · no account needed
Share 𝕏 Facebook Reddit LinkedIn Email

Discussion

0 comments

More from DEV Community