{"id":17572,"library":"dexie-encrypted","title":"Dexie Encryption Middleware","description":"dexie-encrypted provides a robust middleware solution for encrypting and decrypting data stored in Dexie.js (IndexedDB wrapper) databases. It transparently handles cryptographic operations, ensuring sensitive information is stored securely at rest within the browser's persistent storage. The current stable version, 2.0.0, is specifically designed for compatibility with Dexie v3.0.0 and newer versions. This library typically follows the release cadence of major Dexie versions and security patches, focusing on stability and integration. Its primary differentiator is its deep integration with Dexie's hook system, allowing developers to add encryption to their existing Dexie projects with minimal code changes by simply importing the library and configuring the encryption key and tables.","status":"active","version":"2.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/mark43/dexie-encrypted","tags":["javascript"],"install":[{"cmd":"npm install dexie-encrypted","lang":"bash","label":"npm"},{"cmd":"yarn add dexie-encrypted","lang":"bash","label":"yarn"},{"cmd":"pnpm add dexie-encrypted","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency; `dexie-encrypted` extends the Dexie prototype and is unusable without a Dexie instance.","package":"dexie","optional":false}],"imports":[{"note":"This import is a side-effect import that globally extends the Dexie.js prototype, adding methods like `encryptedTables()` and `encryptionKey` to all Dexie instances. No direct symbols are exported from the package itself.","wrong":"import { encrypt } from 'dexie-encrypted';","symbol":"Dexie Prototype Extension","correct":"import 'dexie-encrypted';"},{"note":"The core Dexie class from the peer dependency. After `dexie-encrypted` is imported, instances of this class will have the additional encryption-related methods available.","wrong":"const Dexie = require('dexie');","symbol":"Dexie","correct":"import { Dexie } from 'dexie';"},{"note":"Used for type-safe interaction with database tables, including those marked for encryption. The encryption middleware operates at a lower level, but `Table` is crucial for typical Dexie application logic.","wrong":"import { table } from 'dexie';","symbol":"Table","correct":"import { Table } from 'dexie';"}],"quickstart":{"code":"import { Dexie } from 'dexie';\nimport 'dexie-encrypted'; // This extends the Dexie prototype\n\n// In a real application, get your key securely, e.g., from a Web Worker or IndexedDB\n// DO NOT store it directly in your main application code or local storage.\nconst getEncryptionKey = async (): Promise<CryptoKey> => {\n  // For demonstration: generate a new key if not already stored in sessionStorage\n  let storedKey = sessionStorage.getItem('myAppEncryptionKey');\n  if (storedKey) {\n    return crypto.subtle.importKey(\n      'jwk',\n      JSON.parse(storedKey),\n      { name: 'AES-GCM', length: 256 },\n      true,\n      ['encrypt', 'decrypt']\n    );\n  }\n\n  const newKey = await crypto.subtle.generateKey(\n    { name: 'AES-GCM', length: 256 },\n    true,\n    ['encrypt', 'decrypt']\n  );\n  sessionStorage.setItem(\n    'myAppEncryptionKey',\n    JSON.stringify(await crypto.subtle.exportKey('jwk', newKey))\n  );\n  return newKey;\n};\n\nclass MyEncryptedDatabase extends Dexie {\n  users!: Dexie.Table<{ id: number, name: string, secret: string }, number>;\n\n  constructor() {\n    super('MyEncryptedDatabase');\n    this.version(1).stores({\n      users: '++id, name, secret'\n    });\n    // Specify which tables contain encrypted data\n    this.encryptedTables(['users']);\n  }\n}\n\nasync function runEncryptionDemo() {\n  const db = new MyEncryptedDatabase();\n  \n  try {\n    // Set the encryption key. This must be done BEFORE any data operations.\n    db.encryptionKey = await getEncryptionKey();\n\n    // Add an encrypted user\n    const userId = await db.users.add({ id: 1, name: 'Alice', secret: 'Top secret info' });\n    console.log(`Added user with ID: ${userId}`);\n\n    // Retrieve the user. It will be decrypted automatically.\n    const user = await db.users.get(userId);\n    console.log('Retrieved user:', user);\n    console.log('User secret (decrypted):', user?.secret);\n\n    // Verify that the retrieved secret matches the original\n    if (user?.secret === 'Top secret info') {\n      console.log('Encryption and decryption successful!');\n    } else {\n      console.error('Decryption failed or data mismatch.');\n    }\n\n  } catch (error) {\n    console.error('Error during encryption demo:', error);\n  } finally {\n    db.close();\n  }\n}\n\nrunEncryptionDemo();\n","lang":"typescript","description":"Demonstrates initializing a Dexie database with `dexie-encrypted` middleware, setting an encryption key, and performing encrypted `add` and `get` operations for a user record."},"warnings":[{"fix":"Ensure your project's `package.json` specifies `\"dexie\": \"^3.0.0\"` or higher and install dependencies.","message":"Version 2.0.0 of `dexie-encrypted` introduces breaking changes by requiring Dexie.js v3.0.0 or later. Projects using Dexie v2.x must upgrade Dexie before upgrading `dexie-encrypted`.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Implement a secure key management strategy, potentially involving Web Workers, IndexedDB (with caution), or derived keys from user passwords using strong KDFs (Key Derivation Functions) like PBKDF2 or scrypt, never storing the raw key directly.","message":"Proper encryption key management is critical. Storing the encryption key directly in application source code, local storage, or session storage is generally insecure for production environments.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"When modifying schemas, especially for encrypted tables, implement Dexie's `version().upgrade()` methods to handle data transformation and re-encryption if necessary, ensuring backward compatibility or a clear upgrade path.","message":"Changes to your Dexie database schema, particularly adding or removing encrypted fields, require careful migration planning to avoid data loss or corruption. Existing encrypted data might become unreadable if the schema changes without a proper migration strategy.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always ensure that `db.encryptionKey = await getYourSecureKey();` is called and awaited before any `db.table.add()`, `db.table.put()`, or `db.table.get()` calls that involve encrypted tables.","message":"The `db.encryptionKey` must be set *before* performing any database operations on encrypted tables. Forgetting to set the key or setting it too late will result in errors when trying to read or write encrypted data.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Ensure `import 'dexie-encrypted';` is present at the top level of your application entry file or before any Dexie database instance is created and initialized.","cause":"The `dexie-encrypted` side-effect import was either missed or placed incorrectly, preventing the Dexie prototype from being extended.","error":"TypeError: Cannot read properties of undefined (reading 'encrypt') or Property 'encryptedTables' does not exist on type 'Dexie'."},{"fix":"Call `db.encryptionKey = await getYourSecureKey();` and ensure a valid `CryptoKey` instance is assigned before any read/write operations on encrypted tables.","cause":"The `db.encryptionKey` was not set, or it was `null`/`undefined` when an operation on an encrypted table was attempted.","error":"Error: Encryption key missing for table 'yourTableName'."},{"fix":"Verify your schema's primary key (`id`) and indexes are correctly defined. If using client-side generated UUIDs, ensure they are truly unique. Review Dexie's documentation on unique keys and compound indexes.","cause":"Attempting to add or put an item with a duplicate primary key (e.g., `id`) into an encrypted table without proper handling, or the encryption/decryption process is interfering with key uniqueness.","error":"Uncaught (in promise) DOMException: The key 'id' in 'yourTableName' is not unique."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}