SQLite.Encrypted Packages
SQLite.Encrypted is a collection of packages that include native builds of the official SQLite Encryption Extension (SEE) library. Most packages also include a binding that makes SEE easy to use from a particular language, framework, or ecosystem. The goal of this project is to reduce any friction that would prevent securing important data.
Not sure which package to choose?
Quick StartThe guiding principle is that each package should fit naturally into its ecosystem. When a package contains a wrapper, its API should match the leading SQLite binding for that platform or toolkit as closely as possible. Because SEE requires a custom build of the underlying native SQLite library, every package includes the appropriate SEE native library.
- If the leading SQLite binding is open source, the package uses a patched version of that binding with the native library replaced by SEE.
- If that is not workable, the package provides an API-compatible binding implemented with the SEE native library.
Where a package includes a binding, the main adaptations are:
- The native library is replaced with the SEE native library.
- An activateSEE() method, styled for each language, is provided to configure the activation key.
- An overload is provided for the database open() method to allow providing an encryption key. The overload applies the key through the binding's
key()implementation and reports any key-loading failure. - Add connection-level key() and rekey() methods, styled for each language, and providing string vs binary key overloads where possible.
These docs cover the SEE-specific changes made by each package. Use upstream documentation for ordinary database APIs and the package guides linked below for installation, signatures, targets, and compatibility limits.
1. Integration and security
Packages at a glance
| Package | Upstream baseline | Package identifier | Targets |
|---|---|---|---|
| .NET / NuGet | SQLitePCLRaw and managed SQLite providers that load e_sqlite3 |
SQLite.Encrypted |
Windows, macOS, Linux, Android, iOS |
| Android | SQLite Android binding API | org.sqlite.encrypted:sqlite3 |
Android API 21+ |
| Apple | SQLite.swift 0.16.0 | SQLiteEncrypted Swift package |
iOS, macOS, Mac Catalyst |
| JDBC | Xerial SQLite JDBC 3.53.4.0 | org.sqlite.encrypted:sqlite-jdbc |
Windows x64; macOS x64/ARM64; Linux x64 |
| Node.js | node:sqlite, Node 22 LTS |
@sqlite-encrypted/node |
Windows x64; macOS x64/ARM64; Linux glibc x64/ARM64 |
| Cordova and Capacitor | cordova-sqlite-storage 7.0.0 |
@sqlite-encrypted/cordova |
Android, iOS; Capacitor-compatible |
| React Native | react-native-sqlite-storage 6.0.1 |
@sqlite-encrypted/react-native |
Android, iOS |
| Expo | expo-sqlite 56.0.5 |
@sqlite-encrypted/expo |
Android, iOS; web is not SEE-backed |
| Flutter | sqflite 2.4.3 |
sqlite_encrypted in the SQLite.Encrypted Pub repository |
Android, iOS, Windows x64/ARM64, macOS x64/ARM64, Linux x64/ARM64 |
In your application, this sequence is important:
- Activate SEE once during application or process startup with the activation key.
- Open the encrypted database using the keyed open() overload, or using the PRAGMA statement after an unkeyed call to open().
- Perform schema access only after the key has been provided.
Core rule: Activate SEE before the first encrypted open, and apply the database key before any schema query or migration runs.
Codec support: SQLite.Encrypted currently supports only
aes256ofb. Omit the codec or pass null to useaes256ofb; if a codec argument is supplied toopen(),key(), orrekey(), it must beaes256ofb.
SEE activation is process-scoped and idempotent. Activation is still required before loading a key, but keyed opens rely on the native key() result. During open, if the key() call fails, the open will fail. A keyless open remains available for plaintext databases where supported. All supported native SQLite.Encrypted packages retain the PRAGMA activate_extensions and PRAGMA key sequence. Expo web retains the upstream web implementation and is not SEE-backed.
Prefer a keyed open() overload, or open a connection and immediately call its explicit key() method. Both paths report a failed native key operation. Use the PRAGMA form primarily for compatibility with existing integrations. A successful SEE key PRAGMA returns one row containing ok; no row means the key was not loaded. Code that ignores that result can continue using a connection whose encryption key was never applied and may create or modify a plaintext database.
The connection-level key and rekey APIs accept a database name and optional aes256ofb codec. Text-key overloads use SEE's null-terminated text convention; byte-key overloads preserve the exact byte sequence and length. A null key passes pKey = NULL and nKey = 0, which removes database encryption. Flutter, which does not support overloads, names the binary forms keyBytes and rekeyBytes. Expo follows its upstream sync/async naming and provides keySync, keyAsync, rekeySync, and rekeyAsync.
Keys and secrets: The activation key licenses SEE for the process; the database key encrypts a database or backup. Where possible, retrieve both from a secret store. Never hard-code, log, or store them beside the database.
2. Adoption and release verification
Moving from upstream
Replace the upstream dependency with the SQLite.Encrypted package intended for the same ecosystem. Remove packages that contribute a competing SQLite native module or library. Activate SEE before database services, migrations, background tasks, or connection pools can open an encrypted database.
Add a key only to encrypted opens; do not use an empty string to represent plaintext.
Upstream documentation remains authoritative for transactions, statements, queries, and other unchanged APIs. SQLite.Encrypted documentation focuses on SEE activation, encrypted opens, native packaging, compatibility exceptions, and SEE-specific failures.
Packaging, licensing, and versions
SQLite.Encrypted packages derive their native libraries from a selected SQLite.Encrypted release. Packages containing SQLite.Encrypted binaries are proprietary. Included upstream licenses and third-party notices apply only to their respective components and do not relicense SEE. Preserve the notices when redistributing an application or package.
Artifact names should preserve the complete SQLite.Encrypted version. If an ecosystem permits only three numeric SemVer components, a fourth native component may be represented as build metadata. Release notes should document that mapping so the runtime remains traceable to its source package.