the elements that matter, ranked in the browser
A 6.7 MB model that ranks a web page's elements against a browser agent's goal, so the agent's language model reads the top 50 instead of the whole page.
Rank a saved copy of a real website, or paste your own. Everything runs on this device.
Paste the HTML of any page. In Chrome, open the page, choose View Page Source, then select all and copy.
Measured once on Mind2Web's held-out test websites, and inside a real agent.
| Test split | Keyword search | spotlit |
|---|---|---|
| New tasks | 44.2% | 80.8% |
| New websites | 43.8% | 75.8% |
| New domains | 44.5% | 75.9% |
The benchmark authors' 184M-parameter ranker keeps 85 to 89%; spotlit is 29 times smaller and needs no server.
| Input tokens | Cost | Time | |
|---|---|---|---|
| Every element | 2,700,384 | $3.55 | 149 s |
| spotlit top 50 | 427,787 | $0.48 | 173 s |
Both finished all seven. Claude Sonnet, one run per task. How it was measured
One file for a web page, or the full release on Hugging Face.
import * as ort from "onnxruntime-web"; import * as spotlit from "./spotlit.js"; const ranker = await spotlit.loadPacked(ort, "spotlit-v1.weights.gz"); const top50 = await ranker.rank(goal, spotlit.collectCandidates(document));
Apache-2.0. spotlit.js is in the repository. The .weights.gz file is spotlit's own format, checked part by part as it loads; it is not a PyTorch checkpoint.
Read the blog post on how spotlit works, where it misses, and what happened inside Claude Code and Codex.