sniff Svelte Themes

Sniff

AI-powered QA testing tool. 5 checks in one command: source scanning, accessibility (axe-core), visual regression (pixelmatch), performance (Lighthouse), and AI exploration. Works with React, Next.js, Vue, Svelte, Angular. Zero config. Native MCP integration.

Sniff - open source AI-powered QA testing tool with source scanning, accessibility audits, visual regression, performance budgets, and AI exploration

npm License CI Node Stars

One command. Eight checks. Zero config.
Source bugs, dead links, API endpoints, accessibility, visual regression, performance, AI exploration, and cross-referencing. All in one pass.



What is this?

You ship features. But did you actually test them?

sniff is an AI-powered QA tool that scans your project for real problems: leftover debugger statements, dead links, API endpoint issues, accessibility violations, visual regressions, performance budget breaches, and adversarial edge cases. It runs eight checks in a single command and cross-references source code with browser behavior for high-confidence findings.

npx sniff-qa

That's it. No config files. No signup. No API keys. It just works.


Key facts

  • What: Open source AI-powered QA testing tool that runs 8 checks in a single command: source scanning (6 rule categories + dead links + API endpoint discovery), accessibility audits, visual regression, performance budgets, AI-driven exploration, and source/browser cross-referencing
  • Who it's for: Frontend and full-stack developers who want automated QA without configuring multiple tools
  • How it works: Uses Playwright for browser automation, axe-core for WCAG accessibility, Lighthouse for performance, pixelmatch for visual diffs, and Anthropic Claude for adversarial AI exploration
  • Install: npx sniff-qa (zero config, no signup, no API keys required for base checks)
  • Comparable to: Combines Lighthouse CI + Pa11y + BackstopJS into one tool, plus source code scanning and AI-driven edge case discovery that no other tool offers
  • Unique: First QA tool with native MCP (Model Context Protocol) integration. Flakiness quarantine system isolates non-deterministic test results automatically

Quick start

Step Action
1 Run a source scan: npx sniff-qa
2 Run the full audit: npx sniff-qa --url http://localhost:3000
3 Read the report and fix what matters

The source scan finishes in seconds. The full audit adds accessibility, visual regression, performance, and AI exploration on top of it.

[!TIP] Drop your URL in sniff.config.ts once and you can just run sniff for the full audit every time.


The three modes

graph LR
    A["๐Ÿ” Quick Scan<br/><sub>npx sniff-qa</sub>"] --> B["Source bugs only<br/><sub>No browser needed</sub>"]
    C["๐Ÿ›ก๏ธ Full Audit<br/><sub>npx sniff-qa --url URL</sub>"] --> D["All 8 checks<br/><sub>Source + Browser + Xref</sub>"]
    E["๐Ÿ—๏ธ CI Mode<br/><sub>npx sniff-qa --url URL --ci</sub>"] --> F["Deterministic<br/><sub>Skips AI explorer</sub>"]

    style A fill:#fef2f2,stroke:#ef4444,color:#7f1d1d
    style B fill:#fee2e2,stroke:#ef4444,color:#7f1d1d
    style C fill:#fef2f2,stroke:#ef4444,color:#7f1d1d
    style D fill:#fee2e2,stroke:#ef4444,color:#7f1d1d
    style E fill:#fef2f2,stroke:#ef4444,color:#7f1d1d
    style F fill:#fee2e2,stroke:#ef4444,color:#7f1d1d
npx sniff-qa                                   # quick scan (no browser)
npx sniff-qa --url http://localhost:3000       # full audit (everything)
npx sniff-qa --url http://localhost:3000 --ci  # ci mode (skips AI explorer)

CI mode auto-skips the AI explorer because it is non-deterministic. Everything else runs exactly the same.


What it checks

Check Example finding Details
๐Ÿ“„ Source code debugger statement in handler.ts:42 Leftover debugger, placeholder text, hardcoded URLs, broken imports, TODO/FIXME
๐Ÿ”— Dead links Broken link ./guide.md in README.md:28 Validates internal file refs, external URLs (HTTP HEAD with retry), and anchor links. Catches 404s before your users do
๐Ÿ›ฃ๏ธ API endpoints POST /users has no input validation Discovers routes from Express, Fastify, Hono, Next.js, SvelteKit, tRPC, and GraphQL. Flags missing error handling, auth, and hardcoded secrets
โ™ฟ Accessibility Missing form label on /login WCAG 2.x violations via axe-core with exact fix guidance
๐Ÿ–ผ Visual regression /pricing changed 2.3% of pixels Local pixel diffing via pixelmatch. Commit baselines to track changes
โšก Performance LCP 4200ms on /dashboard (budget: 2500ms) Lighthouse budgets for LCP, FCP, TTI
๐Ÿค– AI explorer XSS in /signup email field crashes app Roams your app, fills forms with adversarial inputs, reports crashes and console errors
๐Ÿ”€ Cross-reference console.log in source confirmed at runtime Correlates source findings with browser evidence. Corroborated issues get bumped severity and HIGH confidence tags

How it works

Sniff pipeline showing 8 checks flowing through source scanner, browser runner, cross-reference engine, and report output

Your code goes in. A report with actionable findings comes out. When you provide a URL, sniff also runs browser checks and cross-references source findings with runtime behavior for high-confidence results. You don't configure anything.


Compared to

Sniff Lighthouse CI Pa11y BackstopJS
Source scanning โœ… โŒ โŒ โŒ
Dead link checking โœ… โŒ โŒ โŒ
API endpoint discovery โœ… โŒ โŒ โŒ
Accessibility โœ… partial โœ… โŒ
Visual regression โœ… โŒ โŒ โœ…
Performance โœ… โœ… โŒ โŒ
AI exploration โœ… โŒ โŒ โŒ
Cross-reference engine โœ… โŒ โŒ โŒ
Flakiness quarantine โœ… โŒ โŒ โŒ
Single command โœ… โŒ โŒ โŒ
MCP server โœ… โŒ โŒ โŒ
Zero config โœ… โŒ โŒ โŒ

[!IMPORTANT] Sniff is the first QA tool with native MCP integration. Your AI editor can trigger scans, read results, and fix issues without you switching context.


Source scanning rules

Sniff ships 6 rule categories that run on every scan. No browser needed.

Rule ID Severity What it catches
Debug statements debug-console-log, debug-debugger medium / high console.log, console.debug, debugger left in production code
Placeholder text placeholder-lorem, placeholder-todo, placeholder-fixme, placeholder-tbd high / medium Lorem ipsum, TODO, FIXME, TBD markers
Hardcoded URLs hardcoded-localhost, hardcoded-127 medium http://localhost:* and http://127.0.0.1:* in non-test files
Broken imports broken-import medium Relative imports that don't resolve to a file (with TS extension mapping)
Dead links dead-link-internal, dead-link-external, dead-link-anchor high / medium / low Broken file references, 404 external URLs, missing anchor targets
API endpoints api-no-error-handling, api-no-validation, api-no-auth, api-hardcoded-secret critical / medium / low Route handlers missing try/catch, input validation, auth, or containing hardcoded secrets

Scans .md, .html, .jsx, .tsx, .vue, .svelte, and .astro files for links and validates them:

  • Internal links: Checks the target file exists (with extension resolution and index file fallback)
  • External links: Sends HTTP HEAD requests with timeout, retry, and GET fallback for servers that reject HEAD
  • Anchor links: Validates #section references against markdown headings and HTML id/name attributes
  • Smart skipping: Ignores mailto:, tel:, data:, javascript:, and template variables
HIGH  README.md:28        Broken internal link: ./missing-guide.md
MED   docs/api.md:15      HTTP 404: https://example.com/old-endpoint
MED   CONTRIBUTING.md:8   Anchor #setup-guide not found in ./README.md

API endpoint discovery

Automatically discovers API routes from 8 frameworks:

Framework Detection method
Express app.get(), router.post(), etc.
Fastify fastify.get(), fastify.post(), etc.
Hono app.get() with new Hono() detection
Next.js App Router app/**/route.ts with exported GET/POST handlers
Next.js Pages Router pages/api/**/*.ts
SvelteKit routes/**/+server.ts
tRPC publicProcedure.query() / .mutation()
GraphQL type Query { } / type Mutation { } definitions

For each endpoint, sniff checks for:

  • Missing error handling (no try/catch or error middleware)
  • Missing input validation on POST/PUT/PATCH routes (no zod, joi, yup, etc.)
  • Missing auth middleware on non-public routes
  • Hardcoded secrets (API keys, tokens, Stripe keys, GitHub tokens)
CRIT  src/routes.ts:12    Hardcoded Stripe key in POST /checkout handler
MED   src/api.ts:5        POST /users has no input validation
MED   src/api.ts:18       GET /admin/data has no error handling
LOW   src/api.ts:25       GET /admin/data has no visible auth middleware
INFO  Discovered 6 API endpoints (express: 4, nextjs-app: 2)

Cross-reference engine

When you run sniff with --url, the cross-reference engine correlates source code findings with browser runtime behavior. Findings confirmed in both layers get bumped severity and a HIGH confidence tag.

5 correlation strategies:

Source finding Browser evidence Correlation
Broken import / dead link 404 network request broken-import-to-404
console.log statement Console output captured console-log-to-runtime
Hardcoded localhost URL Network request to that URL hardcoded-url-to-network
Missing label / a11y issue axe-core violation source-a11y-to-axe
Placeholder text in source Text visible on page placeholder-to-runtime
CORROBORATED (source + browser evidence)
  src/handler.ts:42  console.log("debug data")
    Source: debug-console-log rule triggered
    Browser: console.log output captured at /dashboard
    Confidence: HIGH (confirmed in both layers)

Architecture

Sniff architecture showing source scanner, browser runner, cross-reference engine, and report engine

Example output

Sniff terminal output showing source findings, browser results, and cross-referenced corroborated findings

Works with your stack

No config needed. Sniff auto-detects your framework from package.json and source files.

โš›๏ธ React โ–ฒ Next.js ๐Ÿ’š Vue ๐Ÿ”ถ Svelte ๐Ÿ…ฐ๏ธ Angular ๐ŸŒ Vanilla
JSX / TSX App Router SFC Components Templates HTML / CSS

๐Ÿ”Œ Use with your AI editor

Sniff ships an MCP server. Pick your tool and copy the snippet.

Claude Code
claude mcp add sniff-qa npx sniff-qa --mcp

Or .mcp.json:

{
  "mcpServers": {
    "sniff-qa": { "command": "npx", "args": ["sniff-qa", "--mcp"] }
  }
}
Cursor

~/.cursor/mcp.json or .cursor/mcp.json:

{
  "mcpServers": {
    "sniff-qa": {
      "type": "stdio",
      "command": "npx",
      "args": ["sniff-qa", "--mcp"]
    }
  }
}
Windsurf

~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "sniff-qa": { "command": "npx", "args": ["sniff-qa", "--mcp"] }
  }
}
Codex CLI
codex mcp add sniff-qa -- npx -y sniff-qa --mcp

Or add to ~/.codex/config.toml:

[mcp_servers.sniff-qa]
command = "npx"
args = ["-y", "sniff-qa", "--mcp"]
Gemini CLI

~/.gemini/mcp_config.json:

{
  "mcpServers": {
    "sniff-qa": { "command": "npx", "args": ["sniff-qa", "--mcp"] }
  }
}
Continue.dev

.continue/mcpServers/sniff-qa.yaml:

mcpServers:
  sniff-qa:
    command: npx
    args: [sniff-qa, --mcp]
    type: stdio
VS Code + Copilot

Add to .vscode/mcp.json:

{
  "servers": {
    "sniff-qa": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "sniff-qa", "--mcp"]
    }
  }
}
OpenClaw
clawhub install sniff-qa

Or add to ~/.openclaw/openclaw.json:

{
  "mcpServers": {
    "sniff-qa": {
      "command": "npx",
      "args": ["-y", "sniff-qa", "--mcp"]
    }
  }
}

Once configured, ask: "Scan this project for issues" or "Check accessibility on localhost:3000".

MCP tools exposed: sniff_scan (source), sniff_run (browser), sniff_report (last results).


Install

npm install -D sniff-qa
{
  "scripts": {
    "qa": "sniff --url http://localhost:3000"
  }
}

Then run npm run qa. Requires Node.js 22+. Playwright browsers install automatically the first time.


๐Ÿ—๏ธ CI integration

npx sniff-qa ci

Generates .github/workflows/sniff.yml with Playwright caching, JUnit output, flakiness quarantine, and report artifacts.

Flakiness quarantine. Tests that fail 3 of 5 runs get quarantined. They still run, still appear in reports, but won't block your pipeline.


All commands

๐Ÿ“‹ Full CLI reference
sniff                       quick scan (source only)
sniff --url <url>           full audit (everything)
sniff --url <url> --ci      ci mode (no AI explorer)

sniff init                  scaffold sniff.config.ts
sniff ci                    generate .github/workflows/sniff.yml
sniff report                show last results
sniff update-baselines      accept current screenshots as baselines

Flags (all optional)

Flag Effect
--no-explore Skip AI explorer in full mode
--no-browser Force source-only even when URL is set
--max-steps <n> Cap exploration steps (default: 50)
--no-headless Show the browser window
--format html,json,junit Choose report formats
--fail-on critical,high Severities that exit non-zero
--track-flakes Enable flakiness detection
--json Machine-readable output

Configuration

โš™๏ธ sniff.config.ts reference

Optional. Drop sniff.config.ts in your project root:

import { defineConfig } from 'sniff-qa';

export default defineConfig({
  browser: {
    baseUrl: 'http://localhost:3000',
  },
  viewports: [
    { name: 'mobile', width: 375, height: 667 },
    { name: 'desktop', width: 1280, height: 720 },
  ],
  performance: {
    budgets: { lcp: 2500, fcp: 1800, tti: 3800 },
  },
  visual: { threshold: 0.1 },
  exploration: { maxSteps: 50 },
  flakiness: { windowSize: 5, threshold: 3 },

  // Dead link checker (new in v0.2)
  deadLinks: {
    checkExternal: true,      // validate external URLs via HTTP
    timeout: 5000,            // ms per request
    retries: 2,               // retry failed requests
    ignorePatterns: [],       // regex patterns to skip
    maxConcurrent: 10,        // parallel HTTP requests
  },

  // API endpoint discovery (new in v0.2)
  apiEndpoints: {
    checkErrorHandling: true, // flag missing try/catch
    checkValidation: true,    // flag missing input validation
    checkAuth: true,          // flag missing auth middleware
    checkSecrets: true,       // flag hardcoded secrets
    frameworks: [],           // empty = auto-detect all
  },

  // Disable specific rules
  rules: {
    'debug-console-log': 'off',     // example: allow console.log
    'dead-link-internal': 'off',    // example: skip dead link checks
  },
});

๐Ÿ”’ Trust and privacy

๐Ÿšซ No telemetry. Sniff does not phone home. Ever.
๐Ÿ”‘ No signup. No accounts. No API keys for core functionality.
๐Ÿ“ฆ No data collection. Your code stays on your machine.
๐Ÿ‘๏ธ Open source. Read every line. Apache 2.0.

[!NOTE] The AI explorer requires an Anthropic API key only if you want the chaos monkey feature. The other seven checks (source scanning, dead links, API endpoints, accessibility, visual regression, performance, cross-referencing) work completely offline with zero external calls. External link checking in the dead link scanner makes HTTP requests to validate URLs, but never sends your code.


Built on

Playwright ยท axe-core ยท Lighthouse ยท pixelmatch ยท Zod ยท MCP SDK ยท Anthropic SDK


Contributing

Easiest way in: add a source rule. Each rule is a regex pattern with a severity level in src/scanners/source/rules/. See CONTRIBUTING.md.

Good first contributions:

  • ๐Ÿ”ง Add a new source scanning rule
  • ๐Ÿ› Report a false positive
  • ๐Ÿ“š Improve documentation

License

Apache 2.0


LinkedIn X Website

Built by Adam Boudjemaa ยท Apache 2.0 ยท No telemetry ยท No data collection

Top categories

Loading Svelte Themes