Cortiq-Labs/iconclip-demo
IconClip — Static Browser Demo
100% frontend-only Hugging Face Space. No Python, no GPU, no backend. Type a query, get the top-K matching icons across 11 open-license libraries, ranked by IconClip text→image cosine similarity. Everything — tokenisation, ONNX forward pass, cosine math, SVG rendering — runs in your tab.
How it works
- On first load, the browser pulls the q8 text encoder (
Cortiq-Labs/IconClip-ViT-L-14-text-encoder-ONNX, ~119 MB total: 113 MB ONNX + 7 MB tokeniser assets) via transformers.js v4. - In parallel, it fetches the pre-computed L2-normalised image embedding matrix (
iconclip-vit-l-14.parquet, ~26 MB; 22 827 rows × 768 f32). The embedding parquet must be hosted alongside this Space (see Assets below). - Per query: tokenise →
CLIPTextModelWithProjectionforward (~30-60 ms on modern laptops, ~150 ms on phones) → dot against the matrix (vectors are already unit-norm sodot == cosine) → top-K argmax. - Per result: render the icon's SVG inline (fetched lazily per-library from the companion images parquet on first use, cached in the Cache API).
All slider / filter state is client-side. After the initial asset load the Space makes zero network calls except for the lazy per-library image parquet on first checkbox-enable.
Files
Asset hosting
This demo expects two companion parquets to live on a Hugging Face dataset:
{DATASET_REPO}/data/embeddings/iconclip-vit-l-14.parquet # 26 MB, all 22 827 rows
{DATASET_REPO}/data/images/{library}.parquet # ~145 MB total across 11 libsThe embeddings parquet schema is:
_id: STRING (e.g. "lucide:bell")
embedding: LIST<FLOAT> (768-d, L2-normalised)The per-library images parquet schema is:
_id: STRING (e.g. "lucide:bell")
svg_text: STRING (raw SVG markup, ready for innerHTML)URLs are configured in js/config.js. As of this Space's publication the embedding parquet has not yet been uploaded to the iconclip-search-benchmark dataset (which is text-metadata-only — see its README). Once embeddings ship to that dataset or a sibling, point config.EMBEDDINGS_URL at the resolve URL.
Running locally
No build step. Just open index.html over HTTP (file:// won't work — ONNX Runtime Web needs proper MIME types for the .wasm files):
cd spaces/iconclip-demo-static
python3 -m http.server 7860
# → http://127.0.0.1:7860Or with any other static server (npx serve, caddy file-server, …).
Performance
Measured on a 2024 laptop (M2-class, 16 GB) over a 200 Mbps connection:
Time-to-first-search on cold load: ~5 s (encoder + parquet in parallel). After cache warm: ~300 ms.
Browser support
Tested on Chromium 130+, Firefox 130+, Safari 18+. WebAssembly SIMD is required (universal among the above). WebGPU is opt-in — the demo defaults to WASM for portability; flip config.DEVICE to 'webgpu' for a 5-10× speed-up on supporting browsers.
License
MIT. Model weights, tokeniser assets, and per-icon SVGs each carry their own upstream licenses (see the IconClip Search Benchmark dataset card).
