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.
Live demo
The database below is the countries.sqlite file shipped with
this demo. It is fetched once, then served from your browser cache.
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: *:
- GitHub Releases β free, unlimited size, CORS-enabled
- GitHub Pages β same origin, no CORS header needed
- Zenodo / Figshare / OSF β public data repositories
- Cloudflare R2 / AWS S3 β set a bucket CORS policy
For files that change regularly, change the cacheKey version
whenever you publish a new release. The old cached file is evicted automatically.