@weipertda/sigiljs
v0.18.0
Published
Executable data contracts for JavaScript runtime boundaries.
Maintainers
Readme
SigilJS
Executable data contracts for JavaScript runtime boundaries.
Define structure once, then enforce, transform, project, and prove it across runtime boundaries.
Install
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.
30-second example
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);
}Five pillars
| 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() |
Why SigilJS
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.
Boundary examples
Use SigilJS anywhere data crosses a boundary: APIs, databases, forms, events, queues, webhooks, config files, local storage, plugin systems, and AI structured outputs.
API response
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;Database record
const UserRecord = sigil.exact({
id: String,
email: String,
role: oneOf('admin', 'user'),
createdAt: String,
});
const user = UserRecord.parse(rowFromDatabase);Form submission
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);
}AI structured output
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/
Stable API quick map
// 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.
Projection example
const User = sigil({ id: String, name: String, email: String },
{ name: 'User', version: '1.0.0' });
User.toJSONSchema();
User.toTypeScript('User');
User.toOpenAPI();
User.describe();Contract diff example
sigil diff contracts/user-v1.sigil contracts/user-v2.sigilContract changes:
BREAKING
- required property: email
NON-BREAKING
- added property: displayNameCLI (experimental)
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/.
Experimental features
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.
Docs
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
Projections
Testing
Reference
SigilJS vs Zod
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.
Status
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.
License
MIT
