Product Introduction
- Definition: dif.sh is an open-source developer tool and SDK for implementing feature flags, A/B tests, holdouts, and staged rollouts. It is technically categorized as a feature management and experimentation platform designed to be version-controlled and infrastructure-as-code (IaC) native.
- Core Value Proposition: It exists to move the logic, configuration, and history of feature flags and experiments out of external SaaS dashboards and into a project's Git repository as Markdown and YAML files. This enables PR-based workflows, eliminates vendor lock-in, ensures the experiment definition is always in sync with the code it controls, and provides a portable context file for AI coding agents.
Main Features
- Markdown-First Experiment Definition: Each feature flag or A/B test is a single Markdown file (
your-experiment.md) stored indif/experiments/active/. The file uses YAML frontmatter for machine-readable configuration (ID, status, hypothesis, audience, variants) and Markdown sections for human-readable documentation (Brief, Rationale, Decision). This creates a single source of truth reviewed in a pull request. - Build-Time Conflict Resolution & Client Generation: The
dif buildcommand is a core compiler. It parses all active experiment files, validates the schema, resolves the exclusion group graph to prevent user bucketing conflicts, and fails the build if clashes are detected. It then generates a strongly-typed, tree-shakeable client SDK (dif/generated/client.ts) that is imported directly into the application, ensuring runtime decisions are local with no network latency. - Git-Centric Audit Log and Institutional Memory: Concluded experiments are moved to
dif/experiments/concluded/bydif conclude, which also drafts a Decision block in the file. Crucially, it appends a one-line summary to a surface log file (e.g.,dif/surfaces/checkout.md). This creates a running, versioned history of learnings for each part of the application, which thedif newcommand reads to inform the hypothesis of new drafts. - Runtime-Agnostic Audience Targeting: Audience segmentation is declared in the experiment file's frontmatter (e.g.,
include: - returning_visitor: true). The actual attribute values (likecountryorplan) are provided at runtime from the application's user context via the SDK'sdif.track()method or initialization. No sensitive customer data or lists are ever stored in the repository. - Coding Agent Context (
context.json): Every build regenerates adif/context.jsonfile containing a structured summary of all active experiments, variants, and recent conclusions. This file is designed to be read by AI coding assistants at the start of a development session, providing them with immediate context about ongoing feature work and past learnings.
Problems Solved
- Pain Point: Disconnect between code and feature management. Traditional SaaS platforms create a separate system of record, leading to drift where the live experiment configuration doesn't match the code expecting it, or where the "why" behind a flag is lost in a separate tool's notes.
- Pain Point: Opaque and non-portable experiment history. Learning from past A/B tests is often trapped in dashboards or spreadsheets, not integrated into the development workflow, making it easy for teams to repeat mistakes.
- Target Audience: Engineering teams (particularly in startups and mid-size companies) who value DevOps practices, infrastructure-as-code, and PR-based review cycles. Product managers and data scientists who need rigorous, well-documented experimentation integrated into the development lifecycle.
- Use Cases: Safely rolling out a new checkout UI with a feature flag. Running a statistically valid A/B test on pricing page copy. Implementing a staged rollout (percentage-based release) of a high-risk backend service. Creating a long-term holdout group to measure system-wide impact. Ensuring AI coding agents have full context of active experiments when modifying related code.
Unique Advantages
- Differentiation: Unlike SaaS platforms (LaunchDarkly, Optimizely), dif.sh has no external control plane, dashboard, or vendor runtime. The entire state is in your repo. Unlike simple open-source flag SDKs (Unleash), it bakes in experimentation-specific concepts (hypotheses, metrics, exclusion groups), a built-in audit log, and a compiler for safety, moving complexity from runtime to build time.
- Key Innovation: The integration of the experiment lifecycle—from draft (
dif new) to conclusion and learning capture (dif conclude)—directly into the file system and Git workflow. Thesurfacelog files transform ephemeral experiment results into a persistent, versioned institutional memory that directly seeds future work.
Frequently Asked Questions (FAQ)
- How does dif.sh handle A/B testing analytics and compute statistical significance? The core open-source dif.sh CLI and SDK handle experiment definition, user bucketing, and event tracking. For analytics, you can use
dif.track()to send events to a connected Dif Cloud account (a paid SaaS add-on) which automatically computes lift and confidence intervals. Alternatively, you can usedif init --events customto own the event handlers and forward data to your own analytics pipeline (e.g., Segment, Amplitude, a data warehouse). - Is dif.sh suitable for large-scale, enterprise applications? Its architecture is designed for scale at the build/compile stage, not runtime. The generated client is minimal and fast. The primary considerations for large enterprises would be the need to manage the
dif/directory across many microservices and to potentially build internal tooling around the file-based workflow, as it lacks a centralized management GUI. - Can I use dif.sh with a coding agent like Claude Code or Cursor? Yes, this is a primary design goal. The AI agent reads the generated
dif/context.jsonfile at project open, giving it immediate awareness of all active feature flags, their status, owners, and recent conclusions from surface logs. This allows the agent to reason about code changes in the context of live experiments. - What happens if two developers create experiments with conflicting exclusion groups? The
dif buildcommand will fail. It constructs a graph of all active experiments and theirexclusion_groupassignments. If it detects that a single user could be bucketed into two experiments within the same group, it throws a compilation error, preventing the conflicting configuration from being deployed. This conflict check is enforced in CI/CD. - How do I manage secrets or environment-specific configuration? dif.sh's configuration is intentionally static and committed. For environment-specific overrides (e.g., disabling all experiments in a staging environment), you would use your application's existing environment variable system to conditionally skip the dif client initialization or override the
statuscheck at runtime within your application code.
