spaces-pulse
What AI demo is the internet trying right now?
Live tracker for trending Hugging Face Spaces — velocity, SDK breakdown, hot new arrivals. Refreshed hourly from the public HF API. No auth, no tracking.
What it does
spaces-pulse snapshots the public Hugging Face Spaces API every hour, computes 24h likes/trending deltas, and surfaces six views:
- Trending Now — top by HF
trendingScore. - 24h Movers — biggest velocity score (
0.7·Δlikes + 0.3·Δtrendingover 24h). - Hot New ≤14d — Spaces created in the last 14 days with at least some likes.
- Cooling — Spaces with the steepest negative 24h velocity.
- By SDK — separate boards for Gradio / Streamlit / Docker / Static.
- Search — substring match on id, title, author.
Click any card to see a detail modal with the last 30 snapshots as an inline SVG sparkline plus a table.
Stack
Node.js 18+ · Express 4 · better-sqlite3 (WAL) · node-cron · helmet · compression · vanilla JS SPA, dark theme.
Data sources (all public, no auth)
| Source | URL | Refresh |
|---|---|---|
| Trending | https://huggingface.co/api/spaces?sort=trendingScore&direction=-1&limit=200 | hourly @ :07 UTC |
| Likes | https://huggingface.co/api/spaces?sort=likes&direction=-1&limit=200 | hourly @ :12 UTC |
| Newest | https://huggingface.co/api/spaces?sort=createdAt&direction=-1&limit=200 | hourly @ :22 UTC |
| Per-SDK | https://huggingface.co/api/spaces?sort=trendingScore&filter=<sdk>&limit=50 | every 6h @ :17 UTC |
No mock data, no seed lists, no Math.random() jitter. If a source fails the snapshot is skipped and refresh_log records the error.
Endpoints (all under BASE_PATH = /spaces-pulse, all public)
| Method | Path | What |
|---|---|---|
| GET | / | The SPA |
| GET | /health | { ok, version, spaces, snapshots, last_refresh, uptime_seconds } |
| GET | /api/trending?limit=50 | Top by trending score |
| GET | /api/movers?limit=50 | Top by 24h velocity |
| GET | /api/new?limit=50&days=14 | Hot new arrivals |
| GET | /api/cooling?limit=50 | Biggest 24h drops |
| GET | /api/sdk/:sdk?limit=50 | Per-SDK leaderboard |
| GET | /api/space/:author/:name | Full record + last 30 snapshots |
| GET | /api/search?q=<term> | Substring search |
| GET | /api/stats | Counters + per-source last refresh |
| POST | /api/refresh?source=<src> | Trigger a refresh. src ∈ trending|likes|newest|sdk|sdk:<sdk>|all. Fire-and-forget, returns 202. |
Local dev
cp .env.example .env
npm install
npm start
Default URL: http://localhost:4833/spaces-pulse/.
Acceptance
node --checkpasses on every.jsfile.GET /spaces-pulse/healthreturns 200 within 500 ms with no credentials.- Every refresh row in
refresh_logrecords itsstarted_at,finished_at,ok,items_seen,new_spaces,http_status, anderror.
License
MIT — see LICENSE if/when it appears. Until then, treat as "all rights reserved, free to fork for non-commercial use".