Ask a coding agent to "add urgency" to a product page and it produces a countdown that resets on refresh. Ask it whether a pre-ticked "shipping protection" box is allowed and it cannot cite the article. Most dark-pattern guides are about taste; this skill is about the subset that is against the law in the EU, the UK and the US — with the text each one breaks, a script that finds them in source with a file and a line, and the honest mechanic that replaces each one without losing the sale.
npx skills add kinerette/claude-code-ecommerce-dark-patternsWorks with Claude Code, Codex, Cursor and any agent that reads the Agent Skills format. In Claude Code you can also install it as a plugin:
/plugin marketplace add kinerette/claude-code-ecommerce-dark-patterns
/plugin install ecommerce-dark-patterns@uxgen-compliance
MIT. Zero dependencies. Nothing phones home.
node skills/ecommerce-dark-patterns/scripts/audit-dark-patterns.mjs ./srcReads React, Vue, Svelte, Liquid, HTML, Astro, PHP. Writes nothing. Every finding carries the file, the line, the law and the fix:
■ An add-on that costs money may start ticked [illegal] ×1
law: EU 2011/83/EU art. 22 (refundable) · UK CCR 2013 reg. 40 · US FTC Act §5 ("sneaking")
fix: Start unchecked. Remove the prop that can start it checked. See references/patterns.md #1
components/ShippingProtection.tsx:41 <input type="checkbox" defaultChecked name="protect" />
■ A countdown seeded from the page load (resets on refresh) [illegal] ×1
law: EU 2005/29/EC Annex I §7 · UK DMCC 2024 sched. 20 · US FTC Act §5
fix: Use a server-side end date shared by every visitor, printed as a date; or no timer. See #3
components/OfferTimer.tsx:12 const expires = Date.now() + 15 * 60 * 1000
--json for machine output. --strict exits 1 on anything at severity
illegal, so it can sit in CI next to the linter.
| # | Dark pattern | Where it is illegal | The honest twin |
|---|---|---|---|
| 1 | Pre-ticked add-on / "protect my order" | EU CRD art. 22 (refundable) · UK CCR reg. 40 · US FTC | unchecked box, one sentence of reason |
| 2 | Struck-through price never charged | EU 98/6/EC art. 6a (30-day lowest) · UK DMCC · US 16 CFR 233 | compare-at = real prior price, or none |
| 3 | Countdown seeded from page load | EU UCPD Annex I §7 · UK DMCC sched. 20 · US FTC | a printed end date, or no timer |
| 4 | "Only 3 left" not read from stock | EU UCPD Annex I §7 · UK · US | a figure read from inventory, or nothing |
| 5 | "12 people are viewing" | EU UCPD art. 6 · UK · US | nothing — an invented number has no honest version |
| 6 | Fabricated reviews / ratings | EU UCPD Annex I §23b–c · UK DMCC sched. 20 · US 16 CFR 465 | the real block, or the slot left empty |
| 7 | Drip pricing — fee at the last step | UK DMCC (6 Apr 2025) · US California SB 478 · EU CRD art. 6(1)(e) | the all-in price on the first screen |
| 8 | "Free" that moves the total | EU UCPD Annex I §20 — unfair in all circumstances | a gift that costs zero, "included" |
| 9 | Confirmshaming decline | US FTC report · EU UCPD art. 8–9 · UK | "No thanks", same size, same row |
| 10 | Cancel harder than subscribe | US ROSCA · California ARL (1 Jul 2025) · EU CRD · DE §312k BGB | same medium, same number of steps |
| 11 | Pay button that does not say it charges | EU CRD art. 8(2) — not binding on the consumer | "Pay 48,00 €" |
| 12 | Basket sneaking | EU CRD art. 22 · UK · US | every line came from a click |
Each one written out — what it looks like in code, the text, the replacement —
in references/patterns.md.
Primary sources with the dates they took effect in
references/law.md.
The honest versions as component specs in
references/replacements.md.
Every honest mechanic sells at least as well as its dark twin, because the dark twin is measured on the first visit and refunded on the second.
The audit does not remove urgency, scarcity or proof from a page. It replaces the false version with the true one: a real end date instead of a ticking clock, a stock figure read from inventory instead of "only 3 left", an unchecked bump with a reason instead of a pre-ticked box. The true version survives a second visit, a chargeback dispute and a regulator's letter. The false one survives none of them.
- 28 May 2022 — EU Omnibus: 30-day prior price; fake reviews in Annex I.
- 21 October 2024 — US fake-review rule, civil penalties per violation.
- 6 April 2025 — UK DMCC: fake reviews and drip pricing banned; the CMA fines directly, up to 10% of global turnover.
- 1 July 2025 — California ARL: cancel by the same medium as signup.
- 8 July 2025 — US click-to-cancel rule vacated; ROSCA unchanged.
skills/ecommerce-dark-patterns/
├── SKILL.md the trade, condensed
├── references/
│ ├── patterns.md the twelve, with code, law and replacement
│ ├── law.md primary texts by jurisdiction, linked, dated
│ └── replacements.md the honest versions as component specs
└── scripts/
└── audit-dark-patterns.mjs zero-dependency audit, file + line + law + fix
Not legal advice. A builder's summary of public texts, each linked so the claim can be checked, written so that an agent refuses the pattern instead of building it and adding a comment. When a shop is close to a line, the shop's own counsel decides.
- claude-code-store-design — which selling mechanics belong on this product page, and in what order.
- claude-code-checkout-upsell — which upsell goes in the cart, the checkout and after payment.
Those two build the honest versions. This one checks that what shipped is the honest version.
Built by uxgen, a remote MCP server that hands coding agents the selling mechanics of a storefront with the rules attached. MIT.