{"id":19729090,"url":"https://github.com/guoyunhe/react-storage","last_synced_at":"2025-10-15T06:59:49.586Z","repository":{"id":178017896,"uuid":"661249959","full_name":"guoyunhe/react-storage","owner":"guoyunhe","description":"Better useLocalStorage() and useSessionStorage() hooks","archived":false,"fork":false,"pushed_at":"2025-06-29T09:56:16.000Z","size":48,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-20T15:43:29.724Z","etag":null,"topics":["json","local-storage","prefix","react","react-h","serialization","session-storage","storage"],"latest_commit_sha":null,"homepage":"https://guoyunhe.github.io/react-storage/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/guoyunhe.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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":"2023-07-02T09:00:45.000Z","updated_at":"2025-07-12T14:22:41.000Z","dependencies_parsed_at":"2025-05-30T20:55:17.537Z","dependency_job_id":"90b2fa7e-750d-47ba-87bf-9c229adef939","html_url":"https://github.com/guoyunhe/react-storage","commit_stats":null,"previous_names":["guoyunhe/react-storage","guoyunhe/react-fast-storage"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/guoyunhe/react-storage","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guoyunhe%2Freact-storage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guoyunhe%2Freact-storage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guoyunhe%2Freact-storage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guoyunhe%2Freact-storage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guoyunhe","download_url":"https://codeload.github.com/guoyunhe/react-storage/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guoyunhe%2Freact-storage/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279058749,"owners_count":26094852,"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","status":"online","status_checked_at":"2025-10-15T02:00:07.814Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["json","local-storage","prefix","react","react-h","serialization","session-storage","storage"],"created_at":"2024-11-12T00:10:04.833Z","updated_at":"2025-10-15T06:59:49.580Z","avatar_url":"https://github.com/guoyunhe.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @guoyunhe/react-storage\n\n![npm](https://img.shields.io/npm/v/@guoyunhe/react-storage)\n![downloads](https://img.shields.io/npm/dw/@guoyunhe/react-storage)\n![minzipped size](https://img.shields.io/bundlephobia/minzip/@guoyunhe/react-storage)\n\nBetter useLocalStorage() and useSessionStorage() hooks.\n\n## Installation\n\n```bash\nnpm install --save @guoyunhe/react-storage\n```\n\n## Examples\n\n### Simple\n\nBy default, useLocalStorage support JSON data.\n\n```js\nimport { useLocalStorage, useSessionStorage } from '@guoyunhe/react-storage';\n\ninterface Settings {\n  color: string;\n  size: number;\n}\n\nfunction App() {\n  const [settings, setSettings] = useLocalStorage\u003cSettings\u003e('settings', { color: 'red', size: 20 });\n  const [draft, setDraft] = useSessionStorage\u003cstring\u003e('draft', '');\n}\n```\n\n### Customize serializer and parser\n\nYou can use options to customize serializer and parser.\n\n```js\nimport { useLocalStorage } from '@guoyunhe/react-storage';\n\nfunction App() {\n  const [date, setDate] = useLocalStorage('date', new Date(), {\n    serializer: (date) =\u003e date.toISOString(),\n    parser: (str) =\u003e new Date(str),\n  });\n}\n```\n\n### Storage key prefix\n\nLocalStorage is scoped by domain. However, you may have multiple React apps under same domain and\ndon't want to share data between. In this case, you can specify a global `prefix` with\n`\u003cStorageProvider/\u003e`.\n\n```js\nimport { useLocalStorage, StorageProvider } from '@guoyunhe/react-storage';\n\nfunction App() {\n  return (\n    \u003cStorageProvider prefix=\"dashboard_\"\u003e\n      \u003cPage /\u003e\n    \u003c/StorageProvider\u003e\n  );\n}\n\nfunction Page() {\n  // The actual storage key will be `dashboard_dark_mode`\n  const [darkMode, setDarkMode] = useLocalStorage('dark_mode', false);\n}\n```\n\n### Sync state across components and browser tabs\n\nCommunicating through `stroage` event, states can sync between different components and browser tabs,\nin real-time, without extra effort.\n\n```jsx\nimport { useLocalStorage, StorageProvider } from '@guoyunhe/react-storage';\n\nfunction Page() {\n  const [count, setCount] = useLocalStorage('count', 0);\n  return (\n    \u003cdiv style={{ background: '#8888', padding: 4 }}\u003e\n      \u003cbutton onClick={() =\u003e setCount((prev) =\u003e prev - 1)}\u003e-\u003c/button\u003e\n      \u003cspan style={{ paddingInline: 8 }}\u003e{count}\u003c/span\u003e\n      \u003cbutton onClick={() =\u003e setCount((prev) =\u003e prev + 1)}\u003e+\u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n\nrender(\n  \u003cdiv style={{ display: 'flex', flexDirection: 'column', alignItems: 'start', gap: 8 }}\u003e\n    \u003cPage /\u003e\n    \u003cPage /\u003e\n  \u003c/div\u003e,\n);\n```\n\n## API\n\n### useLocalStorage(key, defaultValue, options)\n\n`useLocalStorage()` can not only persist data, but also share state between browser tabs!\n\nRemember that localStorage has a 5MB size limit. Do NOT write too many data into it.\n\n#### key\n\nType: `string`\n\nStorage key. If [`prefix`](#prefix) is defined, actual storage key is `prefix` + `key`.\n\n#### defaultValue\n\nType: `T`\n\nDefault value to use when storage doesn't exist or can not be parsed.\n\n#### options.serializer\n\nType: `(value: T) =\u003e string`\n\nDefault: `JSON.stringify`\n\nSerialize value to string.\n\n#### options.parser\n\nType: `(data: string) =\u003e T`\n\nDefault: `JSON.parse`\n\nParse string to value.\n\n#### options.prefix\n\nType: `string`\n\nIn case you defined global `prefix` in `\u003cStorageProvider/\u003e`, but need to override it in some places.\n\n### useSessionStorage()\n\nAPI is the same as `useLocalStorage()`, but store data in `sessionStorage`, which will be clear after\nclosing browser tabs. It is useful when you want an easy way to:\n\n- Share state between different React components or apps in the same browser tab\n- Remember state after refreshing browser tab\n\nRemember that sessionStorage also has a 5MB size limit. Do NOT write too many data into it.\n\n### StorageProvider\n\nDefine global configuration for hooks.\n\n#### prefix\n\nType: `string`\n\nIf `prefix` is defined, actual storage key is `prefix` + `key`.\n\n#### serializer\n\nType: `(value: T) =\u003e string`\n\nDefault: `JSON.stringify`\n\nSerialize value to string.\n\n#### parser\n\nType: `(data: string) =\u003e T`\n\nDefault: `JSON.parse`\n\nParse string to value.\n\n## Comparison\n\n| Package                         | TS  | ESM | Prefix | Sync across tabs | Sync across components | Bundle size                                                                              |\n| ------------------------------- | --- | --- | ------ | ---------------- | ---------------------- | ---------------------------------------------------------------------------------------- |\n| @guoyunhe/react-storage         | ✅  | ✅  | ✅     | ✅               | ✅                     | ![Bundle size](https://img.shields.io/bundlephobia/minzip/@guoyunhe/react-storage)       |\n| [use-local-storage-state]       | ✅  | ✅  | ❌     | ✅               | ❌                     | ![Bundle size](https://img.shields.io/bundlephobia/minzip/use-local-storage-state)       |\n| [use-local-storage]             | ✅  | ❌  | ❌     | ✅               | ✅                     | ![Bundle size](https://img.shields.io/bundlephobia/minzip/use-local-storage)             |\n| [@guoyunhe/react-storage-hooks] | ✅  | ❌  | ❌     | ✅               | ❌                     | ![Bundle size](https://img.shields.io/bundlephobia/minzip/@guoyunhe/react-storage-hooks) |\n| [react-use]                     | ✅  | ✅  | ❌     | ❌               | ❌                     | ![Bundle size](https://img.shields.io/bundlephobia/minzip/react-use)                     |\n| [ahooks]                        | ✅  | ✅  | ❌     | ❌               | ❌                     | ![Bundle size](https://img.shields.io/bundlephobia/minzip/ahooks)                        |\n\n[@guoyunhe/react-storage-hooks]: https://www.npmjs.com/package/@guoyunhe/react-storage-hooks\n[use-local-storage-state]: https://www.npmjs.com/package/use-local-storage-state\n[use-local-storage]: https://www.npmjs.com/package/use-local-storage\n[react-use]: https://www.npmjs.com/package/react-use\n[ahooks]: https://www.npmjs.com/package/ahooks\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguoyunhe%2Freact-storage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguoyunhe%2Freact-storage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguoyunhe%2Freact-storage/lists"}