Guide

Get started with VibeDrift

From install to CI/CD in 5 minutes. VibeDrift scans your AI-generated project for contradictions and gives you a score with file-level evidence.

[01] What is drift?

Your AI forgets between sessions.

When you use AI to write code across multiple sessions, each session starts fresh. Session 1 uses a repository pattern. Session 3 switches to raw SQL. Session 7 introduces an ORM. None are wrong individually, but together they create drift: a codebase that contradicts itself.

VibeDrift discovers the patterns your code already follows and finds the exceptions. It's a consistency checker, not a style enforcer. A codebase isn't wrong because it uses raw SQL, it's driftingbecause 8 handlers use a repository and 2 don't.

Drift also shows up as sprawl: the same logic re-implemented again and again across many files because each AI session didn't know the helper already existed. When that re-implementation is dense enough across the codebase, it's a drift signal in its own right, and deep scans now factor it into your score (see Deep scans). A single legacy parallel implementation sitting in otherwise clean code is not penalized, it's the dense, repeated reinvention that counts.

[02] Install

30-second setup.

VibeDrift is a Node.js CLI. You need Node 18.17+. It scans JavaScript, TypeScript, Python, Go, and Rust. No config file, no API key, no signup needed for your first scan.

Install globally (recommended)
$npm install -g @vibedrift/cli
Or run without installing
$npx @vibedrift/cli .
Verify the install
$vibedrift --version
Stay on the latest

VibeDrift is in early stages, new detectors and calibration improvements land most weeks, so running the latest version always gives you the sharpest drift detection. The CLI will nudge you when an update is available; update with vibedrift update or npm i -g @vibedrift/cli@latest.

[03] First scan

Run your first scan.

Scan the current directory
$vibedrift .
Free
Scan a specific project
$vibedrift ~/workspace/my-project

The default output is an HTML report that opens in your browser. The headline is the Vibe Drift Score, 0-100 with an A-F letter grade, measuring how consistently your codebase follows its own cross-file patterns. Alongside it you get a separate, independent Hygiene Score (also 0-100) for generic quality findings like complexity, dead code, and TODOs. The two are independent, hygiene does not move the drift score. The full report is open to everyone, no account needed.

Scanning 55 files · 6,151 LOC · Go
✓ Static analysis
✓ Cross-file drift
✓ Code DNA
 
Vibe Drift Score: 72/100 (C) · Hygiene: 82/100
Fix these 3 → projected ~81/100 (C → B)
Report: ./vibedrift-report.html
Other formats
$vibedrift . --format terminal
$vibedrift . --json > report.json
$vibedrift . --output report.html

Results appear the moment the scan finishes. Signed out, the report is served on localhost; signed in, the same scan also links to your dashboard so you can track the score over time.

Run it alongside your AI session:

One-time sign-in
$vibedrift login
Free
Watch mode, rescan on change, refresh .vibedrift/ context
$vibedrift watch
Pro

While the watcher is running, every time your agent edits a file, VibeDrift refreshes .vibedrift/context.md, fix-plan.md, and patterns.json so the next AI turn sees up-to-date peer context. Watch mode runs --local-only, so it makes zero network calls. It's a Pro feature, the watcher emits full finding details continuously.

[] Configure & exclude

Tell VibeDrift what to scan.

VibeDrift checks your codebase against itself, so it's worth telling it which files are actually yours. Test fixtures, generated code, and vendored files aren't, and scoring them just adds noise. Set this up once:

Guided, one-time setup
$vibedrift init
Free

init detects likely fixtures and generated code, then asks which paths to skip, your CI score floor, and your default report format. It writes two committable files:

.vibedriftignore which paths to skip (gitignore syntax)
.vibedrift/config.json behavior: default format + CI score floor
Commit both so your whole team scans the same way.

Exclude paths without the wizard:

Add a glob to .vibedriftignore
$vibedrift ignore "**/fixtures/**"
Free
Skip files for a single scan
$vibedrift . --exclude "**/*.spec.*"
Scan only certain files for a single scan
$vibedrift . --include "src/**"

.vibedriftignore uses gitignore syntax and is honored by both the CLI and the MCP server, so excluded paths stop counting toward your score in either (init and ignore refresh the baseline for you). Agents can set up a fresh repo in-loop too: the MCP exposes an init tool that writes the same files.

NextSign in to unlock deep scans
[04] Sign in

Unlock deep scans & dashboard.

Free scans run locally with no account. Sign in to unlock deep scans, the dashboard, and scan history.

Browser-based sign in (like GitHub CLI)
$vibedrift login
1. CLI shows a one-time code in your terminal
2. Browser opens → sign in with Google or email
3. CLI picks up the token automatically
No password ever touches the terminal.
Check your status
$vibedrift status
Account: you@example.com
Plan: Pro
Deep: 10 / 12 monthly + 5 purchased
Token: vd_live_...abc (valid)

Your monthly allotment (Free 1, Pro 12) and any top-up credits draw from one shared pool, so status shows both. Top-up credits never expire. Run vibedrift usage for the current billing-period scan counts and limits.

For CI/CD (no browser available)
$export VIBEDRIFT_TOKEN=vd_live_xxxxx
NextRun an AI-powered deep scan
[05] Deep scans

AI-powered analysis.

Deep scans add cloud AI on top of the local scan. The CLI sends function snippets only (not full files, never git history) to the VibeDrift API.

$vibedrift . --deep
Deep scan

Scope a deep scan to changed files with --diff for a fast pre-PR check: vibedrift . --deep --diff compares uncommitted changes against HEAD, and vibedrift . --deep --diff main deep-scans everything that differs from a branch.

What deep scan adds:

·AI finds semantic duplicates that look different but do the same thing
·AI detects when function names don't match their behavior
·AI validates ambiguous findings (confirmed vs disputed)
·Concentrated reimplementation (AI sprawl) is detected and factored into your score
·AI generates a summary with actionable recommendations
·Anomaly detection catches patterns static analysis misses

Reimplementation scoring (0.14.6). On deep scans, the same logic re-built densely across many files lowers your Vibe Drift Score, because that's AI sprawl, not real structure. The penalty only kicks in when the reimplementation is genuinely concentrated; a single legacy or parallel implementation sitting in otherwise clean code stays informational and never costs you points. Local and free scores are unchanged by this, it applies only to the deep (AI) pass.

🎁
Every account gets a free deep scan each month , no card required. Free is 1 deep scan/month, Pro is 12/month. Run out and you can grab a top-up, 5 scans for $10, one-time, credits never expire and pool with your plan. Sign up free →

Deep findings aren't only a CLI thing. Your AI agent can trigger a deep check in-editor through the MCP deep-scan nudge (see MCP server); those in-loop checks draw a small fraction of a deep scan from the same shared pool.

Privacy: Only function snippets (max 60 lines each) are sent. Never full files, git history, or env vars. Processed in memory, never stored.

Local-only mode: Use --local-only to skip ALL network calls even when logged in, no scan log, no beacon, no deep analysis, no fix-prompt synthesis. Useful for:

·Air-gapped or restricted environments with no outbound internet
·Scanning sensitive codebases where zero egress is a requirement
·Offline development (airplane, train, no WiFi)
·Quick local iterations where upload latency isn't wanted
$vibedrift . --local-only
Free

Telemetry: Your code never leaves your machine. After each scan VibeDrift sends a small anonymous usage beacon (language, file count, lines of code, scan time, CLI version, finding count, and score, with no code, no file paths, and no identifiers), on by default for everyone whether you are signed in or not. Turn it off anytime:

$vibedrift telemetry disable
Free

You can also set VIBEDRIFT_TELEMETRY_DISABLED=1, or run --local-only for a fully offline scan with zero network calls. The CLI also checks npm about once a day for updates, controlled by the same flags.

NextFeed patterns to your AI agent
[06] AI agent context

Live peer-pattern context for your AI agent.

VibeDrift's headline feature isn't the scan report, it's the .vibedrift/ folder it writes alongside your CLAUDE.md. Commit it. Your AI coding agent reads it automatically on every new turn and knows exactly which pattern to match.

Without this, every AI session starts cold, it sees the file in front of it but not the 8 sibling files that follow your dominant pattern. So it drifts. The .vibedrift/ folder closes that gap.

.vibedrift/
├── context.mdProject summary, dominant patterns, open drifts
├── fix-plan.mdTop 10 drifts with copy-paste AI prompts
├── fix-prompts.mdPer-finding prompt, one drift at a time
└── patterns.jsonMachine-readable pattern data for tooling

One-shot, after a refactor:

Write once (needs a one-time sign-in)
$vibedrift . --write-context

Continuous, alongside your AI session:

Rescan and refresh on every file change
$vibedrift watch
Pro

Point it at your project while Cursor or Claude Code is working. Watch mode runs --local-only, so every save triggers a local rescan with zero network calls and the context files update before the agent's next turn.

Commit it to git. Reference it in CLAUDE.md so every AI session picks it up:

# CLAUDE.md
See .vibedrift/context.md for the current dominant patterns.
Match them when generating new code.

Both --write-context and vibedrift watch need a one-time vibedrift login, the .vibedrift/ files carry the full finding surface and the Pro fix-prompt synthesis. The HTML report itself is open to everyone, no account required.

[] MCP server

VibeDrift inside your AI agent (MCP).

The .vibedrift/ folder gives your agent context to read. The MCP server goes further: it lets Claude Code and Cursor ask VibeDrift questions while they write, "what's this repo's error-handling pattern?", "does a function like this already exist?", "would this change introduce drift?", and get an answer in well under a second. That turns drift detection into drift prevention.

The core tools are free for everyone, including signed-out users. They run entirely on your machine and never send your code, so your code never leaves your laptop. There's nothing to unlock and no plan to be on, install the server and your agent can use them right away.

Two of them, validate_change and find_similar_function, also take an opt-in deep: true that runs the full deep scan on the single function being checked, intent-mismatch detection plus AI-validated semantic duplicates, so the agent catches a misleading name or a near-clone before the code lands. This is the one metered part: deep mode sends only that one function to the API and draws a small fraction of a deep scan per check from your monthly deep-scan allotment or shared scan pool (hourly-capped, and it falls back to the local result if your budget is empty). Local tools free, deep checks metered.

1. Install the server (once per machine):

Claude Code
$claude mcp add vibedrift -- npx -y @vibedrift/cli mcp
Free

VibeDrift is a standard MCP server, there's no marketplace or extension to install. Any other client launches it with the same command. For Cursor (~/.cursor/mcp.json or project .cursor/mcp.json), and for Claude Desktop, Windsurf, Cline, VS Code, Zed and the rest, paste the same block into that client's MCP config, only the location changes, never the command:

{ "mcpServers": { "vibedrift": { "command": "npx", "args": ["-y", "@vibedrift/cli", "mcp"] } } }

2. Build the baseline, run one scan in the repo so the tools have your patterns to read (one-time, then cached):

Build the baseline
$vibedrift .
Free

3. Just code. Your agent calls these tools on its own:

get_dominant_pattern, the repo's convention for a dimension + files to copy
find_similar_function, does a near-duplicate already exist? (reuse, don't re-write)
check_file_drift, does this file match the repo's patterns?
validate_change, would this change introduce drift or a duplicate?
get_intent_hints, the conventions your CLAUDE.md / AGENTS.md declare
init, one-time, writes .vibedrift/config.json + .vibedriftignore on a fresh repo

What changes.Ask your agent to "add a function to cancel a subscription" and, instead of guessing, it checks your repo first:

// without VibeDrift, drifts 3 ways
export function cancelSub(id) { return db.query("UPDATE subs ...") // raw SQL, repo uses a repository .then(r => r ? r : null); // .then + null, repo is async/await + throws }
// with VibeDrift MCP, matches the repo on the first try
export async function cancelSubscription(id) { const sub = await repo.subscriptions.findById(id); // repository ✓ if (!sub) throw new NotFoundError(); // throws ✓ return repo.subscriptions.markCancelled(sub); // async/await ✓ }

The core tools run entirely on your machine and are free on any plan, signed in or not. If a tool returns no_baseline, run vibedrift . once to build it. The only thing that can run out is your deep-scan budget: when a deep: true check has nothing left to draw from, it quietly falls back to the local result and points you to top up.

The deep-scan nudge. When a lot has changed since your last deep scan, the agent offers, right inside your editor, to run one. Say yes and it runs in your session, no terminal switch. If your deep-scan budget is empty, it points you to upgrade or grab a top-up (5 scans for $10) and carries on.
[07] What it detects

The shapes drift takes.

Under the hood VibeDrift tracks 13 cross-file drift categories, but they roll up into a handful of patterns you'll actually recognize. These are the ones that bite. Click each to see an example.

01Architectural Contradictions
The AI chose three different data access patterns across your handlers.
userService.tsUserRepository.findById(id)
orderService.tsdb.query('SELECT * FROM...')
productService.tsprisma.product.findUnique()
02Security Gaps
03Hidden Duplicates
04Naming Inconsistency
05Phantom Scaffolding
06Implementation Gaps
07Concentrated Reimplementation (AI sprawl)
[08] How analysis works

Three layers, progressive depth.

Layer 1 and Layer 1.7 run locally on your machine (free; your code never leaves your machine, no source code or file paths are sent). Layer 2 adds cloud AI. After each scan the CLI sends a small anonymous usage beacon; turn it off with --local-only or vibedrift telemetry disable.

1
Static + Cross-File Analysis
12 static analyzers (naming, imports, error handling, complexity, security) plus 8 cross-file drift detectors that compare files against each other to find the dominant pattern and flag deviations.
localfree
1.7
Code DNA
Structural fingerprinting. Hash-based duplicate detection. Operation sequence analysis. Taint tracking.
localfree
2
Deep Scan (AI)
ML semantic embeddings for duplicates static analysis can't see. Intent mismatch detection. AI validation. Concentrated-reimplementation scoring. AI summary.
deep scan

Most drift is caught locally for free; the deep (AI) pass adds the semantic findings, intent mismatches, and reimplementation scoring that pattern matching alone can't reach.

[09] Reading the report

Understanding your score.

Score grades:

A90-100Highly consistent, minimal drift
B75-89Good shape, a few areas to clean up
C50-74Notable drift, review the findings
D25-49Significant issues across categories
F0-24Heavy drift, sessions weren't coordinated

Five scoring categories:

Architectural Consistency
Data access, DI, error handling, import patterns, cross-file drift
Security Posture
Auth coverage, injection risks, hardcoded secrets, taint flows
Redundancy
Duplicates, dead code, TODO density, Code DNA fingerprints, and (on deep scans) concentrated reimplementation
Intent Clarity
Complexity, unclear naming, commented-out code, documentation
Dependency Health
Phantom/missing deps, env vars, version management

Report sections: Overall score → Category radar → Drift findings (with code evidence) → Per-file rankings (worst to best). Start fixing from the bottom.

One category can drag the headline down. The overall score is a multiplicative blend of the five categories, so a single collapsed category (say, security with an unguarded route) pulls the whole grade down hard rather than averaging out. That's deliberate: a 95 everywhere with one 20 isn't a 76-quality codebase. Surface-specific categories with no findings (Security Posture, Intent Clarity) are shown as not-measured rather than given a free full score.

On deep scans, Redundancy also reflects concentrated reimplementation: dense cross-file reinvention of the same logic lowers the score, while a sparse or legacy parallel implementation stays informational and doesn't.

[10] Dashboard

Track your progress.

When logged in, every scan is saved to vibedrift.ai/dashboard. You get:

·Score timeline, see if fixes actually improve your score
·Scan detail, full report embedded, shareable link
·Project grouping, scans auto-grouped by git remote URL
·Export, download as JSON, CSV, or DOCX
·API tokens, create and manage CI/CD tokens
·Billing, manage plan, buy a deep-scan top-up, view usage
[11] CI/CD setup

GitHub Actions.

Set VIBEDRIFT_TOKEN as a repo secret, then add this workflow:

.github/workflows/vibedrift.yml
name: VibeDrift
on: [pull_request]

jobs:
  drift-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npx @vibedrift/cli . \
          --deep --json \
          --fail-on-score 70
        env:
          VIBEDRIFT_TOKEN: ${{ secrets.VIBEDRIFT_TOKEN }}

--fail-on-score 70 exits with code 1 if the score drops below the threshold, failing the PR check.

--deep on every pull request burns through your monthly deep-scan budget fast (Free 1, Pro 12). Gate it to the branches that matter, e.g. only PRs targeting main, or drop --deep for routine PR checks and let the free local scan gate them. The GitHub Action below shows the branch-gating pattern, and a published action handles PR comments for you.

Raw CLI vs the published action. The snippet above is the universal path, npx @vibedrift/clidrops into any pipeline (GitLab, CircleCI, Jenkins, Bitbucket). If you're on GitHub and want score-delta PR comments out of the box, use the dedicated action in section 14 instead.

[12] CLI reference

All commands.

Scanning
vibedrift [path]Free local scan (path defaults to .)
vibedrift [path] --deepAI-powered deep scan (needs login)
vibedrift watch [path]Rescan on change, refresh .vibedrift/ (local-only)
vibedrift mcpRun the local MCP server over stdio
Setup
vibedrift initGuided setup: .vibedriftignore + config
vibedrift ignore <glob>Add path glob(s) to .vibedriftignore
vibedrift hook <install|uninstall|status>Manage a pre-push drift-score gate
Options
--format html|terminal|json|csv|docxOutput format (default: html)
--output <path>Output file path
--jsonShorthand for --format json
--fail-on-score <n>Exit 1 if score below n (0-100)
--deepAI deep analysis (requires login)
--diff [ref]Scope to git-changed files (bare = vs HEAD)
--write-contextWrite committable .vibedrift/ files (needs login)
--local-onlySkip ALL network calls (offline scan)
--project-name <name>Override auto-detected project name
--privateAnonymize project name
--no-codednaSkip Code DNA layer
--verboseVerbose output
--include <glob>Include matching files only
--exclude <glob>Exclude matching files
Account & billing
vibedrift loginAuthenticate via browser (device flow)
vibedrift logoutRemove and revoke credentials
vibedrift statusAccount, plan, deep-scan credits
vibedrift usageBilling-period scan counts + limits
vibedrift upgradeOpen the pricing page
vibedrift billingOpen the Stripe customer portal
Utility
vibedrift telemetry <enable|disable>Manage the anonymous scan beacon
vibedrift doctorDiagnose install, auth, connectivity
vibedrift updateUpdate the CLI to the latest version
vibedrift feedback [msg]Send feedback
vibedrift --versionShow CLI version

Check your remaining deep-scan budget (monthly allotment + pooled top-up credits) with vibedrift status or vibedrift usage; buy a top-up from vibedrift billing or the dashboard.

[13] Free vs Deep

What each scan includes.

CapabilityFreeDeep
Drift score (0-100)
5-category breakdown
Cross-file drift findings
Static analysis (12 analyzers)
Code DNA fingerprinting
Per-file rankings
HTML report
CI fail-on-score
AI summary + recommendations
AI semantic duplicate detection
Intent lie-detection (name vs behavior)
In-loop AI verdict on borderline matches
Concentrated reimplementation factored into score
Coherence report graded vs your own patterns
Copy-ready fix prompts
AI anomaly detection
💡
Free catches the bulk of drift with local analysis. Deep adds the AI layer on top, semantic duplicates, intent mismatches, concentrated reimplementation, and anomalies that pattern matching alone can't find.
[14] GitHub Action

Catch drift before merge.

The VibeDrift GitHub Action runs on every PR and posts a comment with the score delta + new drifts introduced. Optionally fails the check if the score drops below your threshold.

.github/workflows/vibedrift.yml
name: VibeDrift
on: [pull_request]

permissions:
  pull-requests: write

jobs:
  drift-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: skhan75/vibedrift-actions@v1
        with:
          token: ${{ secrets.VIBEDRIFT_TOKEN }}
          fail-on-score: 70
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Setup:

·Sign up at vibedrift.ai/login (free, no card)
·Go to Dashboard → Settings → copy your API Token
·Add it as VIBEDRIFT_TOKEN in your repo's GitHub Secrets (Settings → Secrets)
·Add the workflow file above, done

What you get on every PR: a comment showing the score delta (↑ or ↓ vs main), new drifts introduced, consequence lines, and a link to the full report on your dashboard.

Deep scan on release branches: add deep: ${{ github.base_ref == 'main' }} to run AI analysis only on PRs targeting main. Free scans are unlimited; deep scans draw from your monthly budget (Free 1, Pro 12). Gating deep to release branches keeps you from exhausting it on routine PRs, and if you do run out, a one-time top-up (5 scans for $10) refills the shared pool.

Monorepo: set path: packages/api to scan a subdirectory.

Any CI pipeline (not just GitHub): The GitHub Action is a convenience wrapper. The CLI works in any CI system, just run npx @vibedrift/cli . --json --fail-on-score 70 with VIBEDRIFT_TOKEN set as an environment variable.

GitLab · CircleCI · Bitbucket · Jenkins
# GitLab CI
vibedrift:
  stage: test
  script:
    - npx @vibedrift/cli . --json --fail-on-score 70
  variables:
    VIBEDRIFT_TOKEN: $VIBEDRIFT_TOKEN

# CircleCI
- run:
    name: VibeDrift
    command: npx @vibedrift/cli . --json --fail-on-score 70

# Bitbucket Pipelines
- step:
    name: VibeDrift
    script:
      - npx @vibedrift/cli . --json --fail-on-score 70

# Jenkins
stage('VibeDrift') {
  sh 'npx @vibedrift/cli . --json --fail-on-score 70'
}

The --json flag outputs the full scan result as JSON (parseable by downstream tools). --fail-on-score N exits with code 1 when the score drops below your threshold, blocking the pipeline. Add --deep for AI analysis (uses scan budget).

Offline / air-gapped: use --local-only to skip all network calls. The scan runs fully locally with no dashboard upload and no telemetry.

[15] Pricing

Simple pricing.

The local CLI scans and the MCP tools are free for everyone. You only pay for cloud deep scans, and only when you run out of your monthly allotment.

·Free, $0, unlimited local scans + free local MCP tools, 1 deep scan/month
·Pro, $15/mo, 12 deep scans/month + in-loop MCP deep checks + CI/CD + dashboard
·Enterprise, custom, BYOC / self-host + SSO/SAML + SLA, contact sales
·In-loop MCP deep checks draw a small fraction of a deep scan from the shared pool

Deep-scan top-up. Out of deep scans? Grab a top-up, 5 scans for $10, one-time, buyable on both Free and Pro. Credits stack on a shared scan pool used by both CLI deep scans and in-loop MCP deep checks, and they never expire.

One shared pool.Your monthly allotment, top-up credits, and in-loop MCP deep checks all draw from and feed the same balance, so there's a single number to watch (vibedrift status), not separate buckets to reconcile.

View full pricing details →
Ready to scan?
$ npx @vibedrift/cli .
Sign up freeView pricing