https://github.com/jasgigli/gigli.js
Metamorphic, type-safe validation engine for TypeScript. Unified runtime, builder, decorator, and string rule support.
https://github.com/jasgigli/gigli.js
cli engine gigli gigli-js jasgigli javascript json library npm-package package typescript validation validator
Last synced: 6 months ago
JSON representation
Metamorphic, type-safe validation engine for TypeScript. Unified runtime, builder, decorator, and string rule support.
- Host: GitHub
- URL: https://github.com/jasgigli/gigli.js
- Owner: jasgigli
- License: mit
- Created: 2025-07-18T08:51:36.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2025-07-18T14:13:23.000Z (12 months ago)
- Last Synced: 2025-10-11T13:50:04.617Z (9 months ago)
- Topics: cli, engine, gigli, gigli-js, jasgigli, javascript, json, library, npm-package, package, typescript, validation, validator
- Language: JavaScript
- Homepage: https://www.npmjs.com/package/gigli.js
- Size: 1.67 MB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
Gigli.js
Metamorphic, type-safe validation engine for TypeScript & JavaScript
Unified runtime, builder, decorator, and string rule support. Generate OpenAPI/JSON Schema. Use in Node.js, React, Express, NestJS, and more.
---
# π Why Gigli.js?
Gigli.js is not just another validator. It's a metamorphic engine that adapts to your coding styleβbuilder, decorator, or string rulesβwithout sacrificing type safety, power, or extensibility.
- π§© Unified API: Mix & match builder, decorator, and string rules
- π¦Ύ Type Inference: Full TypeScript support, everywhere
- π οΈ Extensible: Custom rules, transformers, and definitions
- π Detailed Error Tracing: See exactly why validation failed
- ποΈ Schema Generation: OpenAPI & JSON Schema out of the box
- β‘ Zero dependencies, works in Node.js, browsers, and modern runtimes
---
# π¦ Installation
```bash
npm install gigli.js
```
---
# π Quick Start
```typescript
import { v } from 'gigli.js';
const UserSchema = v.object({
username: v.string().min(3),
email: v.string().email(),
});
const result = UserSchema.safeParse({ username: 'bob', email: 'bob@email.com' });
console.log(result.success); // true
```
---
# π± Progressive Examples
## 1οΈβ£ Basic Validation
```typescript
import { v } from 'gigli.js';
const UserSchema = v.object({
username: v.string().min(3),
email: v.string().email(),
});
UserSchema.parse({ username: 'ab', email: 'bad' }); // Throws with detailed error
```
## 2οΈβ£ Type Inference
```typescript
type User = v.infer;
// User: { username: string; email: string }
```
## 3οΈβ£ Error Handling & Flattening
```typescript
try {
UserSchema.parse({ username: 'ab', email: 'bad' });
} catch (err) {
console.log(err.flatten());
/*
{
input: { username: 'ab', email: 'bad' },
errors: [
{ path: ['username'], message: 'String must be at least 3 characters' },
{ path: ['email'], message: 'Invalid email address' }
]
}
*/
}
```
## 4οΈβ£ Advanced Builder Features
```typescript
const PostSchema = v.object({
id: v.string().uuid(),
title: v.string().min(5).max(100),
tags: v.array(v.string().min(2)).optional(),
author: UserSchema, // Schemas are composable!
status: v.string().from('enum:values=draft|published|archived'),
meta: v.union([
v.object({ type: v.literal('text'), content: v.string() }),
v.object({ type: v.literal('image'), url: v.string().url() })
])
});
```
## 5οΈβ£ Nested Objects, Arrays, Optionals, Enums
```typescript
const BlogSchema = v.object({
posts: v.array(PostSchema),
owner: v.object({
id: v.string().uuid(),
name: v.string(),
roles: v.array(v.string().from('enum:values=admin|editor|user')),
}),
settings: v.object({
commentsEnabled: v.boolean().optional(),
theme: v.string().default('light'),
})
});
```
## 6οΈβ£ Decorator API (for OOP & NestJS fans)
```typescript
import { v, ValidatedModel } from 'gigli.js';
@v.Refine((dto) => dto.password === dto.passwordConfirm, {
message: "Passwords don't match",
path: ['passwordConfirm'],
})
class CreateUserDto extends ValidatedModel {
@v.Rule(v.string().email())
email: string;
@v.Rule('string:min=8,max=50')
password: string;
@v.Rule(v.string())
passwordConfirm: string;
}
const userDto = CreateUserDto.from({
email: 'foo@bar.com',
password: 'secret123',
passwordConfirm: 'secret123',
});
```
## 7οΈβ£ Pipeline API (for complex workflows)
```typescript
const OrderPipeline = v.pipeline()
.transform((data) => ({ ...data, orderId: data.id.toLowerCase() }))
.validate(v.object({ orderId: v.string().min(1) }))
.dispatch('paymentMethod', {
'credit_card': v.object({ card: v.string().creditCard() }),
'paypal': v.object({ email: v.string().email() }),
})
.refine((order) => order.total > 0, { message: 'Order total must be positive' })
.effect({
onSuccess: (data) => console.log('Order Validated', data.orderId),
onFailure: (trace) => console.error('Order Failed', trace),
});
const result = OrderPipeline.safeParse(orderData);
```
## 8οΈβ£ Custom Rules, Transformers, and Definitions
```typescript
v.registerRule('isEven', (value) => typeof value === 'number' && value % 2 === 0);
v.registerTransformer('trim', (value) => typeof value === 'string' ? value.trim() : value);
v.define('slug', 'string:min=3|regex:^[a-z0-9-]+$');
const SlugSchema = v.string().from('slug').transform('trim');
```
---
# π§βπ» CLI Usage
```sh
npx gigli codegen --schema ./src/schemas.ts --target openapi
npx gigli codegen --schema ./src/schemas.ts --target jsonschema
npx gigli analyze --schema ./src/schemas.ts
npx gigli --help
```
---
# π Feature Comparison
| Feature | Zod | Yup | class-validator | Gigli.js |
|-------------------------------|:---:|:---:|:--------------:|:--------------:|
| Type Inference | β
| β | β
| β
|
| Chainable Schema Builder | β
| β
| β | β
|
| Decorator API | β | β | β
| β
|
| Portable String Rules | β | β | β | β
|
| Unified Runtime (Mix & Match) | β | β | β | β
|
| Validation Pipelines & Dispatch| β | β | β | β
|
| Detailed Error Tracing | β | β | β | β
|
| Auto OpenAPI/JSON Schema Gen | β | β | β | β
|
| Extensible (Rules/Transformers)| β οΈ | β οΈ | β οΈ | β
|
---
# π Use It Everywhere
- Node.js, Deno, Bun, Cloudflare Workers
- React, Vue, Svelte, Solid
- Express, NestJS, tRPC, REST, GraphQL
- Works in browsers and modern runtimes
---
# π Documentation & Resources
- π [Full Usage Guide](docs/USAGE.md)
- π§© API Reference: See above and in-code docs
- π‘ Examples: [examples/](examples/)
- π [Contributing Guide](CONTRIBUTING.md)
- π [Report Issues](https://github.com/jasgigli/gigli.js/issues)
- π¦ [NPM Package](https://www.npmjs.com/package/gigli.js)
- βοΈ [License (MIT)](LICENSE)
---
# π€ Contributing
We are building the future of data validation, and we'd love your help! Please read our [CONTRIBUTING.md](CONTRIBUTING.md) to get started. Whether it's a bug report, a new feature, or a documentation improvement, all contributions are welcome!
---
# πͺͺ License
Gigli.js is open-source software licensed under the MIT License.
---
# π·οΈ Keywords
validation, validator, typescript, schema, zod, yup, class-validator, openapi, jsonschema, decorators, cli, nodejs, react, express, nestjs, type-safe, builder, portable, runtime, inference, extensible, pipeline, unified, metamorphic
## Usage
### ESM (Node.js with `"type": "module"` or `.mjs` files)
```js
import { v } from 'gigli.js';
const UserSchema = v.object({
username: v.string().min(3),
email: v.string().email(),
});
(async () => {
const result = await UserSchema.safeParse({ username: 'bob', email: 'bob@email.com' });
console.log('safeParse:', result); // { success: true, data: ..., error: null }
try {
const parsed = await UserSchema.parse({ username: 'bob', email: 'bob@email.com' });
console.log('parse:', parsed); // { username: 'bob', email: 'bob@email.com' }
} catch (err) {
console.error('parse error:', err);
}
})();
```
---
### CommonJS (default Node.js or `.js` files)
```js
const { v } = require('gigli.js');
const UserSchema = v.object({
username: v.string().min(3),
email: v.string().email(),
});
(async () => {
const result = await UserSchema.safeParse({ username: 'bob', email: 'bob@email.com' });
console.log('safeParse:', result); // { success: true, data: ..., error: null }
try {
const parsed = await UserSchema.parse({ username: 'bob', email: 'bob@email.com' });
console.log('parse:', parsed); // { username: 'bob', email: 'bob@email.com' }
} catch (err) {
console.error('parse error:', err);
}
})();
```
---
### TypeScript
TypeScript types are included automatically. You can use the same import as ESM:
```ts
import { v } from 'gigli.js';
// ...rest of your code
```
---
### API
- `schema.safeParse(data)` β Returns `{ success, data, error }`. Does not throw.
- `schema.parse(data)` β Returns parsed data or throws on error.
Both methods are **async** and must be awaited.
---
## Connect with the Author
- GitHub: [https://github.com/jasgigli/gigli.js](https://github.com/jasgigli/gigli.js)
- Twitter: [@jasgiigli](https://x.com/jasgiigli)
- LinkedIn: [jasgigli](https://www.linkedin.com/in/jasgigli/)