webspec-index
Query WHATWG, W3C, IETF and TC39 web specifications from the command line.
Use webspec-index whenever you need to understand what a web spec says — algorithm steps, section content, cross-references, or whether a spec anchor exists. Specs are fetched and cached locally on first use.
Available specs
Assume that all specs from WHATWG, W3C, IETF and TC39 are indexed. webspec-index specs lists every spec name and its base URL.
Installation
If webspec-index is not already available in your environment, you can install it via cargo:
cargo binstall webspec-index
# or
cargo install webspec-index
Commands
Always put the section identifier in quotes to avoid shell interpretation of #.
See webspec-index --help for full command list and options.
Look up a spec section
webspec-index query 'HTML#navigate'
webspec-index query 'DOM#concept-tree'
webspec-index query 'CSS-GRID#grid-container'
webspec-index query 'https://html.spec.whatwg.org/#navigate'
webspec-index query 'DOM#concept-tree'
webspec-index query "RFC9000#section-22"
webspec-index query "draft-ietf-tsvwg-sctp-dtls-chunk#name-security-considerations"
webspec-index query 'https://w3c.github.io/webappsec-permissions-policy/#permissions-policy-header'
Returns the section’s title, type (heading/algorithm/definition), full content as markdown, navigation tree (parent/prev/next/children), and cross-references. This is the primary command — use it to read what a spec section says.
Use --format markdown for human-readable output, or default --format json for structured data.
For non-hardcoded specs, URL queries are accepted for allowlisted domains (*.spec.whatwg.org, drafts.csswg.org, w3c.github.io, wicg.github.io, webaudio.github.io, tc39.es, w3.org/TR/*, and webassembly.github.io).
Search across specs
webspec-index search "tree order"
webspec-index search "navigate" --spec HTML --limit 5
Full-text search with snippets. Use --spec to narrow to one spec.
Check if a section exists
webspec-index exists 'HTML#navigate'
Exit code 0 = found, 1 = not found. Use this to validate anchor names before referencing them.
Find anchors by pattern
webspec-index anchors "*-tree" --spec DOM
webspec-index anchors "concept-*" --spec HTML
webspec-index anchors "dom-*assign*"
Glob matching (* wildcard). Useful when you know part of an anchor name but not the exact id.
List all sections in a spec
webspec-index list DOM
Returns all heading-level sections with their anchors, titles, types, and depths.
Cross-references
webspec-index refs 'HTML#navigate' --direction incoming
webspec-index refs 'HTML#navigate' --direction outgoing
webspec-index refs 'HTML#navigate'
webspec-index refs 'Window.navigation' --limit 5
webspec-index refs 'HTML#event-navigateerror' --direction incoming --kind step -l 50
Shows which sections reference this one (incoming), which sections this one references (outgoing), or both (default). Target can be exact (SPEC#anchor or full URL) or shorthand (Interface.member) resolved heuristically against currently indexed sections. Use --limit to cap results when using shorthand queries.
Each reference carries the call site it was found at: the step number of the referencing algorithm, that step’s verbatim text, and any enclosing guard steps. --kind filters by where the reference occurs:
step— inside a numbered algorithm step, i.e. an actual callnote— inside a note or example, including one nested in a stepidl— inside a WebIDL blockprose— ordinary prose
Roughly 60% of references are not calls, so --kind step is the difference between “who invokes this” and “who mentions this”. refs 'HTML#event-navigateerror' --direction incoming returns 11 sections; with --kind step it returns the one algorithm that actually fires the event.
Trace the call chain between two sections
webspec-index trace 'HTML#dom-location-assign' 'HTML#event-navigateerror' --max-depth 9 --format markdown
webspec-index trace 'HTML#navigate' 'DOM#concept-tree' --kind any -l 5
webspec-index trace 'HTML#dom-location-assign' 'HTML#event-navigateerror' --detail compact
Enumerates routes through the reference graph from one section to another. Both endpoints must be exact (SPEC#anchor or full URL). Defaults to --kind step, so only call edges are traversed.
Each hop reports the calling section, its step number, the verbatim step text, enclosing guard steps, and a link to the call site itself rather than the callee’s definition. Markdown output is therefore a ready-made trace.
--detail picks how much of each hop to show. verbose (default) carries step text, guards and the call-site link. edges reduces each hop to SPEC#anchor plus its step number — roughly a third the size, and every token is an identifier you can feed back into query or refs. compact gives one linked line per hop, collapsing an edge’s repeated call sites onto it, so an algorithm calling another twelve times reads as one line with twelve links rather than twelve near-identical routes.
Reduced levels are for comparing route shapes, not for judging them: the guards they drop are what decide whether a route is taken.
Use this instead of walking refs by hand. It is exhaustive within --max-depth, and the result distinguishes a search that finished from one cut short by the trace or node budget — so zero traces with truncated: false is evidence that no route exists, not merely that none was found.
Read Search was truncated before trusting the result — raise -l or narrow the endpoints if it appears.
Specs a route passes through are indexed on demand: when an edge points into a spec with no indexed data, trace fetches it and searches again, reporting indexing N spec(s) the route touches on stderr. First run of a cross-spec trace therefore takes a few seconds; later runs do not.
Real chains are longer than they look; location.assign() to navigateerror is seven hops, so a low --max-depth reports zero traces that look like a genuine answer.
WHATWG PR previews
webspec-index query 'HTML#navigate' --pr 12345
webspec-index query 'HTML#navigate' --pr 12345 --diff --format markdown
webspec-index query 'HTML#navigate' --pr 12345 --force-update
webspec-index exists 'HTML#navigate' --pr 12345
webspec-index list HTML --pr 12345
webspec-index refs 'HTML#navigate' --pr 12345
webspec-index search 'OpaqueRange' --spec HTML --pr 12345
webspec-index anchors '*opaquerange*' --spec HTML --pr 12345
Query spec sections as modified by an open WHATWG PR. Previews are lazily fetched from whatpr.org on first use and cached for 24h.
--pr N: query the spec as it would look after PR N is merged. Sections not modified by the PR fall back to the merge base.--diff: show a section-level diff between the PR and its merge base. Lists added/modified sections with unified diffs.--force-update: re-fetch the PR preview even if recently cached (use after the PR is updated).
Manage cached PR data with clear-pr:
webspec-index clear-pr # list cached PRs
webspec-index clear-pr --spec HTML --pr 12345 # remove one PR
webspec-index clear-pr --all # remove all
Update specs
webspec-index update
webspec-index update --spec HTML
webspec-index update --force
Fetches latest spec versions. Uses 24h cache unless --force is given. Specs are auto-fetched on first query, so you rarely need this.
Each check covers the spec and its transitive dependencies; re-indexing happens only when HTML content changed. The first query of the day may take a few seconds while the check completes.
Graph traversal
webspec-index graph 'HTML#navigate' --direction outgoing --max-depth 2
webspec-index graph 'HTML#navigate' --graph-format mermaid
webspec-index graph 'HTML#navigate' --graph-format dot
webspec-index graph 'HTML#navigate' --same-spec-only
webspec-index graph 'HTML#navigate' --include '*concept-*' --exclude 're:^URL#'
Builds a cross-reference graph rooted at a section. Supports JSON (default), Markdown, Mermaid, and Graphviz DOT output.
Use --include and --exclude to filter node ids (SPEC#anchor) by wildcard patterns (*, ?) or regex (re:<pattern>).
Query dedicated WebIDL definitions
webspec-index idl 'HTML#dom-window-navigation'
webspec-index idl 'Window.navigation'
webspec-index idl 'Window.open()'
webspec-index idl 'navigation' --spec HTML --limit 5
Queries structured WebIDL definitions directly. Supports exact anchors (SPEC#anchor or URL) and canonical names (Interface.member, Interface.method()).
Use this first when the task is about API shape or IDL ownership, then use refs to see algorithm usage.
Query field state (who writes a field)
webspec-index state 'HTML#is-initial-about:blank' --format markdown
webspec-index state 'Document' --format markdown
webspec-index state 'Document.*sandbox*' --format markdown
webspec-index state 'HTML#*sandbox*' --format markdown
webspec-index state 'HTML#sandboxing-flag-set' --format markdown
webspec-index state --coverage HTML --format markdown
webspec-index state 'SPEC#anchor' | --coverage SPEC [--no-inits] [--unclassified] [--calls] [--callers] [--opaque] [-l N] [--rules PATH] [--format json|markdown]
Answers: who writes a spec field, under what grammar shape, and with what initial value. Answers use may-semantics — a listed site may set the field. Reads are counted, not listed.
Selector forms:
SPEC#anchorof a field → field view (writes, inits, owner, type)SPEC#anchorof a type → type view (all fields, tables per supertype)SPEC#GLOB(e.g."HTML#*sandbox*") → field list matching anchor globSPEC#anchorof a set → member view (adds/removes per member)TYPE(e.g.Document) → type view"TYPE.FIELD"(e.g."Element.node document") → field view with inheritance path"TYPE.GLOB"(e.g."Document.*sandbox*") → field list matching name or anchor--coverage SPEC→ coverage counters (owner resolution %, set structure %, unclassified %)SPEC#anchorof an algorithm → algorithm view (below)
Algorithms: signature, calls and callers
webspec-index state 'HTML#navigate' --format markdown
webspec-index state 'HTML#location-object-navigate' --calls --format markdown
webspec-index state 'DOM#concept-node-insert' --callers -l 20 --format markdown
webspec-index state 'HTML#navigate' --opaque --format markdown
The algorithm view shows the call template (navigate {navigable} to {url} using {sourceDocument}, with named arguments), a parameter table (type, positional or named, default), and statement counts.
--calls: every call the algorithm makes, with each argument bound to the callee’s parameter (url ← *url* · exceptionsEnabled ← true · 9 named arguments defaulted).--callers: every call into the algorithm from all indexed specs, grouped by caller and bound the same way.-l Ncaps the caller groups (default 20); the total is always reported.--opaque: statements the parser could not structure.
Each call carries a confidence: exact (every argument aligned), partial (some argument is opaque
or missing; the issue list says which), or unbound (no signature, e.g. a callee spec that is not
indexed). Arguments are never guessed: an exact binding is reliable, and a partial one shows its
uncertain values verbatim. For “who invokes X and with what arguments”, prefer --callers over
refs --direction incoming --kind step.
The view under-reports rather than misreports. Calls inside If conditions, and calls embedded in
running prose rather than leading a step, are often missing. So Coverage: may · partial means more
calls may exist: confirm with refs --kind step or by reading the steps before concluding a call is
absent.
Views of long algorithms
query on a long algorithm (HTML#navigate has 67 steps) returns thousands of words. View flags
trim it to what you need:
webspec-index query 'HTML#navigate' --depth 1
webspec-index query 'HTML#navigate' --steps 24.8 --format markdown
webspec-index query 'HTML#navigate' --involving url --format markdown
webspec-index query 'HTML#navigate' --feeding 24.9.1:historyEntry --format markdown
--depth 1: top-level steps only. Drill into a step with--steps 24.8to see all sub-steps under that path.--involving <name>: forward slice from that parameter or variable — every step that uses or is influenced byname, including the steps that carry it forward.--feeding <STEP>:<VAR>: backward slice answering “where doeshistoryEntryin step 24.9.1 come from”.<VAR>is optional; without it, every variable that feeds the step is traced.Combine flags:
--involving url --depth 2limits the forward slice to top-level steps plus one level of sub-steps (paths with at most 2 components).--no-notesdrops notes and examples. Links render as shortSPEC#anchorby default (--links fullfor URLs,--links nonefor plain text).
Markers signal omissions, not algorithm boundaries. A line like
- [steps 3–7 omitted: no use of *url*] means those steps exist and were cut for relevance. The
algorithm continues past a marker; it does not end there. The summary block appears right after the
## Content — … heading (before the steps) and lists slice variables, stores, unfollowed statements,
loop bindings, rebound names, and (for backward slices) inputs and later definitions.
Possible effects of an algorithm
webspec-index effects 'HTML#dom-location-assign' --compact --format markdown
webspec-index effects 'HTML#navigate' --summary-only --format markdown
webspec-index effects 'HTML#navigate' --kind event.fire --format markdown
webspec-index effects 'HTML#navigate' --step 8 --format markdown
Lists what an algorithm may cause, transitively across specs: events fired, tasks and microtasks
queued (with task source), steps run in parallel, promises resolved. Each group names the sites that
do it. Plain effects adds witness traces (the call path to each site, with its conditions);
--compact and --summary-only omit them. --kind or --category events focuses the request.
Semantics are may: a listed effect is reachable along some path, not guaranteed. “Partial
analysis” means more effects may exist. query output also embeds a short effects preview.
Control flow of an algorithm
webspec-index flow 'HTML#location-object-navigate' --flow-format mermaid
Renders the algorithm’s steps as a flowchart (branches, returns, calls to other algorithms).
Usage patterns for Gecko development
Understanding what you’re implementing
When working on a bug that references a spec algorithm:
# Read the algorithm you need to implement
webspec-index query 'HTML#navigate' --format markdown
# Check what concepts it references
webspec-index refs 'HTML#navigate' --direction outgoing
# Look up a referenced concept you don't understand
webspec-index query 'INFRA#ordered-set'
# See every algorithm it calls, with the arguments bound to each callee's parameters
webspec-index state 'HTML#navigate' --calls --format markdown
When query output ends with a line like Written in 4 steps… or Called from 13 algorithms…, run the
command printed on that line.
A value ends up wrong
When a bug or test failure comes down to a spec field holding the wrong value (a flag that stays set, a stale URL, a missing entry in a list), list every step that writes or initializes it, then read each writer:
webspec-index state 'HTML#ongoing-navigation' --format markdown
webspec-index query 'HTML#navigate' --steps 24.8 --format markdown
A field set only at initialization never changes after construction; a writer under a guard changes it only when the guard holds.
Wrong arguments, or a missing call
When Gecko’s caller passes different arguments than the spec, or a call seems missing, compare against
the spec’s call sites. --calls shows what an algorithm calls and with which arguments; --callers
shows every call into it, from every indexed spec:
webspec-index state 'HTML#location-object-navigate' --calls --format markdown
webspec-index state 'DOM#concept-node-insert' --callers --format markdown
An exact binding is reliable; N named arguments defaulted means the spec relies on the defaults.
The view can miss calls inside If conditions and in running prose, so confirm an absence with
refs --direction incoming --kind step before concluding a call does not exist.
Event order and task timing
When a test fails on which events fire, in what order, or whether something happens synchronously, list what the entry point may cause and through which task source:
webspec-index effects 'HTML#dom-location-assign' --compact --format markdown
webspec-index effects 'HTML#dom-location-assign' --kind event.fire --format markdown
Then follow one effect to its site with trace and read the steps on the way. Effects are possible,
not guaranteed: a guard on the route decides whether it happens.
Finding the right spec section
When you see a spec URL in code comments (e.g., https://html.spec.whatwg.org/#navigate), or a step comment like // Step 3.2, query the section to understand the algorithm:
webspec-index query 'https://html.spec.whatwg.org/#navigate'
When you know a concept but not its exact anchor:
# Search by text
webspec-index search "tree order" --spec DOM
# Or find by anchor pattern
webspec-index anchors "*tree*order*" --spec DOM
Verifying spec anchors
Before adding a spec URL to a code comment, verify the anchor exists:
webspec-index exists 'HTML#navigate' && echo "valid"
Understanding cross-spec dependencies
To see what other specs depend on a concept you’re changing:
webspec-index refs 'DOM#concept-tree' --direction incoming
Tracing IDL API usage in algorithms
When implementing or reviewing a DOM API in Gecko:
# Find canonical IDL definition + owning interface
webspec-index idl 'Window.navigation' --format markdown
# Find where the property is used in indexed specs
webspec-index refs 'Window.navigation' --direction incoming
Finding where Gecko implements a spec section
When the user asks where a spec algorithm is implemented in Gecko or SpiderMonkey, query
the spec section first, then pass the url field from the response to searchfox-cli:
# Step 1 — read the spec section (response includes a "url" field)
webspec-index query 'HTML#navigate' --format json
# Step 2 — find Gecko source files that reference that URL
searchfox-cli --spec-refs 'https://html.spec.whatwg.org/#navigate'
For Gecko or SpiderMonkey implementation questions, pass the url field from the query response
to --spec-refs; no manual URL construction needed.
Implementing a feature from a spec PR
When the bug references a spec PR that hasn’t landed yet:
# See what the PR changes at a section level
webspec-index query 'HTML#navigate' --pr 12345 --diff --format markdown
# Read the algorithm as modified by the PR
webspec-index query 'HTML#navigate' --pr 12345 --format markdown
# Check what new cross-references the PR introduces
webspec-index refs 'HTML#navigate' --pr 12345 --direction outgoing