Lint an ODCS contract and validate a CSV against it, offline.
Offline data-contract runtime: parse and lint an Open Data Contract Standard (ODCS) contract, then validate a CSV dataset against it, in the browser or in CI. No warehouse connection, no upload.
by svx · MIT Licensed
Live site: datapact · Source: github.com/srivtx/datapact
Docs: Rules · Usage · CI · FAQ
A data contract is usually a document: written once, filed, and never enforced. The producer starts emitting nulls, renames a column, or changes a currency code, and nothing fails until a dashboard breaks or a downstream job reads garbage. The contract was never wrong; it was just never checked.
The main open-source engine for this is Python and connection-centric: it wants a warehouse, credentials, and a running server. Most teams do not need that. They need to answer one question in a pull request: does this file match this contract?
datapact answers exactly that, and nothing else. It reads a contract and a data
file from disk, checks one against the other, and exits non-zero when they
disagree. It runs in the browser, in a pre-commit hook, or in CI, with no
connection string and no upload.
- Parses ODCS — YAML or JSON, reading the
schemaarray and the properties in it. The rest of the document is accepted and ignored. - Lints the contract — duplicate or missing names, unknown logical types,
invalid regular expressions, bad numeric bounds, empty enums, unknown formats,
and
required/uniqueonobject/arrayproperties (DP-101–DP-109). - Validates a CSV against it — missing required columns, undeclared columns,
type mismatches, empty required values, uniqueness, bounds, patterns, enums,
and formats (
DP-201–DP-210), with a per-rule suppression cap (DP-250). - Stays offline — no network code, no warehouse driver, no telemetry. Your data never leaves the machine.
- Speaks to CI and agents — human-readable text, stable JSON, and SARIF 2.1.0, with a documented exit-code scheme.
datapact is not published to npm. Install it from GitHub with the one-line
script (requires Bun):
# One-line install (installs the `datapact` binary)
curl -fsSL https://raw.githubusercontent.com/srivtx/datapact/main/install.sh | sh
# Or run once, without installing
bunx github:srivtx/datapact#main --help
# Install globally
bun add -g github:srivtx/datapact
datapact --help
# Add to a project as a dev dependency
bun add -d github:srivtx/datapact# Lint a contract on its own
datapact lint --contract spec/example-contract.yaml
# Lint the contract and validate a dataset against it
datapact check --contract spec/example-contract.yaml --data spec/example-data.csv
# Machine-readable output for a program
datapact check --contract contract.yaml --data orders.csv --json
# Write a SARIF report and fail on warnings as well as errors
datapact check --contract contract.yaml --data orders.csv --sarif datapact.sarif --fail-on warningEvery option that takes a value accepts both --flag value and --flag=value.
The failure threshold is one of error (the default), warning, info, or
none; it affects only the exit code, and every finding is still reported.
The same engine is exported for use in your own code. It is browser-safe: no
node: imports, so it runs in a page as well as in Bun.
import { parseContract, parseCsv, lintContract, validateDataset } from "datapact";
const contract = parseContract(contractSource);
const dataset = parseCsv(csvSource);
const issues = [...lintContract(contract), ...validateDataset(contract, dataset)];
for (const issue of issues) {
console.log(issue.code, issue.severity, issue.message);
}| Code | Meaning |
|---|---|
0 |
No findings at or above --fail-on |
1 |
At least one finding at or above --fail-on |
2 |
Invalid usage, or input that could not be parsed (DP-PARSE-000) |
3 |
I/O error: an input file could not be read, or a report could not be written |
An unreadable or structurally invalid contract is never reported as clean: it
produces a DP-PARSE-000 error and exit code 2, so a CI gate cannot pass on
input the tool did not understand.
Every surface is built to be read by a program: stable rule codes, stable JSON, SARIF 2.1.0, and a documented exit-code scheme, so an agent can consume findings without scraping a screen.
-
Docs index: the site serves a machine-readable index at srivtx.github.io/datapact/llms.txt.
-
Agent guide:
AGENTS.mdcovers build, test, layout, and the hard rules. -
MCP server: expose the runtime to any MCP-capable agent over stdio.
{ "mcpServers": { "datapact": { "command": "bunx", "args": ["github:srivtx/datapact#main", "mcp"] } } }
MIT.