# docs v0.1

Documentation.

dif.sh is a handful of CLI commands and a markdown format. These docs walk through both.

The CLI lives in your repo. Experiments are .md files under dif/. dif build compiles the active ones into a typed runtime client, an audience module, and a dif/context.json your coding agent reads on session start. Nothing about the system needs to live outside git.

Start with install, then the quickstart. After that, the four cards below cover the rest.

Install

Three paths. They produce the same binary; pick whichever fits the machine.

Shell installer

One-line, no Node required. macOS and Linux only. Drops the binary at ~/.local/bin/dif by default.

$curl -fsSL https://dif.sh/install.sh | sh

Pin a release, or point the install at a different directory with DIF_INSTALL_DIR:

$curl -fsSL https://dif.sh/install.sh | sh -s -- --version v0.6.1
$curl -fsSL https://dif.sh/install.sh | DIF_INSTALL_DIR="$HOME/bin" sh

Homebrew

macOS and Linux. Easiest if you're already using brew.

$brew install dif-sh/tap/dif

npm wrapper

Works anywhere Node 18+ runs, including Windows. The package's postinstall script downloads the matching binary for your platform. The SDK and framework packages need Node 20.6+.

$npm install -g @dif.sh/cli

Quickstart

From an empty repo to a tested experiment rendering in your app.

1. dif init

Scaffold the workspace. One dif/ directory holds everything.

$dif init
✓ wrote dif/config.yaml
✓ created dif/experiments/{active,concluded}/
✓ created dif/surfaces/home.md
✓ created dif/audiences/{locale,device_type}.ts
✓ added dif guidance to CLAUDE.md, AGENTS.md

2. dif new

Draft a new experiment. Owner comes from git config user.email.

$dif new checkout-cta-v2 --surface home
→ reading dif/surfaces/home.md
  found 0 prior learnings
→ drafted dif/experiments/active/checkout-cta-v2.md
  status: draft, owner: ada@acme.dev

Open the file, fill in the hypothesis, set status: active.

3. dif validate

Every check, run in one pass. Errors include the source location.

$dif validate
✓ all checks passed

4. dif build

Compile the runtime artifacts your app imports and the context file your agent reads.

$dif build
✓ validated 1 active experiment
✓ client    → dif/generated/client.ts
✓ audiences → dif/generated/audiences.ts
✓ context   → dif/context.json

5. Render it

Install the SDK, import the generated client once at boot, and call dif() at the render site. Full reference on the SDK page.

$npm install @dif.sh/sdk
import "./dif/generated/client";
import { attributes } from "./dif/generated/audiences";
import { dif } from "@dif.sh/sdk";

dif.init({
  userId: () => currentUser?.id ?? null,
  attributes: () => attributes(),
});

const cta = dif("checkout-cta-v2", {
  control:   () => "Place order",
  variant_a: () => "Get it today",
});

button.textContent = cta();

Workspace layout

dif init creates a single dif/ tree. The generated files appear after dif build.

dif/
  config.yaml
  context.json          # written by dif build
  audiences/
    locale.ts           # one resolver per audience attribute
    device_type.ts
  experiments/
    active/
    concluded/
  generated/            # gitignored
    client.ts
    audiences.ts
  surfaces/
    home.md

dif/generated/ is gitignored. dif/context.json lives outside it and is meant to be checked in, so coding agents and other repo tooling can read the active-experiment summary on session start. dif init also adds a managed dif block to CLAUDE.md, AGENTS.md, and .github/copilot-instructions.md, and writes .cursor/rules/dif.mdc and .claude/skills/; pass --agents none (or the deprecated --no-agent-files alias) to skip them.

What's where

  • The .md format (frontmatter, surfaces, audiences, exclusion groups): format.
  • Every CLI command, every flag, every exit code: cli.
  • The four Claude Code skills dif init installs for authoring, concluding, generating surfaces, and triaging Cloud verdicts: skills.
  • The JS SDK (dif.init(), dif(), sinks, exposure events, server assignment, and the React and Svelte adapters): sdk.
  • Experiment verdicts for agents and scripts, over MCP or REST, and the rules behind them: mcp.
  • The full dif/config.yaml schema: config.
  • Diagnostic codes and FAQ: troubleshooting.