---
title: Quickstart
description: Install Specdiff and Envlock, run each tool, and verify the result in under five minutes.
url: https://pr-1-ff84656b4b8a.thally.app/quickstart
---

# Quickstart

Install Specdiff and Envlock, run each tool, and verify the result in under five minutes.

## Specdiff

Specdiff compares two versions of a JSON Schema or OpenAPI document and reports every breaking change, warning, and informational difference.

### CLI

Install the CLI as a dev dependency:

```bash
npm install -D @specdiff/cli
```

Compare two OpenAPI files:

```bash
npx specdiff petstore-v1.yaml petstore-v2.yaml
```

The output lists each change grouped by severity. The command exits with code **1** when any breaking change is found (the default `--fail-on breaking` threshold) and **0** otherwise. Use `--format json` or `--format markdown` for machine-readable output.

To learn what a specific rule means and how to remediate it:

```bash
npx specdiff explain endpoint-removed
```

### Library

Install the core library:

```bash
npm install @specdiff/core
```

Use `diffDocuments` to compare two parsed documents and `exceedsThreshold` to decide whether the result should fail a check:

```ts
import { readFileSync } from "node:fs";
import { diffDocuments, exceedsThreshold, formatText } from "@specdiff/core";

const before = JSON.parse(readFileSync("user-v1.json", "utf8"));
const after = JSON.parse(readFileSync("user-v2.json", "utf8"));

const result = diffDocuments(before, after);

console.log(formatText(result));
console.log("Has breaking changes:", exceedsThreshold(result, "breaking"));
```

`diffDocuments` auto-detects whether the inputs are OpenAPI or JSON Schema. The returned `DiffResult` contains a `changes` array, a `summary` with per-severity counts, and a `maxSeverity` field.

---

## Envlock

Envlock validates environment variables against a typed contract so configuration errors surface at startup, not at runtime.

### Generate a starter config

Install the CLI and scaffold a config file:

```bash
npm install -D @envlock/cli
npx envlock init
```

This writes `envlock.config.mjs` with a starter contract:

```js
import { defineEnv, env } from "@envlock/core";

export default defineEnv({
  NODE_ENV: env.enum(["development", "test", "production"]).default("development"),
  PORT: env.port().default(3000).describe("HTTP listen port"),
  DATABASE_URL: env.url({ protocols: ["postgres:", "postgresql:"] })
    .secret()
    .describe("Primary database connection string"),
  LOG_LEVEL: env.enum(["debug", "info", "warn", "error"]).default("info"),
});
```

Edit the file to match the variables your application reads. Each builder (`env.string()`, `env.port()`, `env.url()`, `env.boolean()`, and others) parses and validates the raw string value. Chain `.optional()`, `.default()`, `.secret()`, and `.describe()` to refine the field.

### Validate your environment

Check a `.env` file against the contract:

```bash
npx envlock check --env-file .env
```

A passing check prints a confirmation. A failing check lists every issue with the variable name, issue code (`missing`, `invalid`, or `unknown`), and a human-readable message. Secret values are masked in the output.

### Generate a `.env.example`

Produce a documented example file from the contract:

```bash
npx envlock example --out .env.example
```

The generated file includes a comment block for each variable showing its type, constraints, and description. Run `npx envlock example --check` in CI to ensure the example file stays in sync with the contract.