spotlit

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.

Apache-2.0 · ~0.25 s per page · no server

A real Mind2Web step on a website the model never trained on. The page is redrawn; the element text and the model's output are real.

Try it on a real page

Rank a saved copy of a real website, or paste your own. Everything runs on this device.

Results

Measured once on Mind2Web's held-out test websites, and inside a real agent.

Clicked element kept in the top 50

Test splitKeyword searchspotlit
New tasks44.2%80.8%
New websites43.8%75.8%
New domains44.5%75.9%

The benchmark authors' 184M-parameter ranker keeps 85 to 89%; spotlit is 29 times smaller and needs no server.

Claude Code, seven multi-page tasks

Input tokensCostTime
Every element2,700,384$3.55149 s
spotlit top 50427,787$0.48173 s

Both finished all seven. Claude Sonnet, one run per task. How it was measured

Download

One file for a web page, or the full release on Hugging Face.

For a web page

Both stages and the vocabulary in one gzipped file, loaded by spotlit.js.

Download 5.0 MB

Full open weights

The full-precision re-ranker for Python, the INT8 ONNX, stage 1, the model card and checksums.

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.