A CLAUDE.md is just a markdown file at the root of your repo. Copy the content below into your own project's CLAUDE.md to give your agent the same context.
npx versuz@latest install formatjs-formatjs --kind=claude-mdcurl -o CLAUDE.md https://raw.githubusercontent.com/formatjs/formatjs/HEAD/CLAUDE.md# Instructions for Claude Code
## Knowledge Base
For detailed architecture docs, package dependency hierarchies, CLDR data pipelines, and design decisions, consult @knowledge-base/. Key docs:
- @knowledge-base/001-repo-layout.md — Directory structure, pnpm, linting, CI/CD, common commands
- @knowledge-base/001a-bazel-toolchain.md — Bazel setup, TypeScript/Rust build pipeline, custom macros, tsconfig strategy, composite sub-packages
- @knowledge-base/002-ts-package-dependency-hierarchy.md — 5-layer TypeScript package dependency graph
- @knowledge-base/003-rust-crate-dependency-hierarchy.md — Rust crates, WASM, cross-language connections
- @knowledge-base/004-009 — Per-package design decisions and ECMA-402 conformance details
- @knowledge-base/007a-007k — Individual polyfill CLDR data pipelines
- @knowledge-base/migrations/ — Migration plans (e.g., gazelle migration)
## Critical Rules
### 1. NEVER Run `bazel clean`
- **NEVER** run `bazel clean` or `bazel clean --expunge`
- Destroys build cache, 10+ minute rebuild penalty
- Use specific targets instead: `bazel build //path/to:target`
### 2. Always Use Bazel
This repository uses Bazel as its build system. Never use `npm`, `yarn`, or `pnpm` for building or testing.
```bash
bazel test //... # All tests
bazel test //packages/intl-localematcher:unit_test # Specific package
bazel build //packages/intl-localematcher:dist # Build package
bazel test <target> --test_output=all # Verbose output
bazel query 'kind(test, //packages/...)' # Query test targets
```
### 3. Rust Benchmarks Need `-c opt`
Always use `bazel run -c opt` for Rust benchmarks. Debug mode is ~10x slower.
```bash
bazel run -c opt //crates/icu_messageformat_parser:comparison_bench
```
### 4. No Barrel Exports for Internal Packages
- **Do NOT use barrel `index.ts` files** for internal packages (e.g., `ecma402-abstract`)
- Use deep imports with `.js` extensions: `import {GetOption} from '#packages/ecma402-abstract/GetOption.js'`
- Barrel re-exports are only allowed for **public-facing packages** (e.g., `react-intl`, `intl-messageformat`)
- `ecma402-abstract` is **not published to npm** — no `package.json`. It is imported via `#packages/ecma402-abstract/` (Node.js subpath imports defined in root `package.json`)
- `ecma402-abstract` is split into 3 composite Bazel sub-packages: root, `types/`, `NumberFormat/`
- For new composite sub-packages: use `generate_ide_tsconfig_json(composite = True, project_references = [...])`
- Child Bazel sub-packages are auto-excluded from the parent tsconfig via `native.subpackages()` — no manual exclude needed
- `ast-grep` enforces no-barrel-export rule via `sg-rules/no-barrel-export.yml`
### 5. Polyfill Development
- Cross-check with the [LDML spec](https://unicode.org/reports/tr35/) and [ICU4J](https://unicode-org.github.io/icu-docs/apidoc/released/icu4j/) source
- Each polyfill follows ECMA-402 strictly
- Data is tree-shakeable — locale data is separately importable
- See @knowledge-base/007*.md for per-polyfill CLDR pipeline details
### 6. Commit Message Format
[Conventional Commits](https://www.conventionalcommits.org/) — enforced by commitlint.
```
<type>(<scope>): <subject>
```
**Types:** `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`
**Scope:** Full package name from package.json (e.g., `@formatjs/cli`, `@formatjs/intl-localematcher`), Rust crate name (e.g., `formatjs_cli`), or `deps` for repo-wide/internal changes. Note: `@formatjs/ecma402-abstract` is not a valid scope (no package.json).
**Breaking changes:** Append `!` after scope or add `BREAKING CHANGE:` footer.
## Quick Reference
- **Packages**: `packages/` (33 npm packages)
- **Rust crates**: `crates/` (3 crates: CLI, parser, skeleton parser)
- **Custom Bazel macros**: `tools/` (ts_compile, vitest, oxc_transpiler, etc.)
- **Conformance tests**: `bazel test //packages/cli/integration-tests:conformance_test`
- **Rust CLI tests**: `bazel test //crates/formatjs_cli:formatjs_cli_test` (176 tests)
- **Rust CLI conformance**: 60/60 passing (packages/cli/integration-tests/conformance-tests/)