{"_id":"react-hook-form-storage","_rev":"7-ba7308690897bb6f8f1a386df299e4a9","name":"react-hook-form-storage","dist-tags":{"latest":"1.3.1"},"versions":{"1.0.0":{"name":"react-hook-form-storage","version":"1.0.0","keywords":["react","react-hook-form","react-hook-forms","form","persist","persistent","persistent-storage","localstorage","sessionstorage"],"author":{"name":"Franco Sánchez","email":"francog.sanchez@hotmail.com"},"license":"MIT","_id":"react-hook-form-storage@1.0.0","maintainers":[{"name":"franco.gabriel92","email":"francog.sanchez@gmail.com"}],"homepage":"https://github.com/francogabriel92/react-hook-form-storage#readme","bugs":{"url":"https://github.com/francogabriel92/react-hook-form-storage/issues"},"dist":{"shasum":"6d3deba5a7dc3b9bbec6055776d4b843c84cecff","tarball":"https://registry.npmjs.org/react-hook-form-storage/-/react-hook-form-storage-1.0.0.tgz","fileCount":11,"integrity":"sha512-HtOyZ9iNGgw5N3uj2JvhVdWrb7XRBBFJ4pY0XNx1SEcPlleZ59TKVjCHP0eaL4RbUaIa+5dC39EReRWwQlbrOg==","signatures":[{"sig":"MEUCIAVx65hZUhvl4dsj05/70us0B9VVUOhCeWMT2ZHZGN9TAiEApPMKAZK1mo7PIxqNf3K40lt9C1izdiyiB+l3wmc94a4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43523},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"21057e4301c8143b6a5c0efdfd7d22b4869c6e26","scripts":{"dev":"npm run build:watch","lint":"eslint src/**/*.{ts,tsx} --fix","test":"jest","build":"rollup -c --bundleConfigAsCjs","dev:setup":"cd dev && npm install","test:watch":"jest --watchAll","build:watch":"rollup -c -w","dev:example":"cd dev && npm run dev","test:coverage":"jest --coverage"},"_npmUser":{"name":"franco.gabriel92","email":"francog.sanchez@gmail.com"},"repository":{"url":"git+https://github.com/francogabriel92/react-hook-form-storage.git","type":"git"},"_npmVersion":"11.4.1","description":"A TypeScript library for React Hook Form persist functionality","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"zod":"^4.0.14","jest":"^30.0.5","react":"^19.1.1","tslib":"^2.8.1","eslint":"^9.32.0","ts-jest":"^29.4.0","prettier":"^3.6.2","react-dom":"^19.1.1","typescript":"^5.9.2","@types/react":"^19.1.9","react-hook-form":"^7.62.0","rollup-plugin-dts":"^6.2.1","@hookform/resolvers":"^5.2.1","eslint-plugin-react":"^7.37.5","@rollup/plugin-terser":"^0.4.4","@testing-library/react":"^16.3.0","jest-environment-jsdom":"^30.0.5","@rollup/plugin-commonjs":"^28.0.6","@rollup/plugin-typescript":"^12.1.4","@testing-library/jest-dom":"^6.6.4","@typescript-eslint/parser":"^8.39.0","eslint-plugin-react-hooks":"^5.2.0","@rollup/plugin-node-resolve":"^16.0.1","@testing-library/user-event":"^14.6.1","@typescript-eslint/eslint-plugin":"^8.39.0","rollup-plugin-peer-deps-external":"^2.2.4"},"peerDependencies":{"react":">=16.8.0","react-hook-form":">=7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/react-hook-form-storage_1.0.0_1754430776738_0.9457837329624761","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"react-hook-form-storage","version":"1.1.0","keywords":["react","react-hook-form","react-hook-forms","form","persist","persistent","persistent-storage","localstorage","sessionstorage"],"author":{"name":"Franco Sánchez","email":"francog.sanchez@hotmail.com"},"license":"MIT","_id":"react-hook-form-storage@1.1.0","maintainers":[{"name":"franco.gabriel92","email":"francog.sanchez@gmail.com"}],"homepage":"https://github.com/francogabriel92/react-hook-form-storage#readme","bugs":{"url":"https://github.com/francogabriel92/react-hook-form-storage/issues"},"dist":{"shasum":"4bac9abeeed06b9b85a0bfe0e9a2c7889a36f617","tarball":"https://registry.npmjs.org/react-hook-form-storage/-/react-hook-form-storage-1.1.0.tgz","fileCount":10,"integrity":"sha512-19nvzPlRF9aj8XvG67NbMIXtc3Z38lC1yWw79S3XbEqx5PNAYRozARN3wZmrgVhVW05ax0S/cur0CBkLxBii1Q==","signatures":[{"sig":"MEYCIQC8KBEX3fJLinfqyDeGtk2CtGXfD8ze8SVBauGlTMZGNQIhAMmMfoB0KT0hI2ThjyD2j+lQyE8vgxu7NdRowO5tVh/J","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49835},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"122655f0243302d331f133e88f458c8533bb0035","scripts":{"dev":"npm run build:watch","lint":"eslint src/**/*.{ts,tsx} --fix","test":"jest","build":"rollup -c --bundleConfigAsCjs","dev:setup":"cd dev && npm install","test:watch":"jest --watchAll","build:watch":"rollup -c -w","dev:example":"cd dev && npm run dev","test:coverage":"jest --coverage"},"_npmUser":{"name":"franco.gabriel92","email":"francog.sanchez@gmail.com"},"repository":{"url":"git+https://github.com/francogabriel92/react-hook-form-storage.git","type":"git"},"_npmVersion":"11.4.1","description":"A TypeScript library for React Hook Form persist functionality","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"zod":"^4.0.14","jest":"^30.0.5","react":"^19.1.1","tslib":"^2.8.1","eslint":"^9.32.0","ts-jest":"^29.4.0","prettier":"^3.6.2","react-dom":"^19.1.1","typescript":"^5.9.2","@types/react":"^19.1.9","react-hook-form":"^7.62.0","rollup-plugin-dts":"^6.2.1","@hookform/resolvers":"^5.2.1","eslint-plugin-react":"^7.37.5","@rollup/plugin-terser":"^0.4.4","@testing-library/react":"^16.3.0","jest-environment-jsdom":"^30.0.5","@rollup/plugin-commonjs":"^28.0.6","@rollup/plugin-typescript":"^12.1.4","@testing-library/jest-dom":"^6.6.4","@typescript-eslint/parser":"^8.39.0","eslint-plugin-react-hooks":"^5.2.0","@rollup/plugin-node-resolve":"^16.0.1","@testing-library/user-event":"^14.6.1","@typescript-eslint/eslint-plugin":"^8.39.0","rollup-plugin-peer-deps-external":"^2.2.4"},"peerDependencies":{"react":">=16.8.0","react-hook-form":">=7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/react-hook-form-storage_1.1.0_1754591241907_0.045826484384079436","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"react-hook-form-storage","version":"1.2.0","keywords":["react","react-hook-form","react-hook-forms","form","persist","persistent","persistent-storage","localstorage","sessionstorage"],"author":{"name":"Franco Sánchez","email":"francog.sanchez@hotmail.com"},"license":"MIT","_id":"react-hook-form-storage@1.2.0","maintainers":[{"name":"franco.gabriel92","email":"francog.sanchez@gmail.com"}],"homepage":"https://github.com/francogabriel92/react-hook-form-storage#readme","bugs":{"url":"https://github.com/francogabriel92/react-hook-form-storage/issues"},"dist":{"shasum":"67bf5b0c31daeeb51c5031bd4da951891257b0c7","tarball":"https://registry.npmjs.org/react-hook-form-storage/-/react-hook-form-storage-1.2.0.tgz","fileCount":10,"integrity":"sha512-3RmOzVe2euZ5qlcGH0Ru7yP3R26KiwafdtvTB9DwAc7FpV4YAiMQ0lSDdD257Lo6Z1ds20Yhv+2A+8o7I9kiXQ==","signatures":[{"sig":"MEQCIBZbkZP2Af0i0xdjy098mMIv2aG2cSZDIC+q4GeKdPvQAiB4QuPwT9B/FdD/iJM1uTOOGcp5nGAiAAcFqZ6SxaDBYA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49935},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"7abf87174ca67f1ecbe999ca1db785447a1feb8d","scripts":{"dev":"npm run build:watch","lint":"eslint src/**/*.{ts,tsx} --fix","test":"jest","build":"rollup -c --bundleConfigAsCjs","dev:setup":"cd dev && npm install","test:watch":"jest --watchAll","build:watch":"rollup -c -w","dev:example":"cd dev && npm run dev","test:coverage":"jest --coverage"},"_npmUser":{"name":"franco.gabriel92","email":"francog.sanchez@gmail.com"},"repository":{"url":"git+https://github.com/francogabriel92/react-hook-form-storage.git","type":"git"},"_npmVersion":"11.4.1","description":"A TypeScript library for React Hook Form persist functionality","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"zod":"^4.0.14","jest":"^30.0.5","react":"^19.1.1","tslib":"^2.8.1","eslint":"^9.32.0","ts-jest":"^29.4.0","prettier":"^3.6.2","react-dom":"^19.1.1","typescript":"^5.9.2","@types/react":"^19.1.9","react-hook-form":"^7.62.0","rollup-plugin-dts":"^6.2.1","@hookform/resolvers":"^5.2.1","eslint-plugin-react":"^7.37.5","@rollup/plugin-terser":"^0.4.4","@testing-library/react":"^16.3.0","jest-environment-jsdom":"^30.0.5","@rollup/plugin-commonjs":"^28.0.6","@rollup/plugin-typescript":"^12.1.4","@testing-library/jest-dom":"^6.6.4","@typescript-eslint/parser":"^8.39.0","eslint-plugin-react-hooks":"^5.2.0","@rollup/plugin-node-resolve":"^16.0.1","@testing-library/user-event":"^14.6.1","@typescript-eslint/eslint-plugin":"^8.39.0","rollup-plugin-peer-deps-external":"^2.2.4"},"peerDependencies":{"react":">=16.8.0","react-hook-form":">=7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/react-hook-form-storage_1.2.0_1760436830513_0.7866318118201163","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"react-hook-form-storage","version":"1.3.0","keywords":["react","react-hook-form","react-hook-forms","form","persist","persistent","persistent-storage","localstorage","sessionstorage"],"author":{"name":"Franco Sánchez","email":"francog.sanchez@hotmail.com"},"license":"MIT","_id":"react-hook-form-storage@1.3.0","maintainers":[{"name":"franco.gabriel92","email":"francog.sanchez@gmail.com"}],"homepage":"https://github.com/francogabriel92/react-hook-form-storage#readme","bugs":{"url":"https://github.com/francogabriel92/react-hook-form-storage/issues"},"dist":{"shasum":"95ad5e929ff267c873f65d13445f9f7ad9548afd","tarball":"https://registry.npmjs.org/react-hook-form-storage/-/react-hook-form-storage-1.3.0.tgz","fileCount":10,"integrity":"sha512-7HtTMejUFOw2Gjedjft2c+Pj4vAQyZT49ALpHGWlC9c7PcaD8zYlZGfFvuHX3lCtVdbLxM8sLu2ji+/BSTlMQg==","signatures":[{"sig":"MEUCIDas/XYZoviznw0PgnLQzsVp7MUQvasoG9DPEwxLZzGTAiEA5thEb+Xyd32VfpCdeVARmzLAmPbvFXN9yDqxcVSvUwE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50837},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"7389c67699322b06475c8d2c178c914755ac22e1","scripts":{"dev":"npm run build:watch","lint":"eslint src/**/*.{ts,tsx} --fix","test":"jest","build":"rollup -c --bundleConfigAsCjs","dev:setup":"cd dev && npm install","test:watch":"jest --watchAll","build:watch":"rollup -c -w","dev:example":"cd dev && npm run dev","test:coverage":"jest --coverage"},"_npmUser":{"name":"franco.gabriel92","email":"francog.sanchez@gmail.com"},"repository":{"url":"git+https://github.com/francogabriel92/react-hook-form-storage.git","type":"git"},"_npmVersion":"11.4.1","description":"A TypeScript library for React Hook Form persist functionality","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"zod":"^4.0.14","jest":"^30.0.5","react":"^19.1.1","tslib":"^2.8.1","eslint":"^9.32.0","ts-jest":"^29.4.0","prettier":"^3.6.2","react-dom":"^19.1.1","typescript":"^5.9.2","@types/react":"^19.1.9","react-hook-form":"^7.62.0","rollup-plugin-dts":"^6.2.1","@hookform/resolvers":"^5.2.1","eslint-plugin-react":"^7.37.5","@rollup/plugin-terser":"^0.4.4","@testing-library/react":"^16.3.0","jest-environment-jsdom":"^30.0.5","@rollup/plugin-commonjs":"^29.0.0","@rollup/plugin-typescript":"^12.1.4","@testing-library/jest-dom":"^6.6.4","@typescript-eslint/parser":"^8.39.0","eslint-plugin-react-hooks":"^7.0.1","@rollup/plugin-node-resolve":"^16.0.1","@testing-library/user-event":"^14.6.1","@typescript-eslint/eslint-plugin":"^8.39.0","rollup-plugin-peer-deps-external":"^2.2.4"},"peerDependencies":{"react":">=16.8.0","react-hook-form":">=7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/react-hook-form-storage_1.3.0_1771455796275_0.9251310494691403","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"react-hook-form-storage","version":"1.3.1","description":"Persist React Hook Form state to localStorage/sessionStorage/async storage — TypeScript-first, SSR-safe, with serializers & debounce.","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","scripts":{"build":"rollup -c --bundleConfigAsCjs","build:watch":"rollup -c -w","dev":"npm run build:watch","dev:example":"cd dev && npm run dev","dev:setup":"cd dev && npm install","test":"jest","test:watch":"jest --watchAll","test:coverage":"jest --coverage","lint":"eslint 'src/**/*.{ts,tsx}' --max-warnings=17","lint:fix":"eslint 'src/**/*.{ts,tsx}' --fix","typecheck":"tsc --noEmit"},"keywords":["react","react-hook-form","react-hook-forms","react-hook-form-persist","form","persist","persistent","persistent-storage","localstorage","sessionstorage","autosave","draft","ssr","nextjs"],"author":{"name":"Franco Sánchez","email":"francog.sanchez@hotmail.com"},"license":"MIT","peerDependencies":{"react":">=16.8.0","react-hook-form":">=7.0.0"},"devDependencies":{"@eslint/js":"^9.39.2","@hookform/resolvers":"^5.2.1","@rollup/plugin-commonjs":"^29.0.0","@rollup/plugin-node-resolve":"^16.0.1","@rollup/plugin-terser":"^0.4.4","@rollup/plugin-typescript":"^12.1.4","@testing-library/jest-dom":"^6.6.4","@testing-library/react":"^16.3.0","@testing-library/user-event":"^14.6.1","@types/react":"^19.1.9","@typescript-eslint/eslint-plugin":"^8.39.0","@typescript-eslint/parser":"^8.39.0","eslint":"^9.32.0","eslint-plugin-react":"^7.37.5","eslint-plugin-react-hooks":"^7.0.1","globals":"^17.6.0","jest":"^30.0.5","jest-environment-jsdom":"^30.0.5","prettier":"^3.6.2","react":"^19.1.1","react-dom":"^19.1.1","react-hook-form":"^7.62.0","rollup-plugin-dts":"^6.2.1","rollup-plugin-peer-deps-external":"^2.2.4","ts-jest":"^29.4.0","tslib":"^2.8.1","typescript":"^5.9.2","zod":"^4.0.14"},"repository":{"type":"git","url":"git+https://github.com/francogabriel92/react-hook-form-storage.git"},"bugs":{"url":"https://github.com/francogabriel92/react-hook-form-storage/issues"},"homepage":"https://github.com/francogabriel92/react-hook-form-storage#readme","gitHead":"6d37fdf6e19c657a270105b479b8dec921507563","_id":"react-hook-form-storage@1.3.1","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-tZdC010JSfWqFSnqP7jN/8wIp/ENXaOpHsrwywebLvC4fLKUgycKstc0obl795rUcVRF7ZOoUVumz7Y799Cx+Q==","shasum":"35d278185d7ebff296745b177169e2927895054b","tarball":"https://registry.npmjs.org/react-hook-form-storage/-/react-hook-form-storage-1.3.1.tgz","fileCount":11,"unpackedSize":70204,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/react-hook-form-storage@1.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDGD4rtde22bzwSdRa/CpVQ6yIeG/APv710nmDatJ0RYwIhAJzkHaL0T2dfjGOvJDwL/VcI4k48uewVXjIG2gP7PYbo"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:cbcb4657-99b8-48f5-be44-165f220654cf"}},"directories":{},"maintainers":[{"name":"franco.gabriel92","email":"francog.sanchez@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/react-hook-form-storage_1.3.1_1785880898094_0.38357713550318295"},"_hasShrinkwrap":false}},"time":{"created":"2025-08-05T21:52:56.738Z","modified":"2026-08-04T22:01:38.567Z","0.1.0":"2023-11-27T21:28:13.375Z","1.0.0":"2025-08-05T21:52:56.920Z","1.1.0":"2025-08-07T18:27:22.094Z","1.2.0":"2025-10-14T10:13:50.719Z","1.3.0":"2026-02-18T23:03:16.425Z","1.3.1":"2026-08-04T22:01:38.258Z"},"bugs":{"url":"https://github.com/francogabriel92/react-hook-form-storage/issues"},"author":{"name":"Franco Sánchez","email":"francog.sanchez@hotmail.com"},"license":"MIT","homepage":"https://github.com/francogabriel92/react-hook-form-storage#readme","keywords":["react","react-hook-form","react-hook-forms","react-hook-form-persist","form","persist","persistent","persistent-storage","localstorage","sessionstorage","autosave","draft","ssr","nextjs"],"repository":{"type":"git","url":"git+https://github.com/francogabriel92/react-hook-form-storage.git"},"description":"Persist React Hook Form state to localStorage/sessionStorage/async storage — TypeScript-first, SSR-safe, with serializers & debounce.","maintainers":[{"name":"franco.gabriel92","email":"francog.sanchez@gmail.com"}],"readme":"# React Hook Form Storage\n\n[![npm version](https://img.shields.io/npm/v/react-hook-form-storage.svg)](https://www.npmjs.com/package/react-hook-form-storage)\n![npm package minimized gzipped size](https://img.shields.io/bundlejs/size/react-hook-form-storage)\n![Tests](https://github.com/francogabriel92/react-hook-form-storage/actions/workflows/test.yml/badge.svg)\n[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nPersist React Hook Form state to `localStorage`, `sessionStorage`, or any custom/async storage — TypeScript-first, SSR-safe, with field serializers and debounced auto-save.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [API Reference](#api-reference)\n- [Configuration Options](#configuration-options)\n- [Advanced Usage](#advanced-usage)\n- [Examples](#examples)\n- [Migrating from react-hook-form-persist](#migrating-from-react-hook-form-persist)\n- [TypeScript Support](#typescript-support)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Installation\n\n```bash\nnpm install react-hook-form-storage\n```\n\n```bash\nyarn add react-hook-form-storage\n```\n\n```bash\npnpm add react-hook-form-storage\n```\n\n## Peer Dependencies\n\nThis library requires the following peer dependencies:\n\n- `react >= 16.8.0`\n- `react-hook-form >= 7.0.0`\n\n## Quick Start\n\nHere's a basic example of how to use the library:\n\n```typescript\nimport { useForm } from 'react-hook-form';\nimport { useFormStorage } from 'react-hook-form-storage';\n\ninterface FormData {\n  username: string;\n  email: string;\n  age: number;\n}\n\nfunction MyForm() {\n  const form = useForm<FormData>({\n    defaultValues: {\n      username: '',\n      email: '',\n      age: 0,\n    },\n  });\n\n  const { isRestored, isLoading } = useFormStorage('my-form', form, {\n    // Options go here\n  });\n\n  const onSubmit = (data: FormData) => {\n    console.log(data);\n  };\n\n  if (isLoading) {\n    return <div>Loading saved data...</div>;\n  }\n\n  return (\n    <form onSubmit={form.handleSubmit(onSubmit)}>\n      <input {...form.register('username')} placeholder=\"Username\" />\n      <input {...form.register('email')} placeholder=\"Email\" />\n      <input {...form.register('age', { valueAsNumber: true })} type=\"number\" placeholder=\"Age\" />\n      <button type=\"submit\">Submit</button>\n      {isRestored && <p>Form data restored from storage!</p>}\n    </form>\n  );\n}\n```\n\n## API Reference\n\n`useFormStorage<T>(key: string, form: UseFormReturn<T>, options?: UseFormStorageOptions<T>)`\n\nThe main hook that provides storage functionality for your React Hook Form.\n\n#### Parameters\n\n- **`key`** (`string`): A unique identifier for storing the form data in storage\n- **`form`** (`UseFormReturn<T>`): The form instance returned by `useForm()`\n- **`options`** (`UseFormStorageOptions<T>`): Configuration options (optional)\n\n#### Returns\n\n```typescript\n{\n  isRestored: boolean;          // Indicates if data was restored from storage\n  isLoading: boolean;           // Indicates if restoration is in progress\n  save: () => Promise<void>;    // Manually save the current form values\n  clear: () => Promise<void>;   // Clear the stored data\n  restore: () => Promise<void>; // Manually restore stored values into the form\n}\n```\n\n## Configuration Options\n\n### `UseFormStorageOptions<T>`\n\n```typescript\ninterface UseFormStorageOptions<T extends FieldValues> {\n  storage?: Storage | UseFormStorageAdapter; // Storage implementation (default: localStorage)\n  included?: Array<Path<T>>; // Fields to include in storage\n  excluded?: Array<Path<T>>; // Fields to exclude from storage\n  onRestore?: (data: Partial<T>) => void; // Callback when data is restored\n  onSave?: (data: Partial<T>) => void; // Callback when data is saved\n  debounce?: number; // Debounce delay in milliseconds\n  dirty?: boolean; // Mark fields as dirty when restored\n  touched?: boolean; // Mark fields as touched when restored\n  validate?: boolean; // Validate fields when restored\n  serializer?: Record<Path<T>, Serializer<T, Path<T>>>; // Custom serializers\n  autoSave?: boolean; // Enable/disable automatic saving\n  autoRestore?: boolean; // Enable/disable automatic restoration\n}\n```\n\n### Option Details\n\n#### `storage`\n\n- **Type**: `Storage | UseFormStorageAdapter`\n- **Default**: `localStorage`\n- **Description**: The storage implementation to use. Can be `localStorage`, `sessionStorage`, or a custom (optionally async) storage object that implements `getItem`/`setItem`/`removeItem`. The default is resolved lazily, so the hook is safe to render on the server (see [Server-Side Rendering](#server-side-rendering)).\n\n```typescript\n// Use sessionStorage instead of localStorage\nuseFormStorage('my-form', form, {\n  storage: sessionStorage,\n});\n\n// Custom storage implementation\nconst customStorage = {\n  getItem: (key: string) => {\n    // Custom get logic\n    return myCustomStore.get(key);\n  },\n  setItem: (key: string, value: string) => {\n    // Custom set logic\n    myCustomStore.set(key, value);\n  },\n  removeItem: (key: string) => {\n    // Custom remove logic\n    myCustomStore.delete(key);\n  },\n};\n\nuseFormStorage('my-form', form, {\n  storage: customStorage,\n});\n```\n\n#### `included` / `excluded`\n\n- **Type**: `Array<Path<T>>`\n- **Description**: Control which fields are stored. Use `included` to specify only certain fields, or `excluded` to omit specific fields.\n\n```typescript\n// Only store username and email\nuseFormStorage('my-form', form, {\n  included: ['username', 'email'],\n});\n\n// Store all fields except password\nuseFormStorage('my-form', form, {\n  excluded: ['password'],\n});\n```\n\n#### `onRestore` / `onSave`\n\n- **Type**: `(data: Partial<T>) => void`\n- **Description**: Callbacks that are triggered when data is restored from storage or saved to storage.\n\n```typescript\nuseFormStorage('my-form', form, {\n  onRestore: (data) => {\n    console.log('Data restored:', data);\n    // Custom logic after restoration\n  },\n  onSave: (data) => {\n    console.log('Data saved:', data);\n    // Custom logic after saving\n  },\n});\n```\n\n#### `debounce`\n\n- **Type**: `number`\n- **Default**: `undefined` (no debouncing)\n- **Description**: Debounce delay in milliseconds for auto-saving. Useful to prevent excessive storage writes.\n\n```typescript\n// Save data 500ms after the user stops typing\nuseFormStorage('my-form', form, {\n  debounce: 500,\n});\n```\n\n#### `dirty` / `touched` / `validate`\n\n- **Type**: `boolean`\n- **Default**: `false`\n- **Description**: Control form state when restoring data from storage.\n\n```typescript\nuseFormStorage('my-form', form, {\n  dirty: true, // Mark restored fields as dirty\n  touched: true, // Mark restored fields as touched\n  validate: true, // Validate restored fields\n});\n```\n\n#### `serializer`\n\n- **Type**: `Record<Path<T>, Serializer<T, Path<T>>>`\n- **Description**: Custom serialization/deserialization for specific fields. Both directions are optional — if you omit `serialize` (or `deserialize`), that direction falls back to the identity transform and the field keeps its value.\n\n```typescript\ninterface Serializer<T, K extends Path<T>> {\n  serialize?: (value: PathValue<T, K>) => any;\n  deserialize?: (value: any) => PathValue<T, K>;\n}\n\n// Example: Custom date serialization\nuseFormStorage('my-form', form, {\n  serializer: {\n    birthDate: {\n      serialize: (date: Date) => date.toISOString(),\n      deserialize: (dateString: string) => new Date(dateString),\n    },\n  },\n});\n```\n\n#### `autoSave`\n\n- **Type**: `boolean`\n- **Default**: `true`\n- **Description**: Enable or disable automatic saving. When disabled, use the returned `save` function for manual control.\n\n```typescript\nconst { save } = useFormStorage('my-form', form, {\n  autoSave: false,\n});\n\n// Manually save when needed\nconst handleSave = () => {\n  save();\n};\n```\n\n#### `autoRestore`\n\n- **Type**: `boolean`\n- **Default**: `true`\n- **Description**: Enable or disable automatic restoration of form data from storage. When disabled, you can manually restore data using the `restore` function returned by the hook.\n\n```typescript\nconst { restore } = useFormStorage('my-form', form, {\n  autoRestore: false, // Disable automatic restoration\n});\n\n// Manually restore data when needed\nconst handleRestore = () => {\n  restore();\n};\n```\n\n## Advanced Usage\n\n### Manual Save Control\n\n```typescript\nfunction ManualSaveForm() {\n  const form = useForm<FormData>();\n\n  const { save, isRestored } = useFormStorage('manual-form', form, {\n    autoSave: false, // Disable auto-save\n  });\n\n  const handleManualSave = () => {\n    save(); // Manually trigger save\n  };\n\n  return (\n    <form>\n      {/* Form fields */}\n      <button type=\"button\" onClick={handleManualSave}>\n        Save Draft\n      </button>\n    </form>\n  );\n}\n```\n\n### Complex Data Serialization\n\n```typescript\ninterface ComplexFormData {\n  user: {\n    name: string;\n    preferences: string[];\n  };\n  settings: Map<string, any>;\n  createdAt: Date;\n}\n\nfunction ComplexForm() {\n  const form = useForm<ComplexFormData>();\n\n  useFormStorage('complex-form', form, {\n    serializer: {\n      'settings': {\n        serialize: (map: Map<string, any>) => Object.fromEntries(map),\n        deserialize: (obj: Record<string, any>) => new Map(Object.entries(obj)),\n      },\n      'createdAt': {\n        serialize: (date: Date) => date.toISOString(),\n        deserialize: (dateString: string) => new Date(dateString),\n      },\n    },\n  });\n\n  return (\n    // Form JSX\n  );\n}\n```\n\n### Conditional Storage\n\n```typescript\nfunction ConditionalStorageForm() {\n  const [enableStorage, setEnableStorage] = useState(true);\n  const form = useForm<FormData>();\n\n  useFormStorage('conditional-form', form, {\n    autoSave: enableStorage,\n    onSave: (data) => {\n      if (enableStorage) {\n        console.log('Data saved:', data);\n      }\n    },\n  });\n\n  return (\n    <form>\n      <label>\n        <input\n          type=\"checkbox\"\n          checked={enableStorage}\n          onChange={(e) => setEnableStorage(e.target.checked)}\n        />\n        Enable auto-save\n      </label>\n      {/* Other form fields */}\n    </form>\n  );\n}\n```\n\n## Examples\n\n### Basic Contact Form\n\n```typescript\nimport { useForm } from 'react-hook-form';\nimport { useFormStorage } from 'react-hook-form-storage';\n\ninterface ContactForm {\n  name: string;\n  email: string;\n  message: string;\n}\n\nexport function ContactForm() {\n  const form = useForm<ContactForm>({\n    defaultValues: {\n      name: '',\n      email: '',\n      message: '',\n    },\n  });\n\n  const { isRestored } = useFormStorage('contact-form', form);\n\n  return (\n    <form onSubmit={form.handleSubmit(console.log)}>\n      <div>\n        <label>Name:</label>\n        <input {...form.register('name')} />\n      </div>\n\n      <div>\n        <label>Email:</label>\n        <input {...form.register('email')} type=\"email\" />\n      </div>\n\n      <div>\n        <label>Message:</label>\n        <textarea {...form.register('message')} />\n      </div>\n\n      <button type=\"submit\">Send</button>\n\n      {isRestored && (\n        <p style={{ color: 'green' }}>\n          Your previous input has been restored!\n        </p>\n      )}\n    </form>\n  );\n}\n```\n\n### E-commerce Checkout Form\n\n```typescript\ninterface CheckoutForm {\n  shippingAddress: {\n    street: string;\n    city: string;\n    zipCode: string;\n  };\n  billingAddress: {\n    street: string;\n    city: string;\n    zipCode: string;\n  };\n  paymentMethod: 'credit' | 'debit' | 'paypal';\n  cardNumber: string;\n  expiryDate: string;\n}\n\nexport function CheckoutForm() {\n  const form = useForm<CheckoutForm>();\n\n  useFormStorage('checkout-form', form, {\n    excluded: ['cardNumber', 'expiryDate'], // Exclude sensitive payment info\n    debounce: 1000,\n    onSave: (data) => {\n      console.log('Checkout progress saved');\n    },\n  });\n\n  return (\n    <form>\n      {/* Shipping address fields */}\n      <fieldset>\n        <legend>Shipping Address</legend>\n        <input {...form.register('shippingAddress.street')} placeholder=\"Street\" />\n        <input {...form.register('shippingAddress.city')} placeholder=\"City\" />\n        <input {...form.register('shippingAddress.zipCode')} placeholder=\"ZIP Code\" />\n      </fieldset>\n\n      {/* Billing address fields */}\n      <fieldset>\n        <legend>Billing Address</legend>\n        <input {...form.register('billingAddress.street')} placeholder=\"Street\" />\n        <input {...form.register('billingAddress.city')} placeholder=\"City\" />\n        <input {...form.register('billingAddress.zipCode')} placeholder=\"ZIP Code\" />\n      </fieldset>\n\n      {/* Payment fields (not persisted) */}\n      <fieldset>\n        <legend>Payment Information</legend>\n        <select {...form.register('paymentMethod')}>\n          <option value=\"credit\">Credit Card</option>\n          <option value=\"debit\">Debit Card</option>\n          <option value=\"paypal\">PayPal</option>\n        </select>\n        <input {...form.register('cardNumber')} placeholder=\"Card Number\" />\n        <input {...form.register('expiryDate')} placeholder=\"MM/YY\" />\n      </fieldset>\n\n      <button type=\"submit\">Complete Order</button>\n    </form>\n  );\n}\n```\n\n## Migrating from react-hook-form-persist\n\nComing from [`react-hook-form-persist`](https://github.com/tiaanduplessis/react-hook-form-persist)? The two libraries solve the same problem, so migrating is mostly a rename. The main structural difference is how the hook is called: `react-hook-form-persist` takes `watch` and `setValue` inside the options object, while `react-hook-form-storage` takes the whole `form` instance as its second argument.\n\n```tsx\n// Before — react-hook-form-persist\nimport useFormPersist from 'react-hook-form-persist';\n\nconst form = useForm();\nconst { watch, setValue } = form;\n\nuseFormPersist('my-form', {\n  watch,\n  setValue,\n  storage: window.localStorage,\n  exclude: ['password'],\n  onDataRestored: (data) => console.log(data),\n});\n\n// After — react-hook-form-storage\nimport { useFormStorage } from 'react-hook-form-storage';\n\nconst form = useForm();\n\nuseFormStorage('my-form', form, {\n  storage: window.localStorage,\n  excluded: ['password'],\n  onRestore: (data) => console.log(data),\n});\n```\n\n### Option mapping\n\n| `react-hook-form-persist` | `react-hook-form-storage` | Notes |\n| --- | --- | --- |\n| `useFormPersist(key, { watch, setValue, ... })` | `useFormStorage(key, form, { ... })` | Pass the `form` instance; `watch`/`setValue` are no longer passed manually. |\n| `storage` (defaults to `sessionStorage`) | `storage` (defaults to `localStorage`) | ⚠️ The default storage differs — see the note below. |\n| `exclude` | `excluded` | |\n| `include` | `included` | |\n| `onDataRestored` | `onRestore` | |\n| `validate` | `validate` | |\n| `dirty` | `dirty` | |\n| `touch` | `touched` | |\n| `timeout` / `onTimeout` / `accessKey` | _no direct equivalent_ | There is no built-in expiry. Use a custom `storage` adapter if you need TTL semantics. |\n| _not available_ | `onSave`, `debounce`, `serializer`, `autoSave`, `autoRestore` | Extra capabilities offered by this library. |\n\n> **⚠️ Default storage changes.** `react-hook-form-persist` defaults to `sessionStorage`, while `react-hook-form-storage` defaults to `localStorage`. If you relied on the default, pass `storage: sessionStorage` explicitly to keep the same behavior.\n\nBoth hooks return a `clear()` function to remove the persisted data. `react-hook-form-storage` additionally returns `isRestored`, `isLoading`, `save()` and `restore()` for finer control over the lifecycle (see [API Reference](#api-reference)).\n\n## TypeScript Support\n\nThis library is written in TypeScript and provides full type safety:\n\n```typescript\n// Types are automatically inferred from your form schema\ninterface UserForm {\n  name: string;\n  age: number;\n  preferences: string[];\n}\n\nconst form = useForm<UserForm>();\n\n// TypeScript will ensure field names are valid\nuseFormStorage('user-form', form, {\n  included: ['name', 'age'], // ✅ Valid field names\n  excluded: ['invalid'], // ❌ TypeScript error - 'invalid' doesn't exist\n});\n```\n\n## Server-Side Rendering\n\nThe hook is SSR-safe: the default `localStorage` is resolved lazily and only in the browser, so it can be rendered in Next.js (or any SSR framework) without guards. On the server, storage operations are no-ops and `isRestored` starts as `false`; restoration runs on the client after hydration.\n\n## Browser Compatibility\n\n- Modern browsers with ES2017+ support\n- localStorage/sessionStorage API support\n- React 16.8+ (hooks support)\n\n## Performance Considerations\n\n- Use `debounce` option to limit storage writes\n- Consider `included`/`excluded` options for large forms\n- The library uses React's built-in optimization (useCallback, useMemo)\n- Storage operations are performed asynchronously when possible\n\n```typescript\nuseFormStorage('my-form', form, {\n  onSave: (data) => {\n    // This callback only fires on successful saves\n    console.log('Data saved successfully');\n  },\n  onRestore: (data) => {\n    // This callback only fires on successful restoration\n    console.log('Data restored successfully');\n  },\n});\n```\n\n## Contributing\n\nContributions are welcome!\n\n## License\n\nMIT License.\n\n---\n\nFor more examples and advanced usage patterns, please visit our [GitHub repository](https://github.com/francogabriel92/react-hook-form-storage).\n","readmeFilename":"README.md"}