stratum-sqlite

Load and query a read-only SQLite database on any static website β€” plain HTML, Quarto, Jekyll, Hugo, and more. No server. No backend. The file is cached in the browser after the first download.

Zero dependencies Works offline after first load Browser Cache API ObservableJS compatible

Live demo

The database below is the countries.sqlite file shipped with this demo. It is fetched once, then served from your browser cache.

⏳ Loading database…

Quick start β€” plain HTML

<!-- 1. Copy sql.js files into your project (see README) -->
<script src="libs/sqljs/sql-wasm.js"></script>
<script src="libs/sqljs/stratum-sqlite.umd.js"></script>

<script type="module">
  const db = await StratumSQLite.open("data/mydb.sqlite", {
    sqlJsPath: "libs/sqljs/",   // where sql-wasm.wasm lives
    cacheKey:  "mydb@v1",       // bump version to force re-download
  });

  const rows = db.query("SELECT * FROM countries");
  console.log(rows);

  const tables = db.tables();   // list all tables
</script>

Quick start β€” Quarto / ObservableJS

Add this block to your project's header.html (included via _quarto.yml). It loads stratum-sqlite via import() and exposes it as a Promise that OJS cells can safely await.

<!-- In header.html β€” loaded on every page via _quarto.yml -->
<script>
(function () {
  var siteLibScript = document.querySelector('script[src*="site_libs/"]');
  var root = siteLibScript
    ? siteLibScript.getAttribute('src').replace(/site_libs\/.*$/, '')
    : '';

  window._sqljsBase = root + 'libs/sqljs/';
  window._dbPath    = root + 'data/mydb.sqlite';

  // Resolve to an absolute URL β€” import() rejects bare relative paths.
  var esmUrl = new URL(window._sqljsBase + 'stratum-sqlite.esm.js',
                       window.location.href).href;

  // OJS cells await this Promise to get the StratumSQLite object.
  window._stratumSQLite = import(esmUrl)
    .then(function (m) { return m.default; });
}());
</script>

// In your .qmd file (OJS cell):
db = {
  const StratumSQLite = await window._stratumSQLite;
  return StratumSQLite.open(window._dbPath, {
    sqlJsPath: window._sqljsBase,
    cacheKey:  "mydb@v1",
  });
}

rows = db.query("SELECT * FROM countries")
Inputs.table(rows)

Hosting your own database

Your SQLite file can live anywhere that serves files with Access-Control-Allow-Origin: *:

For files that change regularly, change the cacheKey version whenever you publish a new release. The old cached file is evicted automatically.