Design quality + WCAG gate for AI-generated code

AI writes fast. Deslint keeps it clean.

AI ships design drift, dark-mode gaps, and WCAG failures at the speed of autocomplete. Deslint catches them in your editor, your CI, and every PR — without ever sending your code to a cloud.

20 deterministic rulesWCAG 2.2 & 2.1 AA mapped5 frameworksCode never leaves your machine
file:///.deslint/compliance.html
WCAG 2.2 Compliance Report
Project: deslint-docs · Scanned: Apr 9, 2026 · 18 files
WCAG 2.2
Level AA
WCAG 2.1 AA*
Level AA
Pass Rate
100%
Coverage
100%
Violations
0
ADA Title II note: The public-entity ADA Title II rule adopts WCAG 2.1 Level AA as its technical standard. Every criterion evaluated here also exists in WCAG 2.1.
Level A(5/5 passing)Conformant
1.1.1Non-text ContentPass
1.3.1Info and RelationshipsPass
2.4.4Link Purpose (In Context)Pass
3.1.1Language of PagePass
4.1.2Name, Role, ValuePass
Level AA(8/8 passing)Conformant
1.4.3Contrast (Minimum)Pass
1.4.10ReflowPass
1.4.11Non-text ContrastPass
2.4.6Headings and LabelsPass
2.4.7Focus VisiblePass
ADA Title II
Conformant
Criteria Passing
13 / 13
0
Bytes leave your machine
No cloud, no telemetry, no LLM
20
Deterministic rules
Design drift + WCAG 2.2 AA
5
Frameworks, one config
React · Vue · Svelte · Angular · HTML
1,145
Tests passing
Every rule: valid + invalid + fix

Privacy by architecture

Three zeros nobody else can claim

Security and legal teams buy Deslint because there is nothing to review: no vendor, no contract, no cloud, no LLM, no data. The architecture is the privacy policy.

Zero cloud

Your code never leaves your machine

No SaaS roundtrip. No upload step. No API key in a CI secret. Deslint runs as an ESLint plugin and a local CLI — same binaries, offline-capable, air-gap friendly.

Zero telemetry

No analytics, no phone-home

Deslint does not collect usage, file paths, rule triggers, machine IDs, or anonymous counts. There is nothing to opt out of because there is nothing being collected in the first place.

Zero LLMs

Deterministic static analysis

Every rule is pure AST pattern matching — no LLM, no embedding, no fuzzy judgment. Same input always produces the same output, which is the only way compliance evidence is defensible.

Offline-capable
Runs behind a firewall, on an air-gapped CI, inside a container without egress
Reproducible builds
Same commit → same Design Health Score → same compliance verdict
MIT-licensed
Inspect every rule, fork it, vendor it, audit it

Visual proof

Before and after, rendered in your browser — not a screenshot.

Four common failures AI code generators ship — dark mode, responsive reflow, contrast, and the invisible accessibility gaps that only show up in audits. Each one rendered live, before and after Deslint fixes it.

01

Dark mode · flipped

AI wrote hardcoded colors. The preview looks fine. Flip to dark mode and the page breaks.

localhost:3000/pricing
Before
localhost:3000/pricing
After
Rule: deslint/dark-mode-coverageWCAG 1.4.3 · 1.4.11Auto-fix: adds dark: variants
Or watch the 40-second loop
Same four beats, pre-rendered. Perfect for sharing.
Every fix is deterministic — same input, same output.Inline-styled demos so this page passes its own compliance check.npx deslint scan on your repo to see yours.

The self-correction loop

AI writes the code. Deslint tells it exactly what to fix. Over stdio, in milliseconds, with zero cloud.

The @deslint/mcp server speaks the Model Context Protocol over stdio — the same transport Cursor and Claude Code already use. Your assistant calls analyze_file and analyze_and_fix, gets back structured violations with rule IDs and autofixes, and corrects its own output before you even see it.

AI just wrote this3 violations
Button.tsx
1
2
3
4
5
6
7
8
9
export function Button({ children }) {
return (
<button
className="rounded-md px-[13px] py-[7px]
bg-[#1a5276] text-white"
>
{children}
</button>
}
Deslint MCPstdio · JSON-RPC 2.0
@deslint/mcplistening
// handshake
initialize
serverInfo = "deslint"
tools/list
3 tools ready
analyze_file
4 violations / 600ms
deslint/no-arbitrary-colorsbg-[#1a5276]bg-primary
deslint/no-arbitrary-spacingpx-[13px]px-3
deslint/no-arbitrary-spacingpy-[7px]py-1.5
deslint/no-arbitrary-typographytext-[15px]review
analyze_and_fix
3 auto-fixed · 1 flagged / 26ms
────────────────────────
local-first · no LLM · 0 bytes egress
After Deslint MCP3 auto-fixed · 1 flagged
Button.tsxclean
1
2
3
4
5
6
7
8
9
export function Button({ children }) {
return (
<button
className="rounded-md px-3 py-1.5
bg-primary text-white"
>
{children}
</button>
}
3 toolsregistered over MCP

analyze_file · analyze_project · analyze_and_fix

<1stotal round trip

initialize + list + analyze + fix

0 bytesof source code sent anywhere

stdio transport · no network · no LLM

One engine, everywhere you work

Same rules in your editor, CI, and PR

Configure Deslint once in your flat config. Every surface — IDE, terminal, GitHub Action, MCP agent — runs the same deterministic rule engine against the same config. No duplicated rules, no divergent results, no "it passed locally" drift.

01 · In your editor

Squiggles as you type

ESLint v10 flat config plugin. Drop into any existing setup — no new toolchain, no peer-dep war. Errors and autofixes appear in Cursor, VS Code, WebStorm, and every ESLint-aware IDE instantly.

  • React, Vue, Svelte, Angular, HTML
  • Autofix for color + spacing drift
  • Every rule try/catch wrapped — never crashes lint
components/Button.tsx — deslint-demo
Button.tsx
Card.tsx
1
2
3
4
5
6
7
8
9
export function Button({ children }) {
return (
<button
className="rounded-md px-4 py-2 bg-[#1a5276] text-white"
>
{children}
</button>
)
}
1 ProblemTypeScript ReactUTF-8
Ln 4, Col 35Deslint
Arbitrary color #1a5276 — use bg-primary instead
deslint/no-arbitrary-colors
Quick fix: Replace bg-[#1a5276] with bg-primary

02 · In your terminal

Design Health Score for the whole codebase

One command scans every file, produces a 0–100 Design Health Score, and generates a self-contained HTML compliance report you can email to legal or attach to a SOC 2 audit.

  • deslint scan / fix / compliance / trend
  • Per-category scores + violation breakdown
  • WCAG 2.2 + 2.1 AA report, no external assets
~/projects/my-saas-app — zsh
$ npx deslint scan
Scanning 247 files across 4 frameworks...
Parsed React JSX (148 files)
Parsed Vue SFC (52 files)
Parsed plain HTML (47 files)
Deslint Design Health Report
────────────────────────────────────
Design Health Score: 88/100
Colors
923 violations
Spacing
923 violations
Typography
865 violations
Responsive
971 violation
A11y (WCAG)
10013/13 pass
Full report: .deslint/report.html
$

03 · In your pull requests

Block drift before it lands

GitHub Action runs the same engine as your local scan. Posts inline review comments with rule ID, WCAG mapping, and a commit-ready suggested change. Fails the check when the score drops below your threshold.

  • Inline review comments on the offending line
  • Every violation linked to its WCAG criterion
  • Configurable gate: min-score, per-category, fail-on a11y
Conversation14
Commits7
Checks3
Files changed8
apps/web/components/PricingCard.tsx+18 −4
1212
1313 <div className="rounded-lg p-6">
14 <img src="/icon.png" />
14+ <img src="/icon.png" alt="" />
1515 <h2>Pro plan</h2>
16+ <p className="text-[13px]">$29/mo</p>
D
deslint-botcommented on this linejust now
Arbitrary typography text-[13px] breaks the type scale. Use text-sm (14px) or text-xs (12px).
WCAG 1.4.4 Resize Text·deslint/no-arbitrary-typography
Suggested change
className="text-[13px]"
+className="text-sm"
1617 </div>
deslint / design-quality — 1 violation blocking mergeDetails

What it catches

The bugs that slip past type checkers and tests

AI code compiles. It passes your tests. It renders. And then a designer opens the screen and finds six shades of blue, inconsistent spacing, and a contrast ratio that fails an audit. Deslint catches all of it before the commit lands.

Color drift

Arbitrary hex values, `text-[#abc]` escapes, off-palette tokens. Maps every color back to your Tailwind config or W3C tokens.

-text-[#1a5276] bg-[rgb(39,174,96)]
+text-primary bg-pass
no-arbitrary-colorsno-inline-styles

Spacing inconsistency

Off-scale padding, margins, and gaps. Enforces your 4/8px grid — no more `p-[13px]` creeping in.

-p-[13px] gap-[7px]
+p-3 gap-2
spacing-scale-consistencyno-arbitrary-values

Typography scale breaks

Font sizes outside your type scale, mixed weights, arbitrary line heights — hierarchy that reads like a ransom note.

-text-[15px] leading-[22px]
+text-base leading-relaxed
typography-scaletypography-hierarchy

Broken responsive layouts

Missing mobile breakpoints, desktop-only flex rows, fixed widths. Catches layouts AI forgot to make responsive.

-flex flex-row gap-8
+flex flex-col md:flex-row gap-4 md:gap-8
responsive-requiredno-fixed-dimensions

Accessibility violations

Missing alt text, bad contrast, label-less inputs, no focus states, heading skips. Mapped to WCAG 2.2 + 2.1 AA criteria.

-<img src="hero.png" />
+<img src="hero.png" alt="Product screenshot" />
image-alt-texta11y-color-contrastform-label-required

Dark mode gaps

Hardcoded light-only colors, backgrounds without `dark:` variants, text that vanishes on a dark theme.

-bg-white text-gray-900
+bg-white dark:bg-gray-950 text-gray-900 dark:text-gray-100
dark-mode-required

The gap nobody else fills

Deslint is the only tool that catches design drift, WCAG failures, and framework drift in one pass

Each of these tools does one slice well. eslint-plugin-jsx-a11y is React-only accessibility. eslint-plugin-tailwindcss stalled on Tailwind v4. SonarQube ships code quality to a server. CodeRabbit is an LLM. Deslint is the single local-first, deterministic gate that covers every row.

Capability
DeslintThis tool
jsx-a11yReact a11y
tailwindcssESLint plugin
SonarQubeServer
CodeRabbitAI reviewer
Design-system drift
Arbitrary colors, spacing, typography
WCAG 2.2 + 2.1 AA mapping
Every violation → legal criterion
Framework-agnostic
React, Vue, Svelte, Angular, HTML
ESLint v10 flat config
First-class, no legacy shim
Tailwind v3 AND v4
Both class generations supported
Local-first, zero cloud
No SaaS roundtrip, no API keys
Deterministic — no LLM
Same input → same output, every time
ADA Title II compliance report
Self-contained HTML, audit-ready
Autofix
Committable suggested change
FullPartialNot covered
ADA Title II ready

Accessibility, treated as a legal requirement — not a checkbox

The 2024 ADA Title II rule locks public entities to WCAG 2.1 Level AA. Every criterion Deslint statically detects is in that set, so a passing scan doubles as real compliance evidence.

Every violation links to the W3C specification. The compliance report is a single self-contained HTML file — email it to your counsel, attach it to a SOC 2 audit, or drop it into a Jira ticket.

13 WCAG criteria statically detected today. Everything Deslint cannot verify is flagged as "manual review required" — no false all-clear.

WCAG 2.2 / 2.1 criteria covered13 / 13 mapped
  • 1.1.1Non-text ContentA
  • 1.3.1Info and RelationshipsA
  • 1.4.3Contrast (Minimum)AA
  • 1.4.4Resize TextAA
  • 1.4.10ReflowAA
  • 1.4.11Non-text ContrastAA
  • 1.4.12Text SpacingAA
  • 2.4.4Link Purpose (In Context)A
  • 2.4.6Headings and LabelsAA
  • 2.4.7Focus VisibleAA
  • 3.1.1Language of PageA
  • 3.3.2Labels or InstructionsA
  • 4.1.2Name, Role, ValueA

5 Level A · 8 Level AA. Conformance is computed "at-or-below": one Level A failure drops the whole claim to Not Met.

Framework-agnostic

Same rules, every framework you already ship

Deslint parses the actual template — JSX, Vue SFC, Svelte, Angular, HTML — not a stringly-typed regex. One config, one rule set, zero per-framework plugins.

FrameworkDesign systemAccessibilityAutofix
React / JSX
TSX, JSX, className / clsx / cva
Vue SFC
.vue templates via vue-eslint-parser
Svelte
.svelte via svelte-eslint-parser
Angular
Inline + external templates
HTML
Plain .html via @html-eslint/parser
Full supportPartial — some rules read-onlyjsx-a11y is React-only. tailwindcss-eslint stalled on v4. Deslint covers both.

30-second install

Three steps from npm install to a Design Health Score

No account. No API key. No cloud signup. Everything runs against your existing ESLint setup the moment you install the package.

01

Install

Add the ESLint plugin to your existing project. No new toolchain, no separate config file, no peer-dep war.

bash
npm install -D @deslint/eslint-plugin
02

Configure

Drop Deslint into your flat config alongside whatever ESLint rules you already run. One import, one recommended preset.

eslint.config.ts
import deslint from '@deslint/eslint-plugin';
 
export default [
deslint.configs.recommended,
];
03

Run

Errors appear in every ESLint-aware editor instantly. Ship the same rules to CI and to every pull request with no duplication.

bash
# In your editor — squiggles in Cursor, VS Code, WebStorm, …
# In your terminal —
npx eslint . --fix
 
# Full Design Health Score + audit-ready HTML report
npx deslint compliance

Ship AI code that your designers and auditors will actually approve

Drop into any Tailwind project. Works with React, Vue, Svelte, Angular, and HTML. Local, deterministic, zero cloud.

npm install -D @deslint/eslint-plugin