import "./index.css" import { Link, Meta, Title } from "@solidjs/meta" import { ProviderIcon } from "@opencode-ai/ui/provider-icon" import ibmPlexMonoRegularLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-Regular-Latin1.woff2?url" import ibmPlexMonoMediumLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-Medium-Latin1.woff2?url" import ibmPlexMonoSemiBoldLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-SemiBold-Latin1.woff2?url" import ibmPlexMonoBoldLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-Bold-Latin1.woff2?url" import opencodeWordmarkDark from "../asset/logo-ornate-dark.svg" import statsUnfurlRankings from "../asset/unfurl-rankings.png?url" import { getStatsHomeData, type LeaderboardEntry, type MarketDay, type StatsHomeData, type SessionCostEntry, type TokenCostEntry, type UsagePoint, } from "@opencode-ai/stats-core/domain/home" import { runtime } from "@opencode-ai/stats-core/runtime" import { createAsync, query } from "@solidjs/router" import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show, type JSX } from "solid-js" import { getRequestEvent } from "solid-js/web" const products = ["All Users", "Zen", "Go"] as const const tokenProducts = ["Zen", "Go"] as const const ranges = ["1D", "1W", "2W", "1M", "2M"] as const const rangeLabels: Record = { "1D": "1 Day", "1W": "1 Week", "2W": "2 Weeks", "1M": "1 Month", "2M": "2 Months", } const statsHomeTitle = "OpenCode Stats" const statsHomeDescription = "OpenCode usage, market share, token cost, and session cost stats." const statsHomeFallbackUrl = "https://stats.opencode.ai" const statsUnfurlAlt = "OpenCode Stats wordmark on a dark patterned background" const headerLinks = [ { href: "#top-models", label: "Top Models" }, { href: "#leaderboard", label: "Leaderboard" }, { href: "#token-cost", label: "Token Cost" }, { href: "#session-cost", label: "Session Cost" }, { href: "#market-share", label: "Market Share" }, ] as const const githubLink = { href: "https://github.com/anomalyco/opencode", apiHref: "https://api.github.com/repos/anomalyco/opencode", label: "GitHub", fallbackStars: "150K", ariaLabel: "Star OpenCode on GitHub", } const compactNumberFormatter = new Intl.NumberFormat("en", { notation: "compact", maximumFractionDigits: 1, }) const usageColors = [ "#ed6aff", "#a684ff", "#7c86ff", "#51a2ff", "#00d3f2", "#00d5be", "#00bc7d", "#9ae600", "#ffb900", "#ff8904", "#ff6467", ] const marketColors = ["#ed6aff", "#a684ff", "#7c86ff", "#51a2ff", "#00d3f2", "#00d5be", "#00bc7d", "#9ae600", "#ffb900"] const themePreferences = ["dark", "light", "system"] as const const themePreferenceLabels = { dark: "Dark", light: "Light", system: "System", } as const const themeStorageKey = "opencode:stats-theme" type UsageProduct = (typeof products)[number] type TokenProduct = (typeof tokenProducts)[number] type UsageRange = (typeof ranges)[number] type ThemePreference = (typeof themePreferences)[number] const getData = query(async () => { "use server" return runtime.runPromise(getStatsHomeData()) }, "getStatsHomeData") const getGitHubStars = query(async () => { "use server" return fetch(githubLink.apiHref, { headers: { Accept: "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28", }, }) .then((response) => (response.ok ? response.json() : undefined)) .then((body: unknown) => body && typeof body === "object" && "stargazers_count" in body && typeof body.stargazers_count === "number" ? compactNumberFormatter.format(body.stargazers_count) : githubLink.fallbackStars, ) .catch(() => githubLink.fallbackStars) }, "getGitHubStars") export default function StatsHome() { const event = getRequestEvent() event?.response.headers.set("Cache-Control", "public, max-age=60, s-maxage=300, stale-while-revalidate=86400") const statsHomeUrl = new URL( import.meta.env.BASE_URL, event?.request.url ?? (typeof window === "undefined" ? statsHomeFallbackUrl : window.location.href), ).toString() const statsUnfurlUrl = new URL(statsUnfurlRankings, statsHomeUrl).toString() const data = createAsync(() => getData()) const githubStars = createAsync(() => getGitHubStars()) const [themePreference, setThemePreference] = createSignal("system") const updateThemePreference = (preference: ThemePreference) => { applyThemePreference(preference) setThemePreference(preference) if (typeof window === "undefined") return window.localStorage.setItem(themeStorageKey, preference) } onMount(() => { if (typeof window === "undefined") return const preference = window.localStorage.getItem(themeStorageKey) const nextPreference = isThemePreference(preference) ? preference : "system" applyThemePreference(nextPreference) setThemePreference(nextPreference) }) return (
{statsHomeTitle}
}> {(stats) => ( <> )}
) } function isThemePreference(value: string | null): value is ThemePreference { return value === "dark" || value === "light" || value === "system" } function applyThemePreference(preference: ThemePreference) { if (typeof document === "undefined") return document.documentElement.dataset.statsTheme = preference if (preference === "system") { document.documentElement.style.removeProperty("color-scheme") return } document.documentElement.style.setProperty("color-scheme", preference) } function Hero(props: { updatedAt: string | null }) { const [timeZone, setTimeZone] = createSignal("UTC") const [previousTimeZone, setPreviousTimeZone] = createSignal("UTC") const [isTicking, setIsTicking] = createSignal(false) const updatedAtParts = (timeZone: string) => props.updatedAt ? formatUpdatedAtParts(props.updatedAt, timeZone) : { date: "No rows yet", time: "" } const previousUpdatedAt = createMemo(() => updatedAtParts(previousTimeZone())) const currentUpdatedAt = createMemo(() => updatedAtParts(timeZone())) const currentUpdatedLabel = createMemo(() => props.updatedAt ? `Updated ${formatUpdatedAtLabel(currentUpdatedAt())}` : "No rows yet", ) const isDateTicking = createMemo(() => isTicking() && previousUpdatedAt().date !== currentUpdatedAt().date) const isTimeTicking = createMemo(() => isTicking() && previousUpdatedAt().time !== currentUpdatedAt().time) onMount(() => { if (!props.updatedAt) return const nextTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC" if (nextTimeZone === "UTC") return if ( formatUpdatedAtLabel(formatUpdatedAtParts(props.updatedAt, nextTimeZone)) === formatUpdatedAtLabel(updatedAtParts("UTC")) ) return const timeouts: number[] = [] timeouts.push( window.setTimeout(() => { setPreviousTimeZone(timeZone()) setTimeZone(nextTimeZone) setIsTicking(true) timeouts.push( window.setTimeout(() => { setPreviousTimeZone(nextTimeZone) setIsTicking(false) }, 720), ) }, 480), ) onCleanup(() => timeouts.forEach((timeout) => window.clearTimeout(timeout))) }) return (

{props.updatedAt ? ( <> ) : ( No rows yet )}

) } function HeroMetaTickerPart(props: { previous: string; current: string; ticking: boolean }) { return ( {props.previous} {props.current} ) } function StatsLoading() { return ( <> ) } function ChartSection(props: { id?: string title: string description?: string controls?: JSX.Element children: JSX.Element }) { return (

{props.title}

{props.description &&

{props.description}

}
{props.controls}
{props.children}
) } function SectionTitle(props: { title: string; description: string }) { return (

{props.title}. {props.description}

) } function SectionBridge(props: { label: string; href: string }) { return ( LEAN MORE {props.label} ▸ ) } function EmptyState(props: { title: string; description: string }) { return (
{props.title}

{props.description}

) } function formatUpdatedAtParts(value: string, timeZone: string) { const date = new Date(value) if (Number.isNaN(date.getTime())) return { date: "just now", time: "" } return { date: new Intl.DateTimeFormat("en", { month: "short", day: "numeric", timeZone, }).format(date), time: new Intl.DateTimeFormat("en", { hour: "numeric", minute: "2-digit", timeZone, timeZoneName: "short", }).format(date), } } function formatUpdatedAtLabel(value: { date: string; time: string }) { if (!value.time) return value.date return `${value.date}, ${value.time}` } function TopModelsSection(props: { data: StatsHomeData["usage"]; leaderboard: StatsHomeData["leaderboard"] }) { const [product, setProduct] = createSignal("All Users") const [range, setRange] = createSignal("2M") const [sheet, setSheet] = createSignal<"product" | "range">() const [activeModel, setActiveModel] = createSignal() const data = createMemo(() => props.data[product()][range()]) const leaderboard = createMemo(() => props.leaderboard[product()][range()]) createEffect(() => { if (!sheet()) return if (typeof document === "undefined") return const htmlOverflow = document.documentElement.style.overflow const bodyOverflow = document.body.style.overflow document.documentElement.style.overflow = "hidden" document.body.style.overflow = "hidden" const onKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") setSheet(undefined) } document.addEventListener("keydown", onKeyDown) onCleanup(() => { document.documentElement.style.overflow = htmlOverflow document.body.style.overflow = bodyOverflow document.removeEventListener("keydown", onKeyDown) }) }) return (

Top models. Usage of models across OpenCode.

usageTotal(item) > 0)} fallback={} >
) } function MobileFilterButton(props: { label: string; value: string; expanded: boolean; onClick: () => void }) { return ( ) } function MobileFilterSheet(props: { kind: "product" | "range" product: UsageProduct range: UsageRange onProductSelect: (product: UsageProduct) => void onRangeSelect: (range: UsageRange) => void onClose: () => void }) { return (
{(item) => ( )} } > {(item) => ( )}
) } function ChevronDown() { return ( ) } function StatsFilters(props: { product: UsageProduct range: UsageRange onProductSelect: (product: UsageProduct) => void onRangeSelect: (range: UsageRange) => void }) { return ( <> ) } function FilterPills(props: { items: readonly T[] selected: T label: string variant: "product" | "range" onSelect: (item: T) => void }) { return (
{(item) => ( )}
) } function TopModelsChart(props: { data: UsagePoint[] range: UsageRange activeModel: string | undefined onActiveModelChange: (model: string | undefined) => void }) { let chartRef: HTMLDivElement | undefined const [activeIndex, setActiveIndex] = createSignal() const maxTotal = createMemo(() => getTopModelsMaxTotal(props.data)) const segmentOrder = createMemo(() => getTopModelsSegmentOrder(props.data)) const activePoint = createMemo(() => props.data[activeIndex() ?? -1]) createEffect(() => scrollDenseChartToEnd(chartRef, props.range, props.data.length)) return (
{(day, dayIndex) => (
{ if (event.pointerType !== "touch") return setActiveIndex(dayIndex()) props.onActiveModelChange(undefined) }} onPointerEnter={() => { setActiveIndex(dayIndex()) props.onActiveModelChange(undefined) }} onPointerLeave={(event) => { if (event.pointerType === "touch") return setActiveIndex(undefined) props.onActiveModelChange(undefined) }} onClick={() => { setActiveIndex(dayIndex()) props.onActiveModelChange(undefined) }} onFocus={() => { setActiveIndex(dayIndex()) props.onActiveModelChange(undefined) }} onBlur={() => { setActiveIndex(undefined) props.onActiveModelChange(undefined) }} onKeyDown={(event) => { if (event.key !== "Enter" && event.key !== " ") return event.preventDefault() setActiveIndex(dayIndex()) props.onActiveModelChange(undefined) }} >
{(item) => ( { event.stopPropagation() setActiveIndex(dayIndex()) props.onActiveModelChange(item.segment.model) }} onPointerDown={(event) => { event.stopPropagation() setActiveIndex(dayIndex()) props.onActiveModelChange(item.segment.model) }} onClick={(event) => { event.stopPropagation() setActiveIndex(dayIndex()) props.onActiveModelChange(item.segment.model) }} /> )}
{(point) => (
props.data.length * 0.62 ? "left" : "right"} > {point().date} {formatTokens(usageTotal(point()))} total
{(item) => (

{" "} {item.segment.model} {formatTokens(item.segment.value)}

)}
)}
)}
) } function getTopModelsBarHeight(total: number, max: number) { if (total <= 0) return 0 return Math.max(2, Math.min(100, (total / max) * 100)) } function getTopModelsMaxTotal(data: UsagePoint[]) { const max = Math.max(0, ...data.map((item) => usageTotal(item))) if (max === 0) return 1 if (data.length === 1) return max * 1.75 return max } function getTopModelsSegmentRows(point: UsagePoint, order: Map) { const total = usageTotal(point) if (total <= 0) return "" return stackedTopModelsSegments(point, order) .map((item) => `${(item.segment.value / total) * 100}%`) .join(" ") } function visibleTopModelsSegments(point: UsagePoint) { return point.segments.map((segment, index) => ({ segment, index })).filter((item) => item.segment.value > 0) } function stackedTopModelsSegments(point: UsagePoint, order: Map) { return visibleTopModelsSegments(point) .slice() .sort((a, b) => (order.get(b.segment.model) ?? b.index) - (order.get(a.segment.model) ?? a.index)) } function getTopModelsSegmentOrder(data: UsagePoint[]) { return getRankOrder( data.flatMap((point) => point.segments.map((segment, index) => ({ key: segment.model, value: segment.value, index })), ), ) } function getTopModelsSegmentColor( model: string, index: number, order: Map, muted: boolean, activeModel: string | undefined, ) { if (activeModel !== undefined) return activeModel === model ? getRankColor(model, index, order, usageColors) : "var(--stats-layer-2)" if (muted) return "var(--stats-layer-2)" return getRankColor(model, index, order, usageColors) } function isTopModelsMobileAxisHidden(index: number, count: number) { return count > 7 && index % 2 === 1 } function isColumnLabelHidden(index: number, count: number) { if (count <= 20) return false const interval = Math.ceil(count / 8) return index !== count - 1 && index % interval !== 0 } function isDenseColumnRange(range: UsageRange) { return range === "1M" || range === "2M" } function scrollDenseChartToEnd(element: HTMLDivElement | undefined, range: UsageRange, count: number) { if (!element || count <= 0 || !isDenseColumnRange(range) || typeof window === "undefined") return window.requestAnimationFrame(() => { element.scrollLeft = element.scrollWidth - element.clientWidth }) } function formatTopModelsMobileDate(label: string, range: UsageRange) { if (range === "1M" || range === "2M") return label.split(" - ")[0] ?? label return label } function usageTotal(point: UsagePoint) { return point.segments.reduce((sum, item) => sum + item.value, 0) } function formatTokens(value: number) { if (value >= 1) return `${value.toFixed(value >= 10 ? 0 : 1)}T` return `${Math.round(value * 1000)}B` } function Leaderboard(props: { data: LeaderboardEntry[] activeModel: string | undefined onActiveModelChange: (model: string | undefined) => void }) { return (
{(entry) => ( )}
) } function LeaderboardCard(props: { entry: LeaderboardEntry active: boolean onActiveModelChange: (model: string | undefined) => void }) { return (
props.onActiveModelChange(props.entry.model)} onPointerLeave={(event) => { if (event.pointerType === "touch") return props.onActiveModelChange(undefined) }} onFocus={() => props.onActiveModelChange(props.entry.model)} onBlur={() => props.onActiveModelChange(undefined)} onClick={() => props.onActiveModelChange(props.entry.model)} > {String(props.entry.rank).padStart(2, "0")}
) } function getProviderIconId(author: string) { if (author === "MiniMax") return "minimax" if (author === "Moonshot") return "moonshotai" if (author === "Zhipu") return "zhipuai" return author.toLowerCase() } function formatBillions(value: number) { if (value >= 1000) return `${(value / 1000).toFixed(value >= 10000 ? 0 : 1)}T` return `${value}B` } function formatChange(value: number) { if (value > 0) return `+${value}%` return `${value}%` } function MarketShareSection(props: { data: StatsHomeData["market"] }) { const [range, setRange] = createSignal("2M") const [activeIndex, setActiveIndex] = createSignal(2) const [activeAuthor, setActiveAuthor] = createSignal() const [inspecting, setInspecting] = createSignal(false) const data = createMemo(() => props.data[range()]) const authorOrder = createMemo(() => getMarketAuthorOrder(data())) const selectedIndex = createMemo(() => Math.min(activeIndex(), Math.max(data().length - 1, 0))) const activeDay = createMemo(() => data()[selectedIndex()]) return (
{ if (event.pointerType === "touch") return setActiveAuthor(undefined) setInspecting(false) }} > } > {(day) => ( <> { setActiveIndex(index) setInspecting(true) }} onActiveAuthorChange={(author) => { setActiveAuthor(author) setInspecting(true) }} /> { setActiveAuthor(author) setInspecting(true) }} /> )}

[*] {inspecting() ? formatMarketDate(activeDay()) : formatMarketRange(data())}

{ setRange(item) setActiveAuthor(undefined) setInspecting(false) }} />
) } function MarketShare(props: { data: MarketDay[] range: UsageRange authorOrder: Map activeIndex: number activeAuthor: string | undefined inspecting: boolean onActiveIndexChange: (index: number) => void onActiveAuthorChange: (author: string) => void }) { let chartRef: HTMLDivElement | undefined createEffect(() => scrollDenseChartToEnd(chartRef, props.range, props.data.length)) return (
{(day, index) => ( )}
{(day, index) => ( )}
) } function MarketShareList(props: { data: MarketDay["authors"] authorOrder: Map activeAuthor: string | undefined onActiveAuthorChange: (author: string) => void }) { return (
    {(item, index) => (
  1. props.onActiveAuthorChange(item.author)} onFocus={() => props.onActiveAuthorChange(item.author)} onKeyDown={(event) => { if (event.key !== "Enter" && event.key !== " ") return event.preventDefault() props.onActiveAuthorChange(item.author) }} > {String(index() + 1).padStart(2, "0")} {item.author} {formatTrillions(item.tokens)} {item.share.toFixed(1)}%
  2. )}
) } function getMarketSegmentColor(author: string, color: string, activeAuthor: string | undefined) { if (!activeAuthor) return color if (activeAuthor === author) return color return "var(--stats-bar-idle)" } function stackedMarketAuthors(day: MarketDay, order: Map) { return day.authors .map((author, index) => ({ author, index })) .slice() .sort((a, b) => (order.get(b.author.author) ?? b.index) - (order.get(a.author.author) ?? a.index)) } function getMarketAuthorOrder(data: MarketDay[]) { return getRankOrder( data.flatMap((day) => day.authors.map((author, index) => ({ key: author.author, value: author.tokens, index }))), ) } function getRankOrder(items: { key: string; value: number; index: number }[]) { return new Map( Object.values( items.reduce>((result, item) => { result[item.key] = { key: item.key, value: (result[item.key]?.value ?? 0) + item.value, index: Math.min(result[item.key]?.index ?? item.index, item.index), } return result }, {}), ) .toSorted((a, b) => b.value - a.value || a.index - b.index || a.key.localeCompare(b.key)) .map((item, index) => [item.key, index] as const), ) } function getRankColor(key: string, fallbackIndex: number, order: Map, colors: readonly string[]) { return colors[order.get(key) ?? fallbackIndex] ?? "var(--stats-text)" } function isMarketMobileLabelHidden(index: number, count: number) { return count > 7 && index % 2 === 1 } function formatMarketMobileDate(label: string) { return marketDateParts(label).start } function formatTrillions(value: number) { return `${value.toFixed(value >= 10 ? 0 : 1)}T` } function formatMarketDate(day: MarketDay | undefined) { if (!day) return "No data" return formatMarketDateLabel(day.date) } function formatMarketRange(data: MarketDay[]) { const first = data[0]?.date const last = data[data.length - 1]?.date if (!first || !last) return "No data" const start = marketDateParts(first).start const end = marketDateParts(last).end if (start === end) return formatMarketDateLabel(start) return `${start} ${new Date().getFullYear()} → ${end} ${new Date().getFullYear()}` } function formatMarketDateLabel(label: string) { const parts = marketDateParts(label) const year = new Date().getFullYear() if (parts.start === parts.end) return `${parts.start} ${year}` return `${parts.start} ${year} → ${parts.end} ${year}` } function marketDateParts(label: string) { const [start, end] = label.split(" - ") return { start: start ?? label, end: end ?? start ?? label } } function TokenCostSection(props: { data: StatsHomeData["tokenCost"] }) { const [product, setProduct] = createSignal("Zen") const [activeIndex, setActiveIndex] = createSignal(2) const data = createMemo(() => props.data[product()]) const visible = createMemo(() => data().slice(0, 13)) const selectedIndex = createMemo(() => Math.min(activeIndex(), Math.max(visible().length - 1, 0))) return (
0} fallback={ } >
) } function TokenCostChart(props: { data: TokenCostEntry[] activeIndex: number onActiveIndexChange: (index: number) => void }) { const max = createMemo(() => Math.max(0, ...props.data.map((item) => item.total)) || 1) const active = createMemo(() => props.data[props.activeIndex] ?? props.data[0]) return (
{(item, index) => ( )} {(item) => (

Input {formatDollars(item().input)}

Output {formatDollars(item().output)}

Cached {formatDollars(item().cached)}

)}
) } function formatDollars(value: number) { return `$${value.toFixed(2)}` } function MetricBar(props: { value: number; max: number; active: boolean }) { const fill = createMemo(() => Math.min(1, Math.max(props.value / props.max, props.value > 0 ? 0.03 : 0))) return ( ) } function SessionCostSection(props: { data: StatsHomeData["sessionCost"] }) { const [product, setProduct] = createSignal("Zen") const [activeIndex, setActiveIndex] = createSignal(2) const data = createMemo(() => props.data[product()]) const visible = createMemo(() => data().slice(0, 16)) const selectedIndex = createMemo(() => Math.min(activeIndex(), Math.max(visible().length - 1, 0))) return (
0} fallback={ } >
) } function SessionCostChart(props: { data: SessionCostEntry[] activeIndex: number onActiveIndexChange: (index: number) => void }) { const maxCost = createMemo(() => Math.max(0, ...props.data.map((item) => item.cost)) || 1) const maxTokens = createMemo(() => Math.max(0, ...props.data.map((item) => item.tokens)) || 1) const active = createMemo(() => props.data[props.activeIndex] ?? props.data[0]) return (