https://github.com/antistructured/sigiljs
Turns JavaScript data structures into executable contracts.
https://github.com/antistructured/sigiljs
bun contracts data-contracts executable-contracts javascript json-schema openapi runtime runtime-contracts schema sigil type-checking types typescript validation zero-dependencies zero-dependency
Last synced: 3 days ago
JSON representation
Turns JavaScript data structures into executable contracts.
- Host: GitHub
- URL: https://github.com/antistructured/sigiljs
- Owner: antistructured
- License: mit
- Created: 2026-03-09T22:33:40.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-06-25T23:50:49.000Z (5 days ago)
- Last Synced: 2026-06-26T01:12:44.259Z (5 days ago)
- Topics: bun, contracts, data-contracts, executable-contracts, javascript, json-schema, openapi, runtime, runtime-contracts, schema, sigil, type-checking, types, typescript, validation, zero-dependencies, zero-dependency
- Language: JavaScript
- Homepage: https://github.com/antistructured/sigiljs#readme
- Size: 6.38 MB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: docs/contributing.md
- License: LICENSE
- Roadmap: docs/roadmap.md
Awesome Lists containing this project
README
# SigilJS
Executable data contracts for JavaScript runtime boundaries.
Define structure once, then enforce, transform, project, and prove it across runtime boundaries.

---
## Install
```bash
npm install @weipertda/sigiljs
```
or:
```bash
bun add @weipertda/sigiljs
```
SigilJS 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(...)`; see [`docs/typescript.md`](docs/typescript.md).
---
## 30-second example
```js
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
```js
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
```js
const UserRecord = sigil.exact({
id: String,
email: String,
role: oneOf('admin', 'user'),
createdAt: String,
});
const user = UserRecord.parse(rowFromDatabase);
```
### Form submission
```js
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
```js
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/`](docs/recipes/index.md)
---
## Stable API quick map
```js
// 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 report
```
See [`docs/api.md`](docs/api.md) for the full API reference.
---
## Projection example
```js
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
```bash
sigil diff contracts/user-v1.sigil contracts/user-v2.sigil
```
```
Contract changes:
BREAKING
- required property: email
NON-BREAKING
- added property: displayName
```
---
## CLI (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.
```bash
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.sigil
```
The CLI supports both `.sigil` text files and `.sigil.js` JavaScript module files.
See [`docs/cli.md`](docs/cli.md) and [`examples/cli/`](examples/cli/README.md).
---
## 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** — `sigil` bin for terminal contract workflows
See [`docs/experimental.md`](docs/experimental.md).
Future `@sigil/*` package extraction is intentionally deferred until the core API stabilizes at 1.0.0.
---
## Docs
**Getting started**
- [Public API](docs/api.md)
- [Quickstart](docs/quickstart.md)
- [Sigils](docs/sigils.md)
- [Stability Map](docs/stability.md)
- [Known Limitations](docs/known-limitations.md)
**Real-world recipes**
- [All recipes](docs/recipes/README.md)
- [Full Lifecycle](docs/recipes/full-lifecycle.md) — all five pillars in one workflow ⭐
- [API Route](docs/recipes/api-route.md)
- [LLM Output](docs/recipes/llm-output.md)
- [Form Submission](docs/recipes/form-submission.md)
- [Database Persistence](docs/recipes/database-persistence.md)
- [Contract Testing](docs/recipes/contract-testing.md)
**CLI**
- [CLI Reference](docs/cli.md)
- [CLI Overview](docs/cli/overview.md)
- [CLI Contract Files](docs/cli/contract-files.md)
- [CLI Projections](docs/cli/projections.md)
- [CLI Prove](docs/cli/prove.md)
**Boundaries**
- [HTTP Boundary Helpers](docs/projections/http.md)
- [Form Contracts](docs/forms/form-contracts.md)
- [Database Record Contracts](docs/database/record-contracts.md)
- [AI Structured Output](docs/projections/ai-structured-output.md)
- [Boundary Recipes](docs/recipes/index.md)
**Projections**
- [JSON Schema](docs/projections/json-schema.md)
- [OpenAPI](docs/projections/openapi.md)
- [Forms Projection](docs/projections/forms.md)
- [Testing Helpers](docs/projections/testing.md)
**Testing**
- [Contract-Driven Testing](docs/testing.md)
**Reference**
- [Experimental APIs](docs/experimental.md)
- [Package Split Policy](docs/package-split.md)
- [SigilJS vs Zod](docs/sigil-vs-zod.md)
- [Full docs index](docs/README.md)
---
## 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`](docs/stability.md) and [`docs/known-limitations.md`](docs/known-limitations.md).
---
## License
MIT