Eval charts. For Svelte.
A small, opinionated charting component for showing model evals. Drop it in. Customize the colors. Ship.
npm install @poolsideai/pooleval
Requires Svelte 5.
<script>
import PoolEval from '@poolsideai/pooleval';
const data = [
{ value: 72.4, provider: 'poolside', label: 'Lyra', highlight: true },
{ value: 64, provider: 'openai', label: 'Nova 5' },
{ value: 58.7, provider: 'gemini', label: 'Atlas 2.5 Pro' },
{ value: 51.2, provider: 'claude', label: 'Orion Opus 4.7' },
{ value: 44, provider: 'grok', label: 'Vega 5' },
];
</script>
<PoolEval {data} max={100} title="SWE-bench Verified" />
Numbers count up, bars rise from the floor. Hover any column for the model name.
Pass monochromatic to drop the canonical brand colors and let icons inherit your theme. The highlighted icon picks up --pe-icon-highlight alongside its bar.
<PoolEval
data={gpqa}
max={100}
monochromatic
title="GPQA Diamond"
theme={{
'bar-highlight': '#f97316',
'text-highlight': '#f97316',
'icon-highlight': '#f97316',
'bar-radius': '3px',
'baseline-color': '#d1d5db',
'baseline-padding': '14px',
}}
darkTheme={{
'baseline-color': 'rgba(255, 255, 255, 0.2)',
}}
/>
Pass unit per data point and animate={false} to disable the count-up.
<PoolEval
data={[
{ value: 142, provider: 'grok', label: 'Vega mini', highlight: true, unit: 'ms' },
{ value: 168, provider: 'openai', label: 'Nova 5 mini', unit: 'ms' },
{ value: 195, provider: 'gemini', label: 'Atlas 2.5 Flash', unit: 'ms' },
]}
animate={false}
title="Inference latency, lower is better"
theme={{
'bar-highlight': '#111111',
'text-highlight': '#111111',
'bar-radius': '4px',
}}
/>
Pass labels={true} to show compact model names below the provider icons. The label lane is measured from the longest label.
<PoolEval
data={labeled}
max={100}
labels={true}
title="Arena win rate"
theme={{
'bar-highlight': '#2455ff',
'text-highlight': '#2455ff',
'bar-gap': '28px',
}}
/>
Built-in provider SVGs still resolve from provider. For your own provider mark, pass a Svelte component through providerIcons keyed by provider name.
<script>
import PoolEval from '@poolsideai/pooleval';
import AcmeProviderIcon from './AcmeProviderIcon.svelte';
const data = [
{ value: 94, provider: 'acme', label: 'Acme Reasoner', highlight: true },
{ value: 88, provider: 'poolside', label: 'Lyra' },
{ value: 83, provider: 'openai', label: 'Nova 5' },
];
const providerIcons = {
acme: AcmeProviderIcon,
};
</script>
<PoolEval {data} {providerIcons} max={100} title="Custom provider icon" />
You can also set icon on a single datum when only one column needs an override:
const data = [
{ value: 94, provider: 'acme', label: 'Acme Reasoner', icon: AcmeProviderIcon },
];
| Prop | Type | Default | Description |
|---|---|---|---|
data |
Datum[] |
[] |
Array of data points. See shape below. |
max |
number | null |
null |
Maximum value used to scale the bars. Auto-detected from data if omitted. |
animate |
boolean |
true |
Animate count-up and bar rise on mount. |
duration |
number |
900 |
Animation duration in ms. |
tooltip |
boolean |
true |
Show tooltip with model name on hover. |
monochromatic |
boolean |
false |
Use single-color icons that follow --pe-icon-color / --pe-icon-highlight. |
labels |
boolean |
false |
Show rotated text labels below provider icons. |
counts |
boolean |
true |
Show the numeric value above each bar. |
chartHeight |
number |
150 |
Bar lane height in pixels. |
providerIcons |
Record<string, Component> |
{} |
Custom Svelte components keyed by provider. Used before built-in SVG lookup. |
title |
string |
"Model evaluation chart" |
Accessible title. |
description |
string |
"" |
Accessible description. |
theme |
Record<string,string> |
{} |
CSS variable overrides. See tokens below. |
darkTheme |
Record<string,string> |
{} |
Same as theme but applied in dark mode. |
forceDark |
boolean |
false |
Force dark theme regardless of prefers-color-scheme. |
class |
string |
"" |
Extra class names on the root element. |
type Datum = {
value: number; // numeric value to plot
provider: string; // provider key (see list below)
icon?: Component; // custom provider icon for this datum
label?: string; // model name shown in the tooltip and rotated label
highlight?: boolean; // marks this row as the highlighted (accent) bar
unit?: string; // appended to the count, e.g. "ms" or "%"
};
Custom icon components render inside the fixed-size provider icon wrapper. They receive these props:
type ProviderIconProps = {
datum: Datum;
provider?: string;
label?: string;
value: number;
highlight: boolean;
monochromatic: boolean;
size: string; // "var(--pe-icon-size)"
};
Render SVGs or images at width={size} and height={size} to match the chart's icon-size token.
All visual controls go through CSS variables on the root element. Pass them either through the theme / darkTheme props or via plain CSS overrides.
| Token | Default | Description |
|---|---|---|
bar-color |
#d6d6d6 |
Default bar fill. |
bar-highlight |
#7c3aed |
Highlighted bar fill and focus ring. |
bar-width |
22px |
Width of each bar column. |
bar-radius |
0px |
Corner radius for bars. |
bar-gap |
18px |
Space between bar columns. |
| Token | Default | Description |
|---|---|---|
count-color |
inherits text-color |
Numeric count above each bar. |
count-highlight |
inherits text-highlight |
Highlighted count text color. |
count-font |
inherits font |
Font stack for the counts. |
count-font-size |
inherits font-size |
Font size for the counts. |
| Token | Default | Description |
|---|---|---|
tooltip-bg |
#111 |
Tooltip background color and arrow fill. |
tooltip-color |
#fff |
Tooltip text color. |
tooltip-font |
inherits font |
Font stack used by the tooltip. |
tooltip-font-size |
inherits font-size |
Tooltip text size. |
tooltip-radius |
6px |
Tooltip corner radius. |
| Token | Default | Description |
|---|---|---|
baseline-color |
rgba(0, 0, 0, 0.10) |
Baseline stroke color. |
baseline-width |
1px |
Baseline thickness. |
baseline-padding |
10px |
How far the baseline extends beyond the outside bars. |
baseline-offset |
0px |
Vertical offset from the bar baseline. |
| Token | Default | Description |
|---|---|---|
icon-color |
#d6d6d6 |
Monochromatic icon color. |
icon-highlight |
#7c3aed |
Highlighted monochromatic icon color. |
icon-fg |
#111 |
Foreground color for full-color provider icons. |
icon-size |
20px |
Provider icon size. |
icon-gap |
12px |
Space between bar base and icon. |
| Token | Default | Description |
|---|---|---|
text-color |
#b0b0b0 |
Value labels and rotated model labels. |
text-highlight |
#7c3aed |
Highlighted value and model label text. |
label-color |
inherits text-color |
Rotated model label text color. |
label-highlight |
inherits text-highlight |
Highlighted rotated model label text color. |
label-font |
inherits font |
Font stack used by rotated model labels. |
label-font-size |
11px |
Font size for rotated model labels. |
label-gap |
8px |
Space between icon and rotated label. |
| Token | Default | Description |
|---|---|---|
bg |
transparent |
Chart wrapper background. |
font |
"JetBrains Mono", ui-monospace, monospace |
Font stack used by values, labels, and tooltips. |
font-size |
13px |
Base chart font size. |
anthropic, claude, openai, gemini, google, grok, xai, poolside, qwen, deepseek, zai, glm, mistral, devstral, github, generic.
Each ships a brand-color SVG and a monochromatic variant. Aliases (xai → grok, glm → zai, devstral → mistral) resolve to the canonical mark. Custom components passed through providerIcons or datum icon take precedence over this built-in lookup.
MIT.
All product names, logos, and brand marks are the property of their respective owners. Use of these names, logos, and brand marks does not imply endorsement.