zod-resolver-lite
v1.0.0
Published
A tiny, dependency-free Zod resolver for React Hook Form
Maintainers
Readme
🛠 zod-resolver-lite
A tiny, dependency-free Zod resolver for React Hook Form
Features • Installation • Usage • API • Why This Exists
✨ Features
| Feature | Description |
|---------|-------------|
| 🪶 Lightweight | ~50 lines of code, zero dependencies beyond peer deps |
| 🔄 Zod v4+ Ready | No deprecated imports, fully compatible with latest Zod |
| 📦 Nested Support | Handles items[0].name array paths correctly |
| 🎯 All Errors Mode | Full criteriaMode: "all" support |
| 🛡️ Type Safe | 100% TypeScript with full inference |
| ⚡ Async First | Built for async validation out of the box |
📦 Installation
npm install zod-resolver-lite zod react-hook-form# or with your favorite package manager
pnpm add zod-resolver-lite zod react-hook-form
yarn add zod-resolver-lite zod react-hook-formPeer Dependencies
| Package | Version |
|---------|---------|
| zod | ^4.0.0 |
| react-hook-form | ^7.0.0 |
🚀 Usage
Basic Example
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "zod-resolver-lite";
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
type FormData = z.infer<typeof schema>;
export function LoginForm() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<FormData>({
resolver: zodResolver(schema),
});
return (
<form onSubmit={handleSubmit((data) => console.log(data))}>
<input {...register("email")} placeholder="Email" />
{errors.email && <span>{errors.email.message}</span>}
<input {...register("password")} type="password" placeholder="Password" />
{errors.password && <span>{errors.password.message}</span>}
<button type="submit">Login</button>
</form>
);
}Nested Arrays
Perfect for dynamic forms with field arrays:
const schema = z.object({
users: z.array(
z.object({
name: z.string().min(2, "Name too short"),
email: z.string().email("Invalid email"),
})
),
});
// Error paths are formatted correctly:
// errors["users[0].name"] ✅
// errors["users[1].email"] ✅Criteria Mode: All Errors
Collect all validation failures for a single field:
const schema = z.object({
password: z
.string()
.min(8, "At least 8 characters")
.regex(/[A-Z]/, "Need uppercase")
.regex(/[0-9]/, "Need a number"),
});
const { formState: { errors } } = useForm({
resolver: zodResolver(schema),
criteriaMode: "all", // 👈 Enable all errors
});
// errors.password.types = {
// too_small: "At least 8 characters",
// invalid_string: "Need uppercase"
// }📖 API
zodResolver(schema)
Creates a resolver function compatible with React Hook Form.
function zodResolver<T extends FieldValues>(
schema: ZodTypeAny
): Resolver<T>| Parameter | Type | Description |
|-----------|------|-------------|
| schema | ZodTypeAny | Any Zod schema |
Returns: A Resolver<T> function for React Hook Form
❓ Why This Exists
The Problem
Using @hookform/resolvers/zod can fail in surprising ways:
❌ Cannot find module '@hookform/resolvers/zod'
❌ Could not find a declaration file for module
❌ Import "ZodSchema" is deprecated in Zod v4Root causes:
| Issue | Affected | |-------|----------| | Sub-path exports not resolving | Vite, Next.js 13+, TS projects | | Deprecated Zod imports | Zod v4+ users | | Bundler resolution quirks | ESM/CJS mixed environments |
The Solution
zod-resolver-lite is a self-contained, ~50-line resolver that:
- ✅ Has zero sub-path import magic — just works
- ✅ Uses only modern, non-deprecated Zod APIs
- ✅ Ships as pure ESM with TypeScript declarations
- ✅ Can be copy-pasted into your project if you prefer
🧪 Testing
We use Vitest with 100% coverage of critical paths:
npm test # Run all tests
npm run test:watch # Watch mode
npm run test:coverage # With coverage reportTest Coverage
| Feature | Status |
|---------|--------|
| Schema passes → returns values | ✅ |
| Schema fails → returns errors | ✅ |
| Nested array paths items[0].name | ✅ |
| criteriaMode: "all" | ✅ |
🏗️ Build
npm run buildOutputs to dist/:
index.js— ESM bundleindex.d.ts— TypeScript declarations
🤝 Contributing
Contributions are welcome! Feel free to:
- 🐛 Report bugs
- 💡 Suggest features
- 🔧 Submit PRs
# Clone & install
git clone https://github.com/foudhilriahi/zod-resolver-lite.git
cd zod-resolver-lite
npm install
# Run tests
npm test📄 License
MIT © foudhilriahi
If this helped you, consider giving it a ⭐
Made with ❤️ for the React Hook Form + Zod community
