{"id":28965788,"url":"https://github.com/umarsiddique010/use-localstorage-hook","last_synced_at":"2025-06-24T07:09:33.680Z","repository":{"id":300046307,"uuid":"1005061890","full_name":"umarSiddique010/use-localstorage-hook","owner":"umarSiddique010","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-19T15:50:56.000Z","size":0,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-19T16:29:47.956Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/umarSiddique010.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-19T15:50:41.000Z","updated_at":"2025-06-19T15:51:00.000Z","dependencies_parsed_at":"2025-06-19T16:31:15.790Z","dependency_job_id":"74cf02b7-2cfc-4dd5-a254-541b405bacb7","html_url":"https://github.com/umarSiddique010/use-localstorage-hook","commit_stats":null,"previous_names":["umarsiddique010/use-localstorage-hook"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/umarSiddique010/use-localstorage-hook","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarSiddique010%2Fuse-localstorage-hook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarSiddique010%2Fuse-localstorage-hook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarSiddique010%2Fuse-localstorage-hook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarSiddique010%2Fuse-localstorage-hook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/umarSiddique010","download_url":"https://codeload.github.com/umarSiddique010/use-localstorage-hook/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarSiddique010%2Fuse-localstorage-hook/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261624972,"owners_count":23186121,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-24T07:09:31.783Z","updated_at":"2025-06-24T07:09:33.664Z","avatar_url":"https://github.com/umarSiddique010.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# useLocalstorage\n\nA React hook for safe, reactive access to `localStorage`, with:\n\n* Reactive state management with automatic re-renders\n* Cross-tab synchronization via storage events\n* Auto-initialization on mount with validation\n* Built-in `set`, `get`, `remove`, `clearAll` helpers\n* Support for any JSON-serializable data\n* Error-resilient design with comprehensive error handling\n* Zero dependencies — just native Web APIs + React\n\n---\n\n## Why Use This Hook?\n\n\u003e No more repeating `localStorage.setItem` logic in every component.\n\n`useLocalstorage` is for React developers who want:\n\n* Reactive localStorage state that updates your UI automatically\n* Cross-tab synchronization - changes in one tab update others\n* One-liner setup of persistent browser state\n* Safety against stale keys or malformed data\n* Clean `set/get/remove` operations without spaghetti\n* Auto-persisted defaults on first load\n* Reusability across apps, components, and projects\n\n**Perfect for:**\n\n* Auth tokens or user session keys\n* UI preferences (dark mode, language)\n* Cart data or product filters\n* Any local-only persistence logic that needs cross-tab sync\n\n---\n\n## What Is This?\n\n`useLocalstorage()` is a custom React hook that wraps the native `localStorage` API in a safe, reactive, composable way.\n\nIt handles:\n\n* Reactive state management with `useState`\n* Cross-tab synchronization with storage events\n* When to write to localStorage (`useEffect`)\n* How to write (with stringification and error handling)\n* Reading, removing, and clearing browser keys\n* Making it all memoized and safe for reuse\n\n---\n\n## Installation\n\n```bash\nnpm install @mdus/use-localstorage-hook\n# or\nyarn add @mdus/use-localstorage-hook\n```\n\n---\n\n## API Reference\n\n### What It Expects\n\n| Argument      | Type     | Required | Description                                             |\n| ------------- | -------- | -------- | ------------------------------------------------------- |\n| `storeName`   | `string` | Yes      | The key to use inside localStorage                      |\n| `initialData` | `any`    | Yes      | The default data to initialize if the key is empty/null |\n\n### What It Returns\n\n| Key             | Type       | Description                                                    |\n| --------------- | ---------- | -------------------------------------------------------------- |\n| `getStore`      | `any`      | The current value from localStorage (reactive state)           |\n| `setStore`      | `function` | Sets a value into `localStorage` and updates the reactive state |\n| `removeStore`   | `function` | Removes the item with this key from localStorage               |\n| `clearAllStore` | `function` | Clears **all** localStorage entries                            |\n\n---\n\n## Usage\n\n### 1. Basic Reactive State\n\n```jsx\nimport useLocalstorage from \"@mdus/use-localstorage-hook\";\n\nfunction ThemeToggle() {\n  const { getStore: theme, setStore: setTheme } = useLocalstorage(\"theme\", \"light\");\n\n  const toggleTheme = () =\u003e {\n    setTheme(theme === \"light\" ? \"dark\" : \"light\");\n  };\n\n  return (\n    \u003cdiv className={theme}\u003e\n      \u003cp\u003eCurrent theme: {theme}\u003c/p\u003e\n      \u003cbutton onClick={toggleTheme}\u003eToggle Theme\u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### 2. Cross-Tab Synchronization\n\n```jsx\nfunction UserPreferences() {\n  const { getStore: prefs, setStore: setPrefs } = useLocalstorage(\"userPrefs\", {\n    language: \"en\",\n    notifications: true\n  });\n\n  // This will automatically update across all open tabs\n  const updateLanguage = (lang) =\u003e {\n    setPrefs({ ...prefs, language: lang });\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003cp\u003eLanguage: {prefs.language}\u003c/p\u003e\n      \u003cbutton onClick={() =\u003e updateLanguage(\"es\")}\u003eSwitch to Spanish\u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### 3. Managing Complex Data\n\n```jsx\nfunction ShoppingCart() {\n  const { getStore: cart, setStore: setCart, removeStore } = useLocalstorage(\"cart\", []);\n\n  const addItem = (item) =\u003e {\n    setCart([...cart, item]);\n  };\n\n  const clearCart = () =\u003e {\n    removeStore();\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003cp\u003eItems in cart: {cart.length}\u003c/p\u003e\n      \u003cbutton onClick={() =\u003e addItem({ id: Date.now(), name: \"Product\" })}\u003e\n        Add Item\n      \u003c/button\u003e\n      \u003cbutton onClick={clearCart}\u003eClear Cart\u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n---\n\n## Key Features\n\n### 1. Reactive State Management\n\nThe hook uses `useState` to provide reactive state that automatically re-renders your components when localStorage changes:\n\n```js\nconst [getStore, setGetStore] = useState(() =\u003e {\n  try {\n    const item = localStorage.getItem(key);\n    return item ? JSON.parse(item) : initialData;\n  } catch (err) {\n    console.error(`Error reading localStorage key \"${key}\":`, err);\n    localStorage.removeItem(key);\n    return initialData;\n  }\n});\n```\n\n### 2. Cross-Tab Synchronization\n\nThe hook listens for storage events to keep multiple tabs in sync:\n\n```js\nuseEffect(() =\u003e {\n  const handleStoreChange = (e) =\u003e {\n    if (e.key === key) {\n      try {\n        if (e.newValue === null) {\n          setGetStore(null);\n        } else {\n          setGetStore(JSON.parse(e.newValue));\n        }\n      } catch (err) {\n        console.error(`Error parsing storage event for key \"${key}\":`, err);\n        setGetStore(null);\n      }\n    }\n  };\n\n  window.addEventListener('storage', handleStoreChange);\n  return () =\u003e window.removeEventListener('storage', handleStoreChange);\n}, [key]);\n```\n\n### 3. Safe Initialization\n\nThe hook validates inputs and safely initializes localStorage:\n\n```js\nif (!storeName || initialData === undefined) {\n  throw new Error(\"useLocalstorage: storeName and initialData are required.\");\n}\n```\n\n### 4. Error Resilience\n\nAll operations are wrapped in try/catch blocks with meaningful error messages and fallback behavior.\n\n---\n\n## Internals\n\n### Lifecycle-Safe Initialization\n\nWhen the component mounts, the hook checks if localStorage already contains the key:\n\n```js\nuseEffect(() =\u003e {\n  try {\n    const existing = localStorage.getItem(key);\n    if (existing === null) {\n      setStore(initialData);\n    }\n  } catch (err) {\n    console.error(`Error initializing localStorage key \"${key}\":`, err);\n  }\n}, [key, initialData, setStore]);\n```\n\nThis prevents overwriting existing values.\n\n### Pure React API\n\n* Uses `useState` for reactive state management\n* Uses `useCallback` to memoize methods\n* Uses `useEffect` for storage event listeners and initialization\n* Safe to use inside other hooks and effects\n* Designed for composability in any React component\n\n---\n\n## File Structure\n\n```\nuse-localstorage-hook/\n├── src/\n│   └── useLocalstorage.js\n├── dist/\n│   └── index.js\n├── package.json\n└── README.md\n```\n\n---\n\n## Author\n\n**Md Umar Siddique**\n\n* GitHub: [@umarSiddique010](https://github.com/umarSiddique010)\n* LinkedIn: [md-umar-siddique](https://linkedin.com/in/md-umar-siddique)\n* Dev.to: [@umarSiddique010](https://dev.to/umarsiddique010)\n\n---\n\n## License\n\nMIT © 2025 Md Umar Siddique\n\n---\n\n## Final Note\n\nThis hook solves a **real problem**: managing persistent state in a clean, reactive, and React-friendly way with cross-tab synchronization. It reflects an engineering mindset focused on **clarity**, **reusability**, **reactivity**, and **edge case safety** — all in under 3KB of code.\n\nIf it saves you time, please consider starring and sharing.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumarsiddique010%2Fuse-localstorage-hook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fumarsiddique010%2Fuse-localstorage-hook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumarsiddique010%2Fuse-localstorage-hook/lists"}