Is SQLite in a Single-Page Web App Production-Ready for Offline-First Use?

0
8
Asked By MellowCedar47 On

I'm planning an offline-first application that needs a relational data model with joins, primary keys, foreign keys, and check constraints. SQLite seems like a better fit than a key-value store such as IndexedDB, so I'm evaluating SQLite WASM with OPFS for browser persistence.

The ecosystem has improved considerably, but there still seem to be important caveats. OPFS support is generally good, although private browsing in some browsers can produce unclear failures. Using SharedArrayBuffer may require COOP and COEP headers, which can also restrict external scripts, stylesheets, and other cross-origin resources. SQLite WASM's concurrency model is more limited than native SQLite, particularly when multiple tabs, workers, or extensions need access to the same database.

A single dedicated database worker and one-tab design might avoid many of these issues. There are also alternatives such as an OPFS VFS with concurrent reads, though browser support may be limited. For anyone who has deployed this approach, is SQLite WASM with OPFS reliable enough for production, and what limitations should I plan around?

3 Answers

Answered By CopperLynx31 On

IndexedDB is still the safer cross-browser fallback because it is a long-established browser storage API with fewer WASM, OPFS, and header-related requirements. It does not provide SQLite’s relational features directly, though, so you would need to model relationships yourself or use a library that adds querying and indexing on top of it.

For a schema involving customers, products, invoices, detail rows, referential integrity, and check constraints, SQLite is much more expressive. I’d consider using SQLite where those guarantees are central, while keeping an IndexedDB-based fallback only if supporting older or more restricted browser environments is important.

Answered By QuietHarbor8 On

SQLite WASM with OPFS is getting close, but the browser is still a less predictable environment than native SQLite. Most current browsers support OPFS, so it can be a reasonable production choice if you test carefully. Private browsing, storage quotas, eviction, and browser-specific failures deserve special attention.

If you want to avoid COOP and COEP, sqlite-wasm can use an SAHPool database. The tradeoff is that the database is effectively locked to one access context, so multiple tabs cannot safely use it. That can work well if the application deliberately uses one database worker and one active tab, and exclusive mode may provide better performance.

Concurrency remains the biggest unresolved issue. SharedWorker would be a natural way to coordinate access, but the required synchronous OPFS handle is not broadly available there yet. New VFS designs can support concurrent reads in some browsers, but they should be treated as browser-specific optimizations rather than a universal solution.

MellowCedar47 -

That matches the design I’m considering: one dedicated database worker and intentionally restricting the app to one tab. In that setup, are storage eviction, quota limits, and private-mode behavior the main remaining production concerns?

Answered By PixelMeadow6 On

There are experimental VFS implementations that support concurrent reads, but some currently target Chrome-specific capabilities. They may be useful for improving a controlled deployment, but I would not base a general multi-browser product on them without a fallback and extensive testing.

A practical architecture is to funnel all database operations through one worker, avoid sharing the database across tabs, handle unavailable or cleared storage gracefully, and make synchronization or backup operations explicit. With those constraints, SQLite WASM and OPFS can be viable for production; without them, the concurrency and browser-behavior edge cases are still significant.

Related Questions

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.