https://github.com/alok5953/isovalid
A lightweight, isomorphic data validation library for TypeScript/JavaScript
https://github.com/alok5953/isovalid
backend data-validation express form-validation frontend isomorphic javascript nextjs nodejs react schema-validation type-safety typescript validation vue
Last synced: 3 months ago
JSON representation
A lightweight, isomorphic data validation library for TypeScript/JavaScript
- Host: GitHub
- URL: https://github.com/alok5953/isovalid
- Owner: alok5953
- License: mit
- Created: 2025-03-06T16:14:10.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-10T14:21:34.000Z (over 1 year ago)
- Last Synced: 2026-01-03T14:30:39.947Z (6 months ago)
- Topics: backend, data-validation, express, form-validation, frontend, isomorphic, javascript, nextjs, nodejs, react, schema-validation, type-safety, typescript, validation, vue
- Language: TypeScript
- Size: 67.4 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# IsoValid
[](https://badge.fury.io/js/%40alok5953%2Fisovalid)
[](https://opensource.org/licenses/MIT)
[](https://www.typescriptlang.org/)
[](https://github.com/alok5953/isovalid/blob/main/CONTRIBUTING.md)
A lightweight, isomorphic data validation library for TypeScript and JavaScript that works seamlessly in both browser and Node.js environments. IsoValid is designed to provide a unified validation experience across your entire application stack.
> Created and maintained by [Alok Kaushik](https://github.com/alok5953) | [alokkaushik5953@gmail.com](mailto:alokkaushik5953@gmail.com)
## Why IsoValid?
In modern web applications, data validation is crucial at multiple layers:
- Client-side form validation for immediate user feedback
- API request/response validation for data integrity
- Server-side validation for security
Traditionally, developers had to:
1. Write separate validation logic for frontend and backend
2. Maintain multiple validation libraries
3. Deal with inconsistencies between environments
IsoValid solves these problems by providing:
- đ **True Isomorphic Support** - The exact same validation code runs in both browser and Node.js
- đ¯ **TypeScript-First Design** - Built from the ground up with TypeScript for excellent type inference
- đĒļ **Minimal Bundle Size** - Core validation features without unnecessary bloat
- đ **Developer-Friendly API** - Intuitive, chainable interface for building schemas
- ⥠**High Performance** - Optimized validation with minimal overhead
- đ¨ **Extensible Design** - Easy to add custom validators and error messages
## Installation
```bash
npm install isovalid
```
## Architecture
IsoValid is built on a flexible, extensible architecture:
### Core Components
1. **Base Schema Class**
- Abstract foundation for all schema types
- Handles common validation logic
- Manages optional/nullable states
2. **Type-Specific Schemas**
- StringSchema: String validation with length, pattern, format checks
- NumberSchema: Numeric validation with range, integer, sign checks
- More types coming soon (Boolean, Array, Object)
3. **Validation Pipeline**
- Multi-stage validation process
- Custom validator support
- Detailed error reporting
## API Reference
### String Validation
```typescript
const stringSchema = v.string()
.min(2) // Minimum length
.max(50) // Maximum length
.email() // Email format
.matches(/regex/) // Custom regex pattern
.trimmed() // Auto-trim whitespace
.setOptional() // Allow undefined
.setNullable() // Allow null
.custom(value => value.includes('@') ? null : 'Must include @'); // Custom validation
```
### Number Validation
```typescript
const numberSchema = v.number()
.min(0) // Minimum value
.max(100) // Maximum value
.integer() // Must be an integer
.positive() // Must be > 0
.setOptional() // Allow undefined
.setNullable(); // Allow null
```
### Validation Results
All validations return a structured result:
```typescript
interface ValidationResult {
valid: boolean;
errors: Array<{
path: string[];
message: string;
}>;
}
```
## Real-World Examples
### 1. React Form Validation
```typescript
import { v } from 'isovalid';
import { useState, FormEvent } from 'react';
const userSchema = {
username: v.string().min(3).max(20),
email: v.string().email(),
age: v.number().integer().min(18)
};
function RegistrationForm() {
const [formData, setFormData] = useState({
username: '',
email: '',
age: ''
});
const [errors, setErrors] = useState>({});
const validateField = (field: keyof typeof userSchema, value: any) => {
const result = userSchema[field].validate(value);
return result.valid ? null : result.errors[0].message;
};
const handleSubmit = (e: FormEvent) => {
e.preventDefault();
const newErrors: Record = {};
// Validate all fields
Object.entries(formData).forEach(([field, value]) => {
const error = validateField(field as keyof typeof userSchema, value);
if (error) newErrors[field] = error;
});
if (Object.keys(newErrors).length === 0) {
// Form is valid, submit data
console.log('Submitting:', formData);
} else {
setErrors(newErrors);
}
};
return (
setFormData(prev => ({ ...prev, username: e.target.value }))}
placeholder="Username"
/>
{errors.username && {errors.username}}
{/* Similar fields for email and age */}
Register
);
}
```
### 2. Express API Validation
```typescript
import express from 'express';
import { v } from 'isovalid';
const app = express();
app.use(express.json());
const productSchema = {
name: v.string().min(3).max(100),
price: v.number().min(0),
category: v.string().custom(value =>
['electronics', 'books', 'clothing'].includes(value)
? null
: 'Invalid category'
)
};
app.post('/api/products', (req, res) => {
const errors = Object.entries(productSchema)
.map(([field, schema]) => ({
field,
result: schema.validate(req.body[field])
}))
.filter(({ result }) => !result.valid)
.map(({ field, result }) => ({
field,
message: result.errors[0].message
}));
if (errors.length > 0) {
return res.status(400).json({ errors });
}
// Process valid product data
const product = req.body;
// Save to database, etc.
res.status(201).json(product);
});
```
## Best Practices
1. **Schema Reuse**
- Define schemas once and share between frontend and backend
- Keep schemas in a shared directory accessible to both environments
2. **Type Safety**
- Leverage TypeScript's type inference with IsoValid
- Define interfaces that match your schemas
3. **Performance**
- Create schemas outside request handlers
- Reuse schema instances when possible
4. **Error Handling**
- Always check the `valid` property before accessing data
- Provide user-friendly error messages in custom validators
## Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
1. Fork the repository
2. Create your feature branch
3. Write tests for your changes
4. Submit a pull request
## Testing
IsoValid uses Jest for testing. Run the test suite:
```bash
npm test
```
Current test coverage: >88%
## Roadmap
- [ ] Array schema type
- [ ] Object schema type with nested validation
- [ ] Custom error message templates
- [ ] Async validation support
- [ ] Integration with popular form libraries
- [ ] Schema composition and inheritance
## License
MIT Š [IsoValid](LICENSE)
## Support
- GitHub Issues: Report bugs and feature requests
- Documentation: Check our [Wiki](https://github.com/isovalid/isovalid/wiki)
- Stack Overflow: Tag your questions with `isovalid`