Catch the bugs that never throw. Then stop them.
Add one line. An on-device model reports double submits, stale responses and failing endpoints. Stopping them is opt-in.
Or set it up with your coding agent: The prompt keeps GenClass telemetry on. What it sends
Check any page.
Invisible text, broken images, layouts that break on phones. Paste a URL to find them.
Invisible text
A label in the same colour as its button.
Broken images
An image URL that was made up, or a host that went away.
Layouts that break on phones
One fixed-width block and the whole page scrolls sideways.
Template leaks
undefined, NaN or [object Object] where the data should be.
Covered buttons
An invisible layer on top takes the click.
35 of 35 planted bugs found. 0 false alarms in 128 views of correct pages. How we measured →
New: GenClass Vision (beta), a 4.8 MB model that ranks bugs level with Cloudflare's 27B Clef. Results →
Before and after.
The real runtime, running on this page.
This is the package from npm, deciding on your device. Type fast in the search box or break the stock API, and watch what GenClass reports.
This demo turns on guard with every gain margin at 0, the eager profile and a 1 s hold budget, so you can see it act. The shipped defaults only report. Keep this tab in front: the model loads at idle and the stock poll pauses while the tab is hidden.
The double-click that emails your customer twice
A slow "Send invoice" button with no double-click protection, the kind every app has somewhere. Same code on both sides. The right side has GenClass.
- No emails yet
- No emails yet
Bugs that never throw, reported live
A search box whose answers race each other, and a stock widget whose API you can break. No errors are thrown. Watch what GenClass reports.
- Type in the search box or break the API. Detections appear here with the model's confidence and evidence.
Everything above is the real @genclass/runtime@0.2.2 from npm, deciding on your device (model loading). This run's settings: mode: "guard", aggressiveness: "eager", policy: { thresholds: { guard: 0, heal: 0 }, holdBudgetMs: 1000 }. Before the invoice button turns on, the page asks the model one question, so the runtime has timed a real decision: runtime 0.2.2 otherwise estimates the first one from its warm-up pass, which on WASM overstates it several times, and on a slower CPU then does not hold the first duplicate. The shipped defaults are mode: "observe", aggressiveness: "balanced": run the demo with them, or with guard at its shipped gates. In the compatibility matrix guard at those gates left 249 of 250 runs with a latent bug buggy, so with the defaults this demo shows reports and no fix. The endpoint is real; the page asks for the delays so the race is reproducible. Telemetry is off on this site. Open DevTools to see the same [GenClass] lines.
The worst bugs never throw an error.
Nothing crashes, so error monitors see nothing. GenClass watches the timing and the data, not just the exceptions.
Stale responses
Results for "pa" land under a search box that already says "paris". GenClass sees the old response about to overwrite newer data and can drop its write.
30% detected on held-out real apps
Works with your stack
It finds React, Redux and Zustand (devtools) state on its own. 350 of 351 compatibility cells pass.
- React
- Next.js
- Vue
- Svelte
- Angular
- Solid
- TanStack Query
- Plain HTML
Duplicate submits and more
A double-tap on a slow checkout sends the order twice. GenClass recognises the repeat and can merge it into the request already in flight.
75% detected on held-out real apps
- Failure stormsflag the streak
- Write raceskeep the newer value
- Broken state6% detected
- Slow and flaky callsretry safely
[GenClass] Prevented a stale write: GET /search?q=pa landed after q=paris was shown (stale; discard) [GenClass] Coalesced POST /api/orders with #212, so one order is placed [GenClass] Failing request: GET /api/inventory failed 5 times in 8 s (failing) [GenClass] Held the write to cart.total until the related in-flight operations finish, to decide again.
Every decision in plain English
One console line per detection or action, with the evidence in a collapsed group. Observe, the default, only reports. Guard can act, with undo and an audit trail.
Detection rates: model 0.2.0 at the default balanced profile. All results · How it works
Set up in a minute
- One package. Its only runtime dependency is
onnxruntime-web. Or runnpx @genclass/runtime initand let the CLI wire it in.
Quickstart - Make it the first import of your app. It wraps fetch, XHR, WebSocket and EventSource. Next.js uses
instrumentation-client.ts; plain HTML takes one script tag.
Every framework - Observe mode is the default: it reports in the console and changes nothing.
?genclass=offturns it off on that page.
API reference - Switch to guard when you trust what it sees. It can drop a stale write or merge a duplicate, with undo.
Options
$ npm i @genclass/runtime # or: detects your framework, shows the diff, asks, then writes $ npx @genclass/runtime init
$ npm i @genclass/runtime # or: detects your framework, shows the diff, asks, then writes $ npx @genclass/runtime init
// first line of the app: React, Vue, Svelte, Angular, Solid import "@genclass/runtime/auto"; // Next.js: instrumentation-client.ts at the project root import "@genclass/runtime/auto"; <!-- plain HTML: first in <head>, no build step; keep the version pinned --> <script src="https://cdn.jsdelivr.net/npm/@genclass/runtime@0.2.2"></script>
$ npm run dev [GenClass] Flagged a stale response: search.results was written twice by other operations since its operation (#6) started (version 1 → 3), last 0.69s ago by GET /api/search?q=reac (#8), which started 0.09s after #6, from a later user action (#7). (stale, 0.96)
import "@genclass/runtime/auto/guard"; [GenClass] Prevented a stale response: search.results was written twice by other operations since its operation (#6) started (version 1 → 3), last 0.69s ago by GET /api/search?q=reac (#8), which started 0.09s after #6, from a later user action (#7). Delivered the response to GET /api/search?q=rea (#6) and dropped the state changes it makes over newer data (search.results). (stale, 0.97; discard 0.98)
Anonymous diagnostics, with no page text, are on by default. Turn them off with GenClass.init({ telemetry: false }) or npx @genclass/runtime init --no-telemetry. See what is sent.
Precise when it acts, and it rarely acts.
Tested on held-out apps it never trained on, in real browsers. Every number links to its method.
model 0.2.0, balanced
Introduced in 3,510 runs
Compatibility runs across 7 frameworks and 15 data layers.
held-out simulated apps
False interventions in guard
At the default profile. On held-out real apps it was 0.
held-out real apps
Of the cases where acting helps
get an action from guard. It reports far more than it fixes.
held-out real apps
Duplicate submits caught
Detected in observe mode at the default setting.
Frequently asked questions
Is GenClass free?
Yes. The runtime and its on-device model are open source under Apache-2.0 and free, including in commercial apps, with no usage limits, and so is the genclass.dev dashboard: 90 days of history, data export and forwarding, for every app, with no card. Individual ($29 a month) adds a classifier GenClass trains on your data, and Enterprise runs GenClass's models in our cloud. See pricing.
Does GenClass need an account or an API key?
No account or API key is needed to run it: one script tag or import "@genclass/runtime/auto" is all it takes, and the model runs on the device. A free dashboard at genclass.dev shows your app's detections, in a free account or through a private link. The dashboard fills from deployed pages with diagnostics on, so telemetry: false leaves it empty, and runtime 0.2.2 and earlier do not send to it.
Will GenClass break my app?
The default mode only observes and changes nothing. Across 7 frameworks and 15 data layers, GenClass introduced no bugs in 3,510 test runs (runtime 0.1.0-beta.4, the code shipped as 0.2.1; model 0.2.0). Adding ?genclass=off to a URL turns it off on that page.
Where do GenClass reports go in production?
By default to the end user's browser console, which you do not see. The sinks option forwards each report to your own logging or to an endpoint you own. On every plan, Free too, the genclass.dev collector can also forward detections to Sentry, PostHog, Datadog, Slack or a signed webhook, with no code in your app. Anonymous diagnostics go to the GenClass maintainers to improve the model, and to your dashboard if you have one; telemetry: false turns them off.
Start in observe mode.
It reports what it sees and changes nothing until you turn on guard. The dashboard is free: 90 days of history, export and forwarding, with no card.
Or set it up with your coding agent: The prompt keeps GenClass telemetry on. What it sends