Super lightweight and simple type system library like zod, but faster, smaller, and with fewer functions.
We doesn't use eval, Function or something like this, because we're staying web-friendly
NPM
npm install @nirelc/microtypeBun
bun intall @nirelc/microtypeMicrotype can be imported with wildcard or with only required types
// with only required types import
import { … } from '@nirelc/microtype';
// with a wildcard import
import * as t from '@nirelc/microtype';Microtype simillar with valibot and other type system libs, because of this, you will easily understand our syntax
import { object, string } from "@nirelc/microtype";
// typescript
type UserData = {
username: string;
email?: string;
};
// microtype
const PostSchema = object({
username: string(),
email: string().optional(),
});
type PostData = typeof PostSchema.static;
const data = PostSchema.parse({
username: "system",
should: "strip",
});We provide some useful features with schema chaining
const PostSchema = object({
email: string().min(5).max(128).optional(),
version: number().default(1),
});All types support <type>.default(<value>) syntax.
Now we support these types:
// typescript
type Username = string;
// microtype
const UsernameSchema = string();
// extra fields
const UsernameExtraSchema = string().min(1).max(24).default("root");// typescript
type Version = number;
// microtype
// any number and floats
const VersionSchema = number(); // or `float()` as alias
// only integer (float will trigger error)
const VersionIntSchema = integer();
// integer with pre-built validators
// supports: uinteger, u8, u16, u32, i8, i16, i32
const SmallVersionSchema = u8();
// extra fields
// e.g value should equals 1 <= value <= 3 and should parse string as number and drop float support
const VersionExtraSchema = number().min(1).max(3).coerce(true).integer(true);// typescript
type Username = "root";
// microtype
const UsernameSchema = literal("root");Supported separated type optional(<schema>), also can be chained with <schema>.optional()
// typescript
type Email = string | undefined;
// const EmailSchema = string().optional()
const EmailSchema = optional(string());// typescript
type Username = "root" | "user";
// microtype
const UsernameSchema = union([literal("root"), literal("user")];
// with nested union
const UsernameWithNestedSchema = union([literal("root"), union([literal("user")])])// typescript
type Versions = number[];
// microtype
const VersionsSchema = array(number());
// extra fields
// min 1 item, max 3 items
const VersionsLimitedSchema = array(number()).min(1).max(3);
// array.length should be equal 3
const VersionsWithLengthScheam = array(number()).length(3);All unknown fields will be deleted
// typescript
type User = {
username: string;
email?: string;
status: "banned" | "active";
};
// microtype
const VersionsSchema = object({
username: string(),
// email: string().optional()
email: optional(string()),
status: union([literal("banned"), literal("active")]),
});You can run benchmarks in bench dir.
Cold start (create a new schema and parse it)
| name | avg |
|---|---|
| microtype | 649.81 µs |
| valibot | 3.23 ms |
| typebox | 18.34 ms |
| arktype | 47.28 ms |
| zod | 94.78 ms |
Global schema (parsing with pre-created schema)
| name | avg |
|---|---|
| typebox [compiled]* | 22.19 µs |
| arktype* | 35.63 µs |
| microtype | 382.47 µs |
| valibot | 434.18 µs |
| zod | 426.60 µs |
| typebox | 6.26 ms |
* - arktype and typebox [compiled] uses precompile, because of this, it has better performance for global schema
We using a micro test case for create a type object schema + parse for all libs
| name | avg |
|---|---|
| microtype | 9.02 KB |
| valibot | 13.69 KB |
| zod | 138.03 KB |
| arktype | 281.49 KB |
| typebox | 358.11 KB |
Q: Why did you make another type system lib?
- idk, just for fun