{"slug": "running-mariadb-in-the-browser-with-webassembly", "title": "Running MariaDB in the Browser with WebAssembly", "summary": "Lite4MariaDB, a new open-source project, compiles MariaDB 13.1 to WebAssembly, enabling a full embedded MariaDB server with InnoDB storage to run in browsers and Node.js without a separate server. The ~17 MB module supports transactions, foreign keys, window functions, CTEs, JSON, and vector search, with data persistence via IndexedDB in browsers or file directories in Node.", "body_md": "# MariaDB, compiled to WebAssembly.Real InnoDB. No server.\n\nA full MariaDB embedded server that runs in the browser and in Node.js, with a PGlite-style JavaScript API. Transactions, foreign keys, window functions, CTEs, JSON and vector search — in one ~17 MB module.\n\n**InnoDB**\n\nTransactions, foreign keys, crash recovery. The real storage engine, not a shim.\n\n**memory · file · idb**\n\nEphemeral by default, a directory in Node, IndexedDB in the browser. Snapshots as gzipped tar.\n\n**MariaDB 13.1**\n\nWindow functions, CTEs, JSON functions and native vector search, unchanged.\n\n**Browser + Node ≥ 18**\n\nMain thread or a worker with the same API. One .wasm module plus a thin wrapper.\n\n``` js\nimport { Lite4MariaDB } from 'lite4mariadb';\n\nconst db = await Lite4MariaDB.create({ dataDir: './my-data' });\n\ndb.exec('CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(64)) ENGINE=InnoDB');\ndb.exec('INSERT INTO users VALUES (?, ?)', [1, \"O'Brien\"]);\n\nconst rows = db.query('SELECT * FROM users WHERE id = ?', [1]);\n// => [ { id: 1, name: \"O'Brien\" } ]\n\nawait db.close();\n```\n\nA datadir that already holds a database is resumed on open — InnoDB recovery runs, and your data is back.\n\n``` js\nimport { Lite4MariaDB } from 'lite4mariadb';\n\n// one IndexedDB database per name\nconst db = await Lite4MariaDB.create({ dataDir: 'idb://my-app' });\n\ndb.exec('CREATE TABLE notes (id INT AUTO_INCREMENT PRIMARY KEY, body TEXT)');\ndb.exec('INSERT INTO notes (body) VALUES (?)', ['hello from the tab']);\n\nawait db.persist();   // hard flush; writes are otherwise debounced\nawait db.close();\n```\n\nThe build uses pthreads, so serve with Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp.\n\n``` js\nimport { Lite4MariaDBWorker } from 'lite4mariadb/worker';\n\n// same API, every method async, main thread stays free\nconst db = await Lite4MariaDBWorker.create({ dataDir: 'idb://my-app' });\n\nconst rows = await db.query('SELECT * FROM users');\nawait db.close();\n```\n\nWorks in Node via worker_threads too. Pass your own Worker running dist/worker-entry.mjs as the second argument to customize loading.\n\n| create(opts?) | memory:// (default), file:// in Node, idb:// in the browser |\n| query(sql, params?) | Rows as objects, coerced JS types |\n| exec(sql, params?) | { ok, affected, rows, fields } |\n| execMulti(sql) | A whole script, one result per statement |\n| transaction(cb) | BEGIN / COMMIT, ROLLBACK on throw |\n| dumpDataDir() | Gzipped tar snapshot, restorable via loadDataDir |\n| close() | Flushes idb:// first |", "url": "https://wpnews.pro/news/running-mariadb-in-the-browser-with-webassembly", "canonical_source": "https://lite4mariadb.shyim.de/", "published_at": "2026-09-02 16:38:59+00:00", "updated_at": "2026-09-02 16:52:34.843326+00:00", "lang": "en", "topics": ["developer-tools", "ai-infrastructure"], "entities": ["MariaDB", "Lite4MariaDB", "WebAssembly", "InnoDB", "IndexedDB", "Node.js"], "alternates": {"html": "https://wpnews.pro/news/running-mariadb-in-the-browser-with-webassembly", "markdown": "https://wpnews.pro/news/running-mariadb-in-the-browser-with-webassembly.md", "text": "https://wpnews.pro/news/running-mariadb-in-the-browser-with-webassembly.txt", "jsonld": "https://wpnews.pro/news/running-mariadb-in-the-browser-with-webassembly.jsonld"}}