Key factors in comparing SQLite web implementations
Comparison of leading implementations and VFSs supported
Recommendations on best implementations to use
Expected baseline performance/throughput
10 key performance optimizations to consider
Performance optimizations included in our sqlite_async library
Using a SQLite database to manage state
Example to-do list app
Link to video talk on this topic
Background on performance benchmarking methodology used
Performance comparison of sqlite_async, sqflite, Isar and ObjectBox
Link to GitHub project with performance benchmarking code
Configurability refers to the library’s flexibility in allowing developers to customize its behavior and functionality to meet specific application needs. This includes access to compiler options, using a good set of default extensions and catering for extension loading.
Consistency ensures the library has consistent options across various platforms, capabilities should be consistent across platforms with sensible default settings and cross-platform SDKs should directly access the C API without converting to another language first.
Capability evaluates the libraries inclusion of a comprehensive transaction API, exposure of all possible parameter types and good to have functionality such as update hooks (used for watching for changes), prepared statements and creating user-defined functions.
We recommend sqlite_async because it wraps the sqlite3 Dart bindings and configures the database with a good set of defaults, with all database calls being asynchronous to avoid blocking the UI.
While it does not expose compiler options, it does cater for loading various extensions. It also ensures that core SQLite functionality is consistent across all platforms supported by the library.
For performance-sensitive tasks, transactions are asynchronous and concurrent by default (multiple read and single write) by using a pool of connections, each running in a separate Isolate. Allows the use of SQL queries directly, making complex queries easier, and does not require any code generation. Allows access to the underlying sqlite3 library when high-performance low-level access is required. Allows the use of Drift when an ORM is required.
wa-sqlite leverages WebAssembly (Wasm), allowing SQLite to run efficiently in web browser environments. The Wasm build is highly customizable by providing access to compiler options and having a good set of default options, however, it does not enable extension loading by default.
This Wasm build of SQLite supports writing to SQLite virtual file systems (VFS) completely in JavaScript and allows for alternative browser storage options such as IndexedDB and Origin Private File System (OPFS). Both the synchronous and asynchronous builds use the same set of default options and provide a consistent way to access the SQLite C API through JavaScript wrappers.
It does not provide an easy-to-use transaction API. It requires manual setup for concurrent read transactions. It does not include any update or commit hooks. Both builds allow the use of SQL queries directly, and support the use of prepared statements.
op-sqlite provides a low-level API for executing SQL queries within React Native. It provides access to compiler options configurable through the package.json file and caters for loading additional extensions.
It provides a consistent set of options across compatible platforms and direct access to the SQLite C API through JavaScript. It provides a comprehensive transaction API, exposes multiple parameter types and includes update hooks for various operations such as table or row updates. It also has support for prepared statements out of the box.
While it does not have the niceties of an ORM, it has a smaller footprint resulting in a smaller app size and better performance.
SQLDelight is one the few SQLite drivers that supports Kotlin Multiplatform and is used in almost all KMP samples and showcase apps. It does not expose many compiler options but does however include some good defaults that make extension loading possible. The library shows consistent performance across various platforms when compiling for KMP. It does not allow direct access to the SQLite C API which is provided by the SQLiter library under the hood. SQDelight does however have a rich SQLite API which generates type-safe Kotlin APIs from SQL which makes writing and maintaining SQL statements much easier. It does support querying the database asynchronously and allows the database to be configured for concurrent read transactions (using WAL mode).
View library