A lightweight, fast, and synchronous JavaScript validation library. Built for developers who need performance without the bloat.
Nope is a minimal validation library that prioritizes speed and simplicity. Inspired by Yup, Nope provides a familiar API while being significantly smaller and ~17x faster than Yup by focusing exclusively on synchronous validationβwhich covers the vast majority of use cases.
See benchmark results for detailed performance metrics and test specifications.
- β‘ Fast - Optimized for performance with synchronous validation
- π¦ Small - Minimal bundle size, maximum efficiency
- π― Simple - Clean, intuitive API that's easy to learn
- π Type Safe - Full TypeScript support out of the box
- π« No Exceptions - Returns error objects instead of throwing errors
- π Framework Ready - Works seamlessly with React Hook Form and Formik
Unlike traditional validators that throw errors, Nope returns error objects. If validation passes, it returns undefined. This approach is more predictable and easier to work with in modern JavaScript applications.
npm install nope-validator
# or use your preferred package manager (pnpm, yarn, bun, etc)import Nope from 'nope-validator';
// Define your validation schema
const UserSchema = Nope.object().shape({
name: Nope.string()
.atLeast(5, 'Please provide a longer name')
.atMost(255, 'Name is too long!'),
email: Nope.string().email().required(),
confirmEmail: Nope.string()
.oneOf([Nope.ref('email')], 'Emails must match')
.required(),
});
// Validate data
const errors = UserSchema.validate({
name: 'John',
email: '[email protected]',
confirmEmail: '[email protected]',
});
// Returns: { name: 'Please provide a longer name' }
const valid = UserSchema.validate({
name: 'Jonathan Livingston',
email: '[email protected]',
confirmEmail: '[email protected]',
});
// Returns: undefined (no errors)Nope works seamlessly with React Hook Form using the official resolver:
import { nopeResolver } from '@hookform/resolvers/nope';
import { useForm } from 'react-hook-form';
import * as Nope from 'nope-validator';
const schema = Nope.object().shape({
username: Nope.string().required('Username is required'),
password: Nope.string().required('Password is required'),
});
function LoginForm({ onSubmit }) {
const {
register,
formState: { errors },
handleSubmit,
} = useForm({
resolver: nopeResolver(schema),
});
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('username')} />
{errors.username && <div>{errors.username.message}</div>}
<input type="password" {...register('password')} />
{errors.password && <div>{errors.password.message}</div>}
<button type="submit">Submit</button>
</form>
);
}Use Nope with Formik by passing the validation function to the validate prop:
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Nope from 'nope-validator';
const schema = Nope.object().shape({
username: Nope.string().required('Username is required'),
password: Nope.string().required('Password is required'),
});
function LoginForm() {
return (
<Formik
initialValues={{ username: '', password: '' }}
validate={(values) => schema.validate(values)}
onSubmit={(values) => console.log('Submitted', values)}
>
<Form>
<Field type="text" name="username" />
<ErrorMessage name="username" component="div" />
<Field type="password" name="password" />
<ErrorMessage name="password" component="div" />
<button type="submit">Submit</button>
</Form>
</Formik>
);
}For complete API documentation, examples, and advanced usage, visit the documentation wiki.
We welcome contributions! Please see our Contributing Guide for details on how to get started.