{"id":16509,"library":"react-indexed-db-hook","title":"React IndexedDB Hook","description":"The `react-indexed-db-hook` package provides a React hook-based abstraction over the browser's native IndexedDB API. It simplifies common database operations like initializing the database, creating object stores, and performing CRUD operations (add, get, update, delete) within React components. The current stable version is 1.0.14, last published over three years ago, indicating a slower release cadence, likely in maintenance mode rather than active development with new features. It aims to make the powerful, asynchronous, and transactional IndexedDB API more accessible to React developers, offering a more robust client-side storage solution than `localStorage` for larger, structured datasets, and enabling offline-first application capabilities.","status":"maintenance","version":"1.0.14","language":"javascript","source_language":"en","source_url":"https://github.com/assuncaocharles/react-indexed-db","tags":["javascript","indexed","db","indexeddb","websql","sql","indexed-db","database","react","typescript"],"install":[{"cmd":"npm install react-indexed-db-hook","lang":"bash","label":"npm"},{"cmd":"yarn add react-indexed-db-hook","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-indexed-db-hook","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for all React-based libraries.","package":"react","optional":false},{"reason":"Peer dependency required for rendering React components.","package":"react-dom","optional":false}],"imports":[{"note":"Used once at application startup to configure IndexedDB database name, version, and object stores (schemas). It is a named import.","wrong":"import initDB from 'react-indexed-db-hook';","symbol":"initDB","correct":"import { initDB } from 'react-indexed-db-hook';"},{"note":"The primary React hook for interacting with a specific IndexedDB object store. It provides methods for CRUD operations.","wrong":"import useIndexedDB from 'react-indexed-db-hook';","symbol":"useIndexedDB","correct":"import { useIndexedDB } from 'react-indexed-db-hook';"},{"note":"Type definition for the database configuration object passed to `initDB`.","symbol":"DBConfig","correct":"import type { DBConfig } from 'react-indexed-db-hook';"}],"quickstart":{"code":"import React, { useEffect, useState } from 'react';\nimport { initDB, useIndexedDB } from 'react-indexed-db-hook';\n\ninterface User {\n  id?: number;\n  name: string;\n  email: string;\n}\n\n// 1. Define your database configuration\nconst dbConfig = {\n  name: 'MyDatabase',\n  version: 1,\n  objectStoresMeta: [\n    {\n      store: 'users',\n      storeConfig: { keyPath: 'id', autoIncrement: true },\n      storeSchema: [\n        { name: 'name', keypath: 'name', options: { unique: false } },\n        { name: 'email', keypath: 'email', options: { unique: true } },\n      ],\n    },\n  ],\n};\n\n// 2. Initialize the database (typically once in your app's entry point)\ninitDB(dbConfig);\n\nfunction UserForm() {\n  const { add, getAll } = useIndexedDB<User>('users');\n  const [name, setName] = useState('');\n  const [email, setEmail] = useState('');\n  const [users, setUsers] = useState<User[]>([]);\n\n  useEffect(() => {\n    // Fetch all users on component mount\n    getAll().then((data) => {\n      setUsers(data);\n    });\n  }, [getAll]);\n\n  const handleSubmit = async (e: React.FormEvent) => {\n    e.preventDefault();\n    if (!name || !email) return;\n\n    try {\n      const userId = await add({ name, email });\n      alert(`User added with ID: ${userId}`);\n      setName('');\n      setEmail('');\n      // Re-fetch users to update the list\n      getAll().then((data) => setUsers(data));\n    } catch (error) {\n      console.error('Error adding user:', error);\n      alert('Failed to add user. Email might already exist.');\n    }\n  };\n\n  return (\n    <div>\n      <h1>Add New User</h1>\n      <form onSubmit={handleSubmit}>\n        <input\n          type=\"text\"\n          placeholder=\"Name\"\n          value={name}\n          onChange={(e) => setName(e.target.value)}\n        />\n        <input\n          type=\"email\"\n          placeholder=\"Email\"\n          value={email}\n          onChange={(e) => setEmail(e.target.value)}\n        />\n        <button type=\"submit\">Add User</button>\n      </form>\n\n      <h2>Users List</h2>\n      {users.length === 0 ? (\n        <p>No users yet.</p>\n      ) : (\n        <ul>\n          {users.map((user) => (\n            <li key={user.id}>\n              {user.name} ({user.email})\n            </li>\n          ))}\n        </ul>\n      )}\n    </div>\n  );\n}\n\nexport default UserForm;","lang":"typescript","description":"Demonstrates initializing the IndexedDB database, adding a new user to an object store, and retrieving all users using the `useIndexedDB` hook. This covers basic setup and CRUD operations."},"warnings":[{"fix":"Guard IndexedDB usage with client-side checks or dynamic imports for SSR applications. Example: `if (typeof window !== 'undefined') { // IndexedDB code }`.","message":"IndexedDB is a browser-only API. Using `react-indexed-db-hook` directly in Server-Side Rendering (SSR) environments (like Next.js or Astro) will result in `window is not defined` errors. Ensure IndexedDB-related code runs only on the client-side, typically by dynamically importing components or checking `typeof window !== 'undefined'`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"When modifying your `dbConfig` (e.g., changing `objectStoresMeta`), increment the `version` number in `initDB`. Handle schema migrations in the `onupgradeneeded` event if more complex logic is required (though this library abstracts some of that).","message":"Changing `keyPath` or adding new indexes to an existing object store requires incrementing the database version in `initDB`. Failure to do so will result in `DOMException: A mutation operation was attempted on a database that did not allow mutations` or `VersionError`.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Inform users to close other tabs if they encounter 'blocked' errors during database upgrades or deletions. For critical updates, consider using `IDBFactory.deleteDatabase()` with `onblocked` handling, or implement a version migration strategy that gracefully handles conflicts.","message":"IndexedDB operations can be 'blocked' if the database is open in other browser tabs or instances when an `onupgradeneeded` event is triggered. This can prevent schema changes or even database deletion.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Evaluate your project's needs for active maintenance and support. For long-term projects or those requiring advanced features, consider alternatives like `Dexie.js` or `RxDB` which provide more robust and actively developed abstractions over IndexedDB.","message":"The `react-indexed-db-hook` package has not been updated in over three years (last published 2022-11-27). While functional, it may not receive new features, performance optimizations, or prompt bug fixes compared to more actively maintained IndexedDB wrappers or state management libraries.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Increment the `version` property in your `dbConfig` object passed to `initDB` whenever you make schema changes to your `objectStoresMeta`.","cause":"Attempting to change database schema (e.g., add or modify an object store or index) without incrementing the database version in `initDB`.","error":"Failed to open IndexedDB: A mutation operation was attempted on a database that did not allow mutations."},{"fix":"Ensure that all write operations are performed within the scope of a transaction explicitly created for that purpose. The `useIndexedDB` hook is designed to manage these transactions, so this error might indicate incorrect usage of the hook's methods or an attempt to use IndexedDB directly without proper transaction handling.","cause":"This often occurs when trying to perform write operations (add, put, delete) on IndexedDB outside of an active write transaction context, or when a transaction has already completed.","error":"Uncaught (in promise) DOMException: Failed to execute 'transaction' on 'IDBDatabase': The database is not running a versionchange transaction."},{"fix":"Wrap your IndexedDB-dependent code in client-side checks (`if (typeof window !== 'undefined')`) or dynamically import components that use `react-indexed-db-hook` to ensure they only render in the browser.","cause":"Attempting to run IndexedDB-related code, which is a browser API, in a Node.js environment (e.g., during Server-Side Rendering with Next.js or other SSR frameworks).","error":"ReferenceError: window is not defined"}],"ecosystem":"npm"}