Executable data contracts for JavaScript runtime boundaries.
Define structure once, then enforce, transform, project, and prove it across runtime boundaries.
npm install @weipertda/sigiljsor:
bun add @weipertda/sigiljsSigilJS is written in JavaScript and ships TypeScript declarations for public API consumption.
The declarations are intentionally conservative: they describe the runtime API, but do not yet infer precise object shapes from every contract definition. For typed usage, pass an explicit generic such as sigil.exact<User>(...); see docs/typescript.md.
import { oneOf, optional, sigil } from '@weipertda/sigiljs';
const User = sigil.exact({
id: String,
email: String,
role: oneOf('admin', 'user'),
age: optional(Number),
});
const result = User.safeParse(unknownInput);
if (result.success) {
// result.data is trusted — id, email, role, age are verified
saveUser(result.data);
} else {
console.error(result.error.message);
}| Pillar | Purpose | Methods |
|---|---|---|
| Define | Declare structure in JavaScript | sigil(), sigil.exact(), optional(), oneOf(), union() |
| Enforce | Validate runtime data | parse(), safeParse(), assert(), check() |
| Transform | Normalize trusted data | transform(), pipe(), trim(), serialize() |
| Project | Generate tooling artifacts | toJSONSchema(), toTypeScript(), toOpenAPI(), toFormConstraints(), describe() |
| Prove | Test contract behavior | mock(), cases(), test(), diff() |
Data crosses runtime boundaries constantly — API responses, form submissions, database rows, AI outputs, CLI inputs. That data is untrusted until a contract enforces it.
SigilJS provides one contract object per shape that you can:
- enforce at any runtime boundary
- project into JSON Schema, TypeScript, OpenAPI, or form metadata
- use to generate test fixtures and run self-tests
- compare across versions with structural diffs
- consume from TypeScript projects without missing declaration errors
A sigil is not a schema. It is a contract object that lives in your JavaScript and travels with your data.
Use SigilJS anywhere data crosses a boundary: APIs, databases, forms, events, queues, webhooks, config files, local storage, plugin systems, and AI structured outputs.
const ApiResponse = sigil.exact({
id: String,
name: String,
role: oneOf('admin', 'user'),
});
const result = ApiResponse.safeParse(await response.json());
if (!result.success) {
throw new Error(`Unexpected API shape: ${result.error.message}`);
}
return result.data;const UserRecord = sigil.exact({
id: String,
email: String,
role: oneOf('admin', 'user'),
createdAt: String,
});
const user = UserRecord.parse(rowFromDatabase);const SignupForm = sigil.exact({
name: String,
email: String,
plan: oneOf('free', 'pro'),
});
const result = SignupForm.safeParse(formValues);
if (!result.success) {
showFieldError(result.error.path?.at(-1), result.error.message);
}const LeadIntent = sigil.exact({
name: String,
urgency: oneOf('low', 'medium', 'high'),
summary: String,
});
// JSON Schema bridges the contract to LLM structured output APIs
const schema = LeadIntent.toJSONSchema();
// Pass schema to your LLM provider as the output format
const result = LeadIntent.safeParse(llmOutput);
if (result.success) {
handleTrustedLead(result.data);
}More boundary recipes: docs/recipes/
// Define
import { sigil, optional, oneOf, union, pipe, trim } from '@weipertda/sigiljs';
sigil.exact(definition) // exact object contract
// Enforce
contract.parse(value) // throws on invalid
contract.safeParse(value) // { success, data } | { success, error }
contract.assert(value) // throws on invalid, returns void
contract.check(value) // boolean
// Transform
contract.transform(fn) // returns new contract with transform
contract.serialize(value) // validates and returns
// Project
contract.describe() // stable contract description model
contract.toJSONSchema() // JSON Schema
contract.toTypeScript(name) // TypeScript type declaration
contract.toOpenAPI() // OpenAPI schema
contract.toFormConstraints() // form field metadata (experimental)
// Prove
contract.mock() // deterministic valid sample
contract.cases() // { valid, invalid } test case sets
contract.test(cases) // run and report contract behavior
contract.diff(other) // structural change reportSee docs/api.md for the full API reference.
const User = sigil({ id: String, name: String, email: String },
{ name: 'User', version: '1.0.0' });
User.toJSONSchema();
User.toTypeScript('User');
User.toOpenAPI();
User.describe();sigil diff contracts/user-v1.sigil contracts/user-v2.sigilContract changes:
BREAKING
- required property: email
NON-BREAKING
- added property: displayName
SigilJS includes a dependency-free CLI for contract workflows. The CLI is Bun-first and experimental — commands, output shapes, exit-code guarantees, CWD/module-loading behavior, and .sigil compatibility may change before 1.0.0.
sigil check contracts/user.sigil data/user.json
sigil json-schema contracts/user.sigil
sigil types contracts/user.sigil User
sigil mock contracts/user.sigil
sigil cases contracts/user.sigil.js
sigil diff contracts/user-v1.sigil contracts/user-v2.sigilThe CLI supports both .sigil text files and .sigil.js JavaScript module files.
See docs/cli.md and examples/cli/.
The following APIs are experimental — they are tested and usable, but their surface may change before 1.0.0:
- HTTP helpers —
httpContract()for framework-neutral request/response boundaries - Form constraints —
contract.toFormConstraints()for form field metadata - CLI workflows —
sigilbin for terminal contract workflows
See docs/experimental.md.
Future @sigil/* package extraction is intentionally deferred until the core API stabilizes at 1.0.0.
Getting started
Real-world recipes
- All recipes
- Full Lifecycle — all five pillars in one workflow ⭐
- API Route
- LLM Output
- Form Submission
- Database Persistence
- Contract Testing
CLI
Boundaries
- HTTP Boundary Helpers
- Form Contracts
- Database Record Contracts
- AI Structured Output
- Boundary Recipes
Projections
Testing
Reference
Zod is a mature, expressive TypeScript-first validation library with a large ecosystem. SigilJS is a smaller executable data contract system for teams that want one readable runtime contract object they can enforce, transform, describe, and project across system boundaries without a TypeScript compiler dependency.
SigilJS does not claim to replace Zod. It is a focused alternative when you need runtime contracts with zero runtime dependencies, cross-boundary projection workflows, and a CLI for contract tooling.
Version 0.18.0. Core API is ready for broader public 0.x usage feedback, but this is not a 1.0.0 release. HTTP helpers, form constraints, and CLI are experimental.
See docs/stability.md and docs/known-limitations.md.
MIT
