caniuse

Use when checking if a CSS, HTML, or JavaScript feature works in specific browsers. Provides live data from the caniuse dataset — more accurate than training-data recall.

caniuse — Browser Compatibility Data

Overview

Covers the full workflow for checking browser support: querying the caniuse dataset programmatically (GitHub raw files or npm packages), navigating feature pages on caniuse.com, and interpreting support values. The programmatic path is strongly preferred — it returns structured data instantly with no browser required and no rate limits.

Not covered here: Editing caniuse data, submitting feature requests, account management (caniuse has none). All data is read-only and public.

Auth required for: Nothing — all data is public.


Agent Paths

Programmatic [API] — No browser needed

  • Per-feature data: GET https://raw.githubusercontent.com/Fyrd/caniuse/main/features-json/{slug}.json
  • Full dataset (553 features, 4.5 MB): GET https://raw.githubusercontent.com/Fyrd/caniuse/main/data.json

Required headers: None — GitHub raw is fully public, no auth needed

npm alternative (if in Node.js context):

npm install caniuse-lite    # packed format, used by webpack/postcss — smallest
npm install caniuse-db      # raw JSON identical to data.json — same as GitHub file

Browser [Browser] — Requires browser control

  • Use selectors and Navigation Flows below
  • Required when: showing the visual compat table to the user, navigating the feature index, comparing browsers side-by-side
  • Cannot read compat table values with standard selectors — the table is rendered inside a <ciu-feature-list> custom web component with shadow DOM. Standard CSS selectors (table, td, etc.) return zero matches. See Anti-Patterns.

When to use which

  • Default to Programmatic — one HTTP fetch returns all support data for a feature in structured JSON
  • Use Browser when: the user wants to see the visual table, or needs to share a caniuse.com URL
  • Never navigate the browser just to check supportfeatures-json/{slug}.json is always faster and doesn't involve shadow DOM

Agent Knowledge Note

Most frontier LLMs have caniuse browser support data in training data — support for CSS Grid, Flexbox, Fetch, etc. is widely covered. This skill adds value via:

  • No JSON REST API on caniuse.com itselfcaniuse.com/data.json redirects to an error page. The correct programmatic path is GitHub raw: raw.githubusercontent.com/Fyrd/caniuse/main/features-json/{slug}.json. Agents that try to fetch from caniuse.com directly will fail.
  • Shadow DOM blocks compat table scrapinghttps://caniuse.com/{slug} renders the entire compat table inside <ciu-feature-list>, a custom web component. document.querySelectorAll('table') returns zero results. There is no compat table in the normal DOM.
  • Support values are compound strings, not simple booleans'a x #2' means partial support, prefix required, see note 2. Checking value === 'y' will miss partial-but-usable support. Check value.startsWith('y') or value.includes('y') to find any level of affirmative support.
  • Training data goes stale; live data doesn't — browser version numbers change every few weeks. Always fetch live from GitHub for current support — don't rely on training knowledge for specific version numbers.
  • https://caniuse.com/fetch redirects — the slug fetch is valid in data.json (Fetch API, 96.32% support) but the URL redirects to an error page. Use the GitHub data or navigate via search input instead.
  • 553 features in dataset — more than most agents expect. Includes obscure features like aac, wasm-bigint, css-if, cross-document-view-transitions. The full slug list is the data object's keys in data.json.

Site Map

PageURL PatternNotes
Homepagehttps://caniuse.com/Search input, trending/new features, browser scores
Feature pagehttps://caniuse.com/{slug}Visual compat table — shadow DOM, not scrapable
Feature indexhttps://caniuse.com/ciu/indexFull alphabetical list of all 553 features
Browser comparisonhttps://caniuse.com/ciu/comparisonSide-by-side feature support by browser
Usage tablehttps://caniuse.com/usage-tableGlobal browser version usage percentages
Newshttps://caniuse.com/ciu/newsRecent feature additions
Settingshttps://caniuse.com/ciu/settingsTheme, default browser set
GitHub data (per-feature)https://raw.githubusercontent.com/Fyrd/caniuse/main/features-json/{slug}.jsonRecommended programmatic path
GitHub data (full)https://raw.githubusercontent.com/Fyrd/caniuse/main/data.jsonAll features, 4.5 MB

Page Structures

Homepage (https://caniuse.com/)

ElementSelectorNotes
Search inputinput[name="search"]Also: #feat_search, input[type="text"]
Search formform.ciu-search__formWraps input + submit
Settings buttonbutton.options-toggleOpens filter/settings panel
Filter features buttonbutton.filter-buttonFilters feature list
Score toggle: current versionbutton.home__score-button.is-selectedToggle between current/dev browser versions
Score toggle buttonsbutton.home__score-button2 matches — "Current version" and "Dev version"
Latest features listol.home__list.js-latest-features5 most recently added features
Top features (by usage)ol.home__list.home__list--numberedTop 5 by global usage
Browser scoresol.home__list.js-browser-scoresBrowser usage breakdown
News linka.newsLatest site news announcement
Main contentmain.ciu-page-contentWraps all page content
Nav tabs#tab-container5 tab links (Home, Index, News, etc.)
Legendsection.ciu-legendSupport color key
Search sectionsection.ciu-searchContains search form

Feature Page (https://caniuse.com/{slug})

ElementSelectorNotes
Search inputinput[name="search"]Persistent header search
Settings buttonbutton.options-toggleSame as homepage
Main containermain.ciu-page-contentContains <ciu-feature-list> custom element
Compat table componentciu-feature-listShadow DOM — standard selectors cannot reach children
Nav linksa[href="/ciu/news"], a[href="/ciu/comparison"]Persistent header links

Note: The entire compat table — browser names, version cells, support colors — is inside <ciu-feature-list>'s shadow DOM. document.querySelectorAll('table') returns 0 results. Use the programmatic path for data extraction.


Navigation Flows

Flow: Check Browser Support for a Feature [API] (Recommended)

Starting point: None — direct HTTP fetch Prerequisites: Know the feature slug (see Agent Knowledge Note for lookup)

StepActionTargetNotes
1fetchhttps://raw.githubusercontent.com/Fyrd/caniuse/main/features-json/{slug}.jsonReturns full feature data
2readstats.{browser_id}.{version}Support value for a specific version
3readusage_perc_yGlobal % with full support

Success state: JSON with title, stats, usage_perc_y, status, notes.

Branching:

  • If slug is unknown → fetch data.json, iterate Object.keys(data.data) and match against data.data[slug].title or data.data[slug].keywords
  • If HTTP 404 → slug does not exist; try searching on caniuse.com or check data.json keys

Flow: Search for a Feature [Browser]

Starting point: https://caniuse.com/ Prerequisites: None

StepActionTargetValueWait ForTimeout
1navigatehttps://caniuse.com/input[name="search"] visible5s
2typeinput[name="search"]Feature name or keyword
3pressinput[name="search"]EnterURL contains ?search= or /{slug}3s

Success state: URL changes to https://caniuse.com/?search={term} (multiple results) or directly to https://caniuse.com/{slug} if exact match.

Branching:

  • If redirected directly to a feature page → single match, load complete
  • If ?search= in URL → multiple results shown in the DOM — read a[href^="/"] links in main.ciu-page-content

Flow: View Feature Compat Table [Browser]

Starting point: Any page Prerequisites: Know the slug

StepActionTargetValueWait ForTimeout
1navigatehttps://caniuse.com/{slug}ciu-feature-list present5s

Success state: Page title includes feature name. ciu-feature-list element exists in DOM (confirms page loaded). Visual table visible on screen.

Reading compat data programmatically from the browser (shadow DOM piercing):

// Use page.evaluate() to pierce shadow DOM
const data = await page.evaluate(() => {
  const el = document.querySelector('ciu-feature-list');
  // Shadow DOM access — may be restricted depending on shadow mode
  return el ? el.shadowRoot?.innerHTML?.slice(0, 500) : null;
});

Note: if shadowRoot is null, the component uses closed shadow DOM and cannot be pierced. Use the programmatic API path instead.


API Response Shapes

GET https://raw.githubusercontent.com/Fyrd/caniuse/main/features-json/{slug}.json

{
  "title": "CSS Grid Layout (level 1)",
  "description": "Method of using a grid concept to lay out content, providing a mechanism for authors to divide available space for layout into columns and rows using a set of predictable sizing behaviors.",
  "spec": "https://drafts.csswg.org/css-grid-2/",
  "status": "cr",
  "links": [
    { "url": "https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout", "title": "MDN article" }
  ],
  "categories": ["CSS"],
  "stats": {
    "ie": {
      "10": "a x #2",
      "11": "a x #2"
    },
    "edge": {
      "16": "y",
      "144": "y"
    },
    "firefox": {
      "52": "y",
      "150": "y"
    },
    "chrome": {
      "57": "y",
      "148": "y"
    },
    "safari": {
      "10.1": "y",
      "TP": "y"
    },
    "ios_saf": {
      "10.3": "y",
      "18.3": "y"
    },
    "samsung": {
      "6.2": "y",
      "27": "y"
    }
  },
  "notes": "Partial support in IE refers to an older version of the specification.",
  "notes_by_num": {
    "2": "Partial support in IE refers to an older version of the specification."
  },
  "usage_perc_y": 96.17,
  "usage_perc_a": 0.04,
  "ucprefix": false,
  "parent": "",
  "keywords": "css grid,grid layout,grid template,grid area",
  "shown": true
}

Key fields:

FieldDescription
titleHuman-readable feature name
statusW3C status: rec (Recommendation), cr (Candidate Rec), wd (Working Draft), ls (Living Standard), pr (Proposed Rec), other, unoff (Unofficial)
statsObject: browser ID → version string → support value
usage_perc_y% of global users with full (y) support
usage_perc_a% of global users with partial (a) support
notes_by_numObject: note number → explanation text
specURL to the formal specification

Support values in stats:

ValueMeaning
'y'Fully supported
'n'Not supported
'a'Partial support
'p'Polyfill required
'u'Unknown
'x'Requires vendor prefix
'y x'Supported with prefix
'a x #2'Partial, prefix required, see note 2

Check for any support: value.startsWith('y') or value.includes('y') — catches 'y', 'y x', 'a #1 y' compounds. Check for full support only: value === 'y' or value.trim() === 'y'.

Browser IDs in stats:

IDBrowser
chromeChrome (desktop)
firefoxFirefox (desktop)
safariSafari (desktop)
edgeEdge
ieInternet Explorer
operaOpera
ios_safSafari on iOS
and_chrChrome on Android
and_ffFirefox on Android
samsungSamsung Internet
op_mobOpera Mobile
and_ucUC Browser
baiduBaidu Browser

Common Agent Tasks

"Does {feature} work in all modern browsers?"

  1. Fetch: GET https://raw.githubusercontent.com/Fyrd/caniuse/main/features-json/{slug}.json
  2. Check usage_perc_y — if > 95%, it's broadly supported
  3. Check latest 2 versions of key browsers: chrome, firefox, safari, edge, ios_saf, samsung
    • To get latest versions: fetch data.json, read agents.{browser_id}.versions array — last non-empty entries are current
  4. For each browser, check if any stats.{browser_id}.{version} value contains 'y'
  5. Note any 'a' (partial) entries and read the corresponding notes_by_num text

Output: Summary table: browser → version → support level + any notes


"Can I use {feature} safely in production today?"

  1. Fetch: GET features-json/{slug}.json
  2. Check usage_perc_y + usage_perc_a — total addressable users
  3. Check stats.ie — IE still matters for some enterprise contexts (all IE versions are historical now)
  4. Check stats.safari and stats.ios_saf — Safari is often the last to ship
  5. Read notes and notes_by_num — partial support (a) may be workable depending on which sub-features are needed
  6. Check statusrec or ls means the spec is finalized and won't change; wd means still in flux

Output: Recommendation with global coverage %, browser exceptions, and relevant notes


"What's the difference in support between {feature1} and {feature2}?"

  1. Fetch both in parallel: features-json/{slug1}.json and features-json/{slug2}.json
  2. Compare usage_perc_y for global reach
  3. For each major browser (chrome, firefox, safari, edge, ios_saf): compare the first version where support = 'y'
  4. Compare status — both finalized? One still a Working Draft?

Output: Side-by-side table: browser → first supported version for each feature


Dynamic Content Patterns

  • Custom web component: <ciu-feature-list> renders the entire compat table via shadow DOM. The page itself is server-rendered HTML, but all compat data is populated by JavaScript into the web component. document.querySelector('table') returns nothing.
  • Data loaded from js-data/data.js: caniuse.com loads its compat data as a JavaScript file (window.dataLoaded callback), not a JSON API. The GitHub raw files contain the same data in JSON format.
  • Server-rendered shell: The <html>, <head>, <header>, <footer>, and <input> elements are fully server-rendered. Only the compat table content is JS-populated.
  • networkidle wait required: The feature page shows a loading state until data.js executes and populates <ciu-feature-list>. Use --wait=networkidle with discover.js or Playwright.

Timing & Waiting

TransitionWait ForTypical Delay
Feature page navigationnetworkidle1–3s (data.js load)
Search submitURL changes to ?search= or /{slug}0.5–1s
GitHub raw fetchResponse body0.2–0.8s
Full data.json fetchResponse body1–3s (4.5 MB)

Rate Limits

ScopeLimitNotes
GitHub raw CDNNo documented limitCached at CDN; very permissive for normal usage
caniuse.com browserNo documented limitStandard web traffic; no bot protection observed

Parallel requests: Safe to fire multiple features-json/ requests in parallel — the GitHub CDN handles concurrent fetches well. Commonly needed when comparing N features.


Common Gotchas

  1. caniuse.com/data.json redirects to an error page. The dataset is not served from caniuse.com itself. Use raw.githubusercontent.com/Fyrd/caniuse/main/data.json instead.

  2. Shadow DOM blocks compat table reading. The feature page renders everything inside <ciu-feature-list>. querySelectorAll('table') returns 0 results. Standard CSS selectors cannot reach browser names, version numbers, or support values. Use the GitHub data API.

  3. https://caniuse.com/fetch redirects despite fetch being a valid slug. The Fetch API slug (fetch) is valid in data.json (96.32% support) but caniuse.com/fetch returns a 302 to /?search=406.shtml. Use the GitHub API or navigate via the search input. Other single-word slugs may have the same issue.

  4. Support values are compound strings, not simple booleans. 'a x #2' = partial support, vendor prefix required, see note 2. Never check value === 'y' alone — use value.startsWith('y') or value.includes('y') for "any positive support" and value.trim() === 'y' for "full unprefixed support."

  5. Version keys in stats are strings, not numbers. '10.1' and '10' are different keys. String sorting will order '10' before '9'. To get the most recent versions, use the ordered agents.{browser_id}.versions array from data.json — it's ordered oldest to newest.

  6. features-json/ is much smaller than data.json. For a single feature lookup, fetch the per-feature file (typically 5–30 KB) rather than the full 4.5 MB dataset. Only use data.json when you need to query across all 553 features (e.g., "list everything with >95% support").

  7. usage_perc_y does not include partial support. A feature may have usage_perc_y: 0.5 but usage_perc_a: 94. Check both when assessing real-world reach.


Anti-Patterns

  • NEVER fetch https://caniuse.com/data.json — it redirects to /?search=406.shtml (error page). Use https://raw.githubusercontent.com/Fyrd/caniuse/main/data.json.
  • NEVER use document.querySelectorAll('table') on a feature page — returns 0 results. The compat table is inside <ciu-feature-list> shadow DOM.
  • NEVER check support with value === 'y' alone — misses 'y x' (prefix), 'a #1 y' compounds, and valid partial support. Use value.startsWith('y') for "any yes" or value.trim() === 'y' for "clean yes".
  • NEVER sort version strings alphabetically to find the latest'9' sorts after '148' lexicographically. Use agents.{browser_id}.versions array order from data.json.
  • NEVER navigate https://caniuse.com/fetch in a browser — that URL redirects. Use search input or GitHub data for the Fetch API.
  • Training data for specific version support is stale — browser versions advance every few weeks. Always fetch live features-json/{slug}.json for current version numbers; don't rely on memory of which Chrome/Firefox version first supported something.

Freshness

Skill verified2026-02-20
Data updatedUnix timestamp in data.json under updated key — checked per-fetch; data changes when browsers ship
GitHub raw stable since2013 — raw.githubusercontent.com/Fyrd/caniuse/main/data.json path has been stable; primary distribution channel
Selector stabilityHIGH — caniuse.com uses intentional BEM-style class names (ciu-page-header, ciu-search__form, home__list); no hashed classes; site design is conservative and rarely changes
Breaking change riskLow for selectors; None for GitHub data (it's a versioned file, not an API)