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 Start
Browse example applications on GitHub

The 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.

  1. If the leading SQLite binding is open source, the package uses a patched version of that binding with the native library replaced by SEE.
  2. 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:

  1. The native library is replaced with the SEE native library.
  2. An activateSEE() method, styled for each language, is provided to configure the activation key.
  3. 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.
  4. 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:

  1. Activate SEE once during application or process startup with the activation key.
  2. Open the encrypted database using the keyed open() overload, or using the PRAGMA statement after an unkeyed call to open().
  3. 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 use aes256ofb; if a codec argument is supplied to open(), key(), or rekey(), it must be aes256ofb.

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.