dif.sh
Open-source CLI tool that stores feature flags and A/B experiments as Markdown files in your git repo, with a typed TypeScript SDK and optional cloud analytics.
At a Glance
Full CLI and SDK, self-hosted, no signup required. MIT licensed.
Engagement
Available On
Alternatives
Listed Sep 2026
About dif.sh
dif.sh is a free, open-source feature flag and A/B testing tool built around a simple idea: flags and experiments belong in the repo, not in a web dashboard. Released under the MIT license, the core CLI is written in Rust and the SDK ships with zero dependencies. It was voted Product of the Day on Product Hunt.
What It Is
dif.sh treats every feature flag, A/B test, holdout, and staged rollout as a single Markdown file checked into git alongside the code it controls. A YAML frontmatter block declares the experiment's id, status, owner, audience targeting, variants, weights, metrics, and exclusion groups. The freeform body holds the hypothesis, rationale, and decision. Because everything lives in git, PR review becomes the approval flow and git history becomes the audit log — no separate database or change-history service to reconcile.
How the File-First Architecture Works
The CLI compiles active experiment files into a typed TypeScript client (dif/generated/client.ts) and a dif/context.json summary that coding agents read on session start. Assignment is a pure local function — no network call, no assignment database — so a user never flips between variants across page loads or devices. The same bucketing math runs in the Rust CLI and the TypeScript SDK, locked by a shared test fixture that fails CI if the two implementations drift.
Key structural points:
- One file format covers flags, experiments, holdouts, and staged rollouts — different frontmatter, same shape.
exclusion_groupin frontmatter prevents two live tests from bucketing the same user; conflicts faildif build, not production.- Audience targeting declares attributes (country, plan,
returning_visitor) once in config; values arrive at runtime from the app's user context — no customer list is ever committed. - Surface files (
dif/surfaces/*.md) accumulate one-line learnings per concluded experiment, so the nextdif newon that surface starts from institutional memory.
The Eight CLI Commands
The CLI covers the full experiment lifecycle without opening a browser or requiring a login:
dif init— scaffolds thedif/folder, config, and agent guidance files (CLAUDE.md,AGENTS.md,.cursorrules, Claude Code skills).dif new— drafts a new experiment file, pre-populated from the surface's prior learnings.dif validate— checks schema, owners, surface refs, exclusion graph, and warns when code references a missing experiment.dif build— compiles active experiments into the typed TS client and refreshescontext.json; fails on any conflict.dif qa— traces the exact variant a given user receives and emits a preview URL with that variant forced.dif conclude— archives the file, drafts the Decision block, and appends a one-line learning to the surface log.dif connect— links the workspace to dif.sh Cloud with a publishable key.dif scaffold-audiences— idempotently scaffolds starter audience resolvers (locale, device_type).
Agent-Native Design
dif init installs three Claude Code skills into .claude/skills/: dif-generate-surfaces (reads routes and pages, proposes the surface set), dif-author-experiment (drafts frontmatter, picks weights, runs validate), and dif-conclude-experiment (writes the decision, archives the file, logs the learning). Because flags are files, a coding agent can read, write, and validate them the same way it handles any other source — something a web dashboard cannot offer.
dif.sh Cloud
The optional hosted layer at cloud.dif.sh handles event ingest, metrics, and statistical analysis. It adds three views: Pulse (live lift, confidence intervals, and exposures alongside the hypothesis from the file), Suggestions (AI-drafted experiment briefs with hypothesis and expected lift drawn from surface history and behavioral data), and History (all concluded experiments with outcome, lift, and approver). The core CLI and SDK work fully offline without a Cloud key; analytics are opt-in.
Update: v0.6.1
The latest release is v0.6.1, published on 2026-08-06, with the repository last updated in September 2026. The project is written primarily in Rust for the core parser, validator, bucketing, and codegen (dif-core and dif-cli crates), with TypeScript packages for the SDK, React adapter, and Svelte adapter. Install paths include an npm global package (@dif.sh/cli), a shell installer (macOS/Linux, no Node required), and Homebrew (dif-sh/tap/dif). The SDK and framework packages require Node 20.6+.
Community Discussions
Be the first to start a conversation about dif.sh
Share your experience with dif.sh, ask questions, or help others learn from your insights.
Pricing
Open Source
Full CLI and SDK, self-hosted, no signup required. MIT licensed.
- All 8 CLI commands
- Markdown-based feature flags and experiments
- Local variant assignment (no network)
- Typed TypeScript client generation
- React and Svelte SDK adapters
Dif Cloud
Hosted analytics layer with event ingest, lift metrics, confidence intervals, AI-drafted experiment suggestions, and history.
- Pulse: live lift and confidence intervals
- AI-drafted experiment suggestions
- History of all concluded experiments
- Event ingest and metric tracking via dif.track()
- Verdict drafted as a PR
Capabilities
Key Features
- Feature flags as Markdown files in git
- A/B experiments with YAML frontmatter
- Staged rollouts and holdouts in the same file format
- Local, network-free variant assignment
- Typed TypeScript client generated by dif build
- Conflict detection via exclusion groups at build time
- Surface files with accumulated experiment learnings
- Coding agent integration via context.json and Claude Code skills
- dif validate checks schema, owners, surface refs, and exclusion graph
- dif qa traces exact variant for a user and emits a preview URL
- dif conclude archives experiments and logs learnings
- Optional dif.sh Cloud for event ingest, metrics, and statistical analysis
- Audience targeting by country, plan, returning_visitor, device_type, locale
- React and Svelte SDK adapters
- Zero-dependency TypeScript SDK
- Homebrew, npm, and shell installer install paths
- CI-friendly: dif build fails on conflicts before production
