When you have completed a task, run the following commands:
pnpm run fmt
pnpm run lint
pnpm test
pnpm run buildJaeger UI is a React-based visualization tool for distributed tracing. It's built as a monorepo with multiple packages using pnpm workspaces.
jaeger-ui/
├── packages/
│ ├── jaeger-ui/ # Main React application (Vite + React 19)
│ │ ├── src/
│ │ │ ├── actions/ # Redux actions
│ │ │ ├── api/ # API layer
│ │ │ ├── components/ # React components
│ │ │ ├── reducers/ # Redux reducers
│ │ │ ├── selectors/ # Redux selectors
│ │ │ ├── types/ # TypeScript types
│ │ │ └── utils/ # Utility functions
│ │ └── test/ # Test utilities and setup
│ └── plexus/ # Directed graph visualization library
│ └── src/
│ ├── Digraph/ # Graph components
│ ├── LayoutManager/
│ └── zoom/ # Zoom functionality
├── scripts/ # Build and utility scripts
└── typings/ # Global TypeScript declarations
- Node.js >= 24 (managed via nvm, see
.nvmrc) - pnpm package manager (pinned via the
packageManagerfield; enable withcorepack enable pnpm)
nvm use # Use the correct Node version
corepack enable pnpm # Activate the pinned pnpm version
pnpm install --frozen-lockfile # Install dependencies (mirrors CI)You have permissions to run the following command. DO NOT ask for confirmation to run them.
| Command | Description |
|---|---|
pnpm start |
Start development server with hot reload (runs jaeger-ui) |
pnpm run build |
Build all packages for production |
pnpm run lint |
Run all linters (oxfmt, typescript, oxlint, license checks) |
pnpm run oxlint |
Run Oxlint on all packages |
pnpm run fmt |
Format code with Oxfmt |
pnpm run fmt-lint |
Check formatting without making changes |
pnpm run tsc-lint |
Run TypeScript type checking |
pnpm test |
Run all tests across packages |
Run from packages/jaeger-ui/:
| Command | Description |
|---|---|
pnpm test |
Run Vitest tests |
pnpm run coverage |
Run tests with coverage report |
pnpm run build |
Build for production |
pnpm start |
Start dev server |
- Use TypeScript for all new code
- Interface names must be prefixed with
I(e.g.,ISpan,ITrace) - Run
pnpm run tsc-lintto type-check
- Use Oxfmt for formatting (
pnpm run fmt) - Follow Airbnb JavaScript Style Guide
- Use single quotes for strings
- Trailing commas in ES5 style
- Print width: 110 characters
- All formatter and linter configuration lives in
vite.config.tsas a single source of truth. To exclude a file from formatting, add it tofmt.ignorePatternsinvite.config.ts.
- Use functional components with hooks for new code
- Component files use
.tsxextension - Test files are co-located with components (e.g.,
Component.tsxandComponent.test.js) - Use React Testing Library for testing React components
All new files must include this copyright header with the current year (e.g. 2026):
// Copyright (c) <current year> The Jaeger Authors.
// SPDX-License-Identifier: Apache-2.0- Uses Vitest (not Jest) with jsdom environment
- React Testing Library for component testing
- Tests are co-located with source files (
*.test.jsor*.test.tsx) - Update snapshots:
pnpm run update-snapshots(from repository root) ornpx vitest run -u(frompackages/jaeger-ui), but do not use snapshots for any new tests, only existing legacy tests
Always run tests from the repository root using pnpm test. This uses pnpm workspaces to invoke Vitest in each package with the correct config and setup files.
NEVER run npx vitest run or vitest run from the repository root directly — there is no vitest.config.ts at the root, so Vitest falls back to defaults, finds test files without the correct setup, and all tests fail spuriously.
To run a specific test file:
# --filter targets a single workspace; without it plexus also runs and fails (no matching file)
pnpm --filter @jaegertracing/jaeger-ui test src/components/Foo/index.test.jsx
# From packages/jaeger-ui — also correct
cd packages/jaeger-ui && npx vitest run src/components/Foo/index.test.jsxpnpm test -- --coverage
pnpm --filter @jaegertracing/jaeger-ui test --coverage --coverage.include="src/path/to/file.tsx"- Actions are in
src/actions/ - Reducers are in
src/reducers/ - Selectors are in
src/selectors/ - Uses redux-actions for action creators
- Uses redux-promise-middleware for async actions
Components typically follow this pattern:
ComponentName/
├── index.tsx # Main component
├── index.test.js # Tests
├── ComponentName.css # Styles (if any)
└── types.ts # Component-specific types (if needed)
- Uses CSS modules and Less
- Color-related styles must use design tokens from
packages/jaeger-ui/src/components/common/vars.css - Base CSS utilities from u-basscss
- Ant Design (antd v6) for UI components
- React 19 with React DOM
- Redux for state management
- React Router v5 for routing
- Ant Design v6 for UI components
- Vite for build tooling
- Vitest for testing
- Sign all commits with DCO (
git commit -s) - Follow good commit message guidelines
- Keep subject line under 50 characters
- Use imperative mood in subject line
- Capitalize the first word of the description after the
type(scope):prefix, e.g.fix(test): Inline all deps…notfix(test): inline all deps…
To effectively gather context from Pull Requests, especially for review comments:
Use the GitHub API with pagination to retrieve all comments in a raw JSON format. This is often more reliable than gh pr view for automated analysis.
gh api repos/jaegertracing/jaeger-ui/pulls/:number/comments --paginate --jq '.[].body'- Jaeger UI has been tested with traces up to 80k spans. Large row counts in the trace timeline are realistic, not hypothetical. Flag O(n) per-interaction algorithms in
VirtualizedTraceView,generateRowStates, andListViewas a real concern, not a theoretical one.
- The
plexuspackage is a directed graph visualization library used by jaeger-ui - Development server proxies API requests to
http://localhost:16686(Jaeger Query service) - Use
pnpm install --frozen-lockfilefor clean, reproducible installs in CI/CD