Skip to content
EliteChart

Contributing

Clone, build, test, ship — the full ChartForge contributor loop.

ChartForge is MIT-licensed and welcomes contributions. This page describes the canonical local development loop, the architectural boundaries you should respect, and the slash-command workflow used internally by the project's AI orchestration layer.

Authoritative source of truth — every contributor (human or agent) MUST read CLAUDE.md before making changes. It defines non-negotiable quality gates (TypeScript strict, 90% coverage, performance budget, bundle budget, accessibility, SSR-safety, etc.). Anything that conflicts with CLAUDE.md is wrong.

Repository layout

code
trading-chart-library/
├── packages/
│   ├── core/         # @elitechart/core — engine, renderer, data, types
│   ├── react/        # @elitechart/react — minimal React adapter
│   ├── elitechart/   # @elitechart/elitechart — drop-in trading chart
│   ├── indicators/   # @elitechart/indicators — 50+ TA indicators
│   ├── drawings/     # @elitechart/drawings — drawing tools
│   └── themes/       # @elitechart/themes — prebuilt themes
├── apps/
│   ├── docs/         # This documentation site (Next.js + fumadocs)
│   ├── playground/   # Editable live examples
│   ├── elitechart-demo/ # Reference EliteChart integration
│   └── next-demo/    # Reference Next.js App Router integration
├── docs/             # Architecture docs, ADRs
└── .claude/          # Agent charters, skills, slash commands

Architectural boundaries are firm:

  • @elitechart/core has zero runtime dependencies (single exception: a tiny date-utility subset). No new deps without orchestrator approval.
  • @elitechart/react depends only on @elitechart/core and React's peer.
  • @elitechart/elitechart depends on the four sibling packages (core, themes, indicators, drawings) plus a small set of UI deps (lucide-react, zustand). It does not export anything back to @elitechart/core.
  • @elitechart/indicators is pure functional math — no hidden state, deterministic output for equal inputs.

See docs/architecture/overview.md for the full diagram.

Dev loop

code
git clone https://github.com/sammirzaev/chart-library-open-source.git
cd chart-library-open-source
pnpm install
pnpm dev

pnpm dev runs every package in watch mode through Turborepo, plus the docs site, the EliteChart demo, and the playground. Open:

To work on a single package only:

code
pnpm --filter @elitechart/core dev
pnpm --filter @elitechart/docs dev

Test loop

code
pnpm test          # unit + integration (Vitest)
pnpm test:e2e      # Playwright cross-browser + visual regression
pnpm typecheck     # strict TS, all packages
pnpm lint          # ESLint, all packages

Coverage thresholds (enforced in CI):

  • @elitechart/core: ≥ 90%
  • @elitechart/indicators: ≥ 90%
  • All other packages: best-effort

A change that drops coverage below threshold blocks merge.

How to add a new technical-analysis indicator

ChartForge automates this with the /add-indicator slash command in the AI orchestrator. Manually, the steps are:

  1. Pick the indicator and find a citable reference (Wilder 1978, Murphy 1999, Bollinger 2002, etc.). Citations are non-negotiable for math correctness.
  2. Create the source file at packages/indicators/src/<name>.ts. Export a single pure function that returns LineOutput | MultiLineOutput. No hidden state. Use the Bar type from @elitechart/core.
  3. Add a unit test at packages/indicators/test/<name>.test.ts with at least one cited fixture (paper appendix, reference impl output, or another authoritative source). Decimal tolerance: 1e-8 unless the reference itself is approximate.
  4. Add the subpath export to packages/indicators/package.json under exports, mirroring the pattern of the existing entries.
  5. Add a docs page under apps/docs/content/<eventually-an-indicators-section>/.
  6. Add a playground example at apps/playground/fixtures/indicators/<name>.tsx.
  7. Run the math sign-offfintech-ta-expert and financial-math-expert both approve before merge.

See the add-indicator slash command for the full automation.

How to add a new drawing tool

Symmetric to indicators, but in packages/drawings/:

  1. Pick the tool (see drawing-tools-expert's charter for the prioritized backlog).
  2. Create packages/drawings/src/<name>.ts exporting a constructor that returns a DrawingPlugin (pure-function compute() plus pure paint()).
  3. Test geometry separately from rendering — geometry tests run in jsdom, paint tests run in Playwright with screenshot diff.
  4. Add the subpath export to packages/drawings/package.json.
  5. Add a docs page + playground fixture.
  6. drawing-tools-expert review before merge.

Releasing — Changesets workflow

ChartForge uses Changesets to map conventional commits to semver bumps and changelogs. Every PR that changes user-visible behavior must include a changeset:

code
pnpm changeset

The CLI prompts for:

  • Which packages changed.
  • Bump level (patch / minor / major).
  • A user-facing summary (one sentence — this lands in the changelog).

Commit the generated .changeset/*.md file alongside your code.

To cut a release:

code
pnpm release           # dry-run — version bump + build + test
pnpm release --publish # actually publish to npm

The release pipeline:

  1. changeset version — applies pending changesets, bumps package.json versions, writes CHANGELOG.md files.
  2. turbo run build — builds every package.
  3. turbo run test — runs the full test suite.
  4. changeset publish — publishes to npm with provenance.

Provenance is enforced — every published artifact has a signed attestation linking it back to the GitHub Actions run that built it.

See the release slash command for the orchestrated version.

Pull-request review

ChartForge runs every non-trivial PR through the /review-pr workflow:

  • QA-1, QA-2, QA-3 — three QA agents validate tests, coverage, performance, accessibility, SSR.
  • Relevant architectsolution-architect for plugin-API changes, financial-math-expert for math, etc.
  • Visual regression — Playwright screenshot diff in light/dark × 3 viewports.

A PR cannot merge until every reviewer signs off.

Code style

  • TypeScript strict — no any, no @ts-ignore, no @ts-expect-error without a linked issue.
  • Named exports only from library packages.
  • 400-line file cap (tests exempt).
  • Conventional Commits: feat(core): …, fix(indicators): …, perf(renderer): …, docs: …, chore: ….
  • kebab-case filenames, camelCase functions, PascalCase types/components, SCREAMING_SNAKE constants.
  • No console.log in committed code — use the logger abstraction.

The full set lives in CLAUDE.md §5.

Skills + slash commands

ChartForge ships an opinionated set of reusable skill files at .claude/skills/ — covering Canvas rendering, indicator math, OHLCV data contract, theme tokens, responsive UX, npm publishing, Next.js SSR-safety, and TypeScript strict patterns. Read the relevant one before starting a task; agents are required to.

Slash commands at .claude/commands/ drive the most common workflows:

  • /plan-feature — decompose a feature into tasks + agents.
  • /review-pr — full review trio.
  • /benchmark — perf profile vs. budget.
  • /add-indicator — scaffold a new indicator end-to-end.
  • /release — Changesets pipeline.
  • /audit-a11y — axe-core + manual a11y sweep.
  • /sync-docs — regenerate TypeDoc + playground fixtures.

ChartForge is MIT-licensed (see LICENSE). Copyright Samandar Mirzaev. Contributions are accepted under the same license.

ChartForge intentionally does not copy any code from existing proprietary trading-chart vendors. Studying competitor UX for scope and feel is fine; copying source is not.

What's next?