This monorepo uses pnpm workspaces (no Turbo). All scripts use pnpm --filter to target specific packages.
Available scripts:
pnpm run dev # Build evalite + UI, then run tsc -w on evalite + vitest on evalite-tests
pnpm run example # Build, then run evalite watch + UI dev server (parallel)
pnpm run test # Build, then run tests on evalite + evalite-tests
pnpm run build # Build evalite, then evalite-ui
pnpm run ci # Full CI: build, test, lint, check-formatIndividual package scripts:
pnpm build:evalite # Build evalite package only
pnpm build:evalite-ui # Build UI and copy to evalite/dist/uiSetup:
- Create
.envinpackages/examplewithOPENAI_API_KEY=your-key - Run
pnpm install - For global
evalitecommand:pnpm build && cd packages/evalite && npm link
This project uses Tailwind CSS v4 with a custom design system built on semantic color tokens and OKLCH color space. Follow these guidelines to maintain consistency.
DO: Use semantic tokens with opacity modifiers
<div className="text-foreground/60 bg-foreground/10 hover:bg-foreground/20" />DON'T: Use hardcoded Tailwind colors
// ❌ Avoid
<div className="text-gray-600 bg-gray-100 hover:bg-gray-200" />Always provide dark mode variants for interactive states:
// Button example
<button className="
bg-primary text-primary-foreground
hover:bg-primary/90
focus-visible:ring-ring/50
dark:bg-primary/80
dark:hover:bg-primary/70
" />
// Input example
<input className="
bg-background border-input
dark:bg-input/30 dark:border-input
hover:border-ring
" />Use prose-invert for markdown content:
<ReactMarkdown className="prose dark:prose-invert prose-sm">
{content}
</ReactMarkdown>- System light mode → app should be light
- System dark mode → app should be dark
- System preference change → app should update immediately
- No FOUC on page load
- All interactive states have visible dark variants
- Focus rings visible in both modes
- Markdown content readable in both modes