import React, { useEffect, useMemo, useRef, useState } from 'react' import { api, hubTop } from './api.js' import { Sparkline, Stat, AreaChart, fmt, pct } from './components.jsx' import { ModelPage, AuthorPage, Loading, ErrBox } from './pages.jsx' function parseHash() { const h = location.hash if (h.startsWith('#/m/')) return { v: 'model', id: decodeURIComponent(h.slice(4)) } if (h.startsWith('#/a/')) return { v: 'author', author: decodeURIComponent(h.slice(4)) } return { v: 'home' } } const BOARDS = [ { key: 'gainers_7d', label: 'Gainers 7d', sub: 'biggest absolute 7-day gains' }, { key: 'growth_7d', label: 'Fastest growing', sub: 'relative growth vs week before' }, { key: 'breakouts', label: 'Breakouts', sub: 'new entries with traction' }, { key: 'likes_7d', label: 'Most liked 7d', sub: 'likes gained this week' }, { key: 'families', label: 'Top families', sub: 'ecosystems by family downloads' }, { key: 'authors_dl30', label: 'Authors 30d', sub: 'most downloaded authors' }, { key: 'authors_7d', label: 'Authors 7d', sub: 'this week\'s top authors' }, ] function BoardTable({ rows, go, isAuthors }) { if (!rows || !rows.length) return

Empty board this week.

const maxdl = Math.max(1, ...rows.map((r) => r.dl30 || 0)) return ( {!isAuthors && } {rows.map((r, i) => { const name = isAuthors ? r.author : r.id const href = isAuthors ? '#/a/' + r.author : '#/m/' + r.id return ( go(href)} className="cursor-pointer border-b border-[var(--line2)] transition-colors hover:bg-[var(--accent-soft)]/40"> {!isAuthors && } ) })}
# {isAuthors ? 'Author' : 'Model'} 30d 7dGrowth♥
{i + 1} {name}{!isAuthors && r.pipeline_tag && {r.pipeline_tag}} {isAuthors && {fmt(r.models)} models} {fmt(r.dl30)} {fmt(r.dl_7d)}♥ {fmt(r.likes)}
) } function Home({ go }) { const [hub, setHub] = useState(null) const [hubErr, setHubErr] = useState(null) const [boards, setBoards] = useState(null) const [board, setBoard] = useState('gainers_7d') const [top, setTop] = useState(null) const [trend, setTrend] = useState(null) useEffect(() => { api.hub().then(setHub).catch(setHubErr) api.leaderboards().then(setBoards).catch(() => {}) hubTop('downloads', 12).then(setTop).catch(() => {}) hubTop('trendingScore', 10).then(setTrend).catch(() => {}) }, []) const pulse = useMemo(() => { if (!hub || !hub.day) return null const byDay = new Map() const low = new Set(hub.low_days || []) hub.day.forEach((day, i) => { if (low.has(day)) return; byDay.set(day, (byDay.get(day) || 0) + (hub.dl[i] || 0)) }) const days = Array.from(byDay.keys()).sort() return { days, vals: days.map((d) => byDay.get(d)) } }, [hub]) const yestTotal = pulse ? pulse.vals[pulse.vals.length - 1] : null const prevTotal = pulse ? pulse.vals[pulse.vals.length - 8] : null const week = pulse ? pulse.vals.slice(-7).reduce((a, b) => a + b, 0) : null return (

The pulse of the whole Hub, day by day.

Download history for every model on Hugging Face — search any repo, follow its curve, climb through the leaderboards. ~1M+ models, updated daily.

{hubErr && location.reload()} />} {!pulse && !hubErr && (
)} {pulse && (

Hub downloads per day

{fmt(yestTotal)} yesterday · {fmt(week)} last 7d · vs {fmt(prevTotal)} week before

Aggregate across the 8 largest task families · gaps in the source data are smoothed out

)} {trend && trend.length > 0 && (

Trending right now · live from the Hub API

{trend.map((m) => ( {m.id} ))}
)}

Leaderboards · week of {boards ? boards.updated : '…'}

{BOARDS.map((b) => ( ))}

{(BOARDS.find((b) => b.key === board) || {}).sub}

{boards ? : }
{top && (

Most downloaded right now · live from the Hub API

{top.map((m, i) => ( go('#/m/' + m.id)} className="cursor-pointer border-b border-[var(--line2)] transition-colors hover:bg-[var(--accent-soft)]/40"> ))}
{i + 1} {m.id}{m.pipeline_tag || ''} {fmt(m.downloads)} {fmt(m.downloadsAllTime)} all time ♥ {fmt(m.likes)}
)}
) } export default function App() { const [route, setRoute] = useState(parseHash()) const [theme, setTheme] = useState(() => (localStorage.getItem('hf-theme') || 'dark')) const [query, setQuery] = useState('') const [results, setResults] = useState(null) const [searching, setSearching] = useState(false) const searchRef = useRef(null) const boxRef = useRef(null) useEffect(() => { document.documentElement.classList.toggle('light', theme === 'light') localStorage.setItem('hf-theme', theme) }, [theme]) useEffect(() => { const f = () => { setRoute(parseHash()); setResults(null); setQuery('') } window.addEventListener('hashchange', f) return () => window.removeEventListener('hashchange', f) }, []) useEffect(() => { const onKey = (e) => { if (e.key === '/' && document.activeElement !== searchRef.current) { e.preventDefault(); searchRef.current?.focus() } if (e.key === 'Escape') { setResults(null); searchRef.current?.blur() } } const onClick = (e) => { if (boxRef.current && !boxRef.current.contains(e.target)) setResults(null) } window.addEventListener('keydown', onKey) window.addEventListener('mousedown', onClick) return () => { window.removeEventListener('keydown', onKey); window.removeEventListener('mousedown', onClick) } }, []) useEffect(() => { const q = query.trim() if (q.length < 2) { setResults(null); setSearching(false); return } setSearching(true) const t = setTimeout(() => { api.search(q).then((r) => { setResults(r.slice(0, 8)); setSearching(false) }).catch(() => { setResults([]); setSearching(false) }) }, 250) return () => clearTimeout(t) }, [query]) const go = (href) => { location.hash = href } const open = (href) => { setResults(null); setQuery(''); go(href) } return (
hub·flow {route.v === 'home' ? 'every model on the hub' : route.v === 'model' ? 'model' : 'author'}
setQuery(e.target.value)} placeholder={'Search models /'} className="w-44 rounded-lg border border-[var(--line)] bg-[var(--panel)] px-3 py-1.5 font-mono text-xs text-[var(--ink)] placeholder-[var(--faint)] outline-none transition-colors focus:border-[var(--accent)] sm:w-64" /> {results && results.length > 0 && (
{results.map((r) => ( ))}
)} {results && !results.length && !searching && (
Nothing found for “{query}”
)}
) }