Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project overview

Arbitrum Docs — a Docusaurus 3.6.3 site serving technical documentation at docs.arbitrum.io. The repo contains 450+ MDX docs organized by audience (developers, node operators, chain builders, users) plus React components, build scripts, and two git submodules (arbitrum-sdk, stylus-by-example).

## Commands

```bash
# Install dependencies
yarn

# Initialize submodules (required for first setup)
git submodule update --init --recursive

# Development server
yarn start

# Production build (installs SDK deps, syncs stylus content, then builds)
yarn build

# Serve production build locally
yarn serve

# Format all files (docs + app code)
yarn format

# Check formatting only
yarn format:check

# Lint markdown (excludes docs/sdk/)
yarn lint:markdown
yarn lint:markdown:fix

# TypeScript type checking
yarn typecheck

# Generate SDK docs from submodule source
yarn generate-sdk-docs

# Build glossary from partial files
npx tsx scripts/build-glossary.ts

# Generate doc manifest (scans all docs into .audit/doc-manifest.json)
yarn generate-doc-manifest

# Run doc audit (generates manifest then audits)
yarn audit-docs

# Update variable references in docs after changing globalVars.js
yarn update-variable-refs

# Generate precompile reference tables
yarn generate-precompiles-ref-tables
```

Node >= 22.0.0 is required. Yarn is the package manager.

## Validation workflow

**IMPORTANT**: `yarn build` is slow (~30-40s). Use faster commands for iteration:

```bash
# Quick validation (1-2 seconds) - use this for most checks
yarn lint:markdown && yarn format:check

# Dev server with hot reload (10-15s initial, then instant updates)
yarn start

# Full production build (slow, only use before committing)
yarn build
```

**Recommended workflow when making doc changes:**

1. Make changes to MDX files
2. Run quick validation: `yarn lint:markdown && yarn format:check`
3. If you need to verify links/sidebar structure, use `yarn start` (has hot reload)
4. Only run `yarn build` as final verification before committing

Common issues caught by each:

- `lint:markdown` - Markdown syntax errors, formatting issues
- `format:check` - Code/doc formatting problems
- `start` - Broken links, missing sidebar docs, MDX compilation errors
- `build` - Everything above + production-specific issues

## Architecture

### Content organization

- `docs/` — MDX documentation files organized by section (build-decentralized-apps, stylus, how-arbitrum-works, run-arbitrum-node, launch-arbitrum-chain, etc.)
- `docs/partials/` — Reusable content fragments; filenames start with `_` (Docusaurus strips their frontmatter automatically via `docusaurus.config.js` `parseFrontMatter`)
- `docs/sdk/` — **Auto-generated** from TypeDoc; do not edit manually
- `docs/stylus-by-example/` — **Auto-generated** from submodule; do not edit manually
- `docs/partials/glossary/` — Glossary term files with specific frontmatter format (`title`, `key`, `titleforSort`)

### Doc frontmatter

Documents use frontmatter with fields: `title`, `description`, `sidebar_label`, `sidebar_position`, `content_type` (quickstart | how-to | concept | reference | faq | gentle-introduction | troubleshooting), `author`, `sme`.

### Application code

- `src/components/` — React components used within docs (ImageZoom, InteractiveDiagrams, Quicklooks, etc.)
- `src/resources/globalVars.js` — Chain-specific parameters (docker images, RPC endpoints, contract addresses, block times). After modifying, run `yarn update-variable-refs` to propagate changes into docs.
- `src/resources/precompilesInformation.js` — Precompile metadata
- `src/theme/` — Docusaurus theme overrides
- `src/css/custom.scss` — Global styles

### Navigation

`sidebars.js` (1600+ lines) defines all sidebar navigation. There are 8+ sidebars: getStartedSidebar, buildAppsSidebar, stylusSidebar, runArbitrumChainSidebar, runNodeSidebar, bridgeSidebar, howItWorksSidebar, noticeSidebar.

### Build pipeline

- `docusaurus.config.js` — Main config; uses a custom markdown preprocessor (`scripts/markdown-preprocessor.js`), remark-math/rehype-katex for LaTeX, Mermaid diagrams, and TypeDoc plugin for SDK generation
- Docusaurus routes docs at `/` (not `/docs/`)
- Broken links and broken markdown links both configured to `throw` (build fails on broken links)
- Vercel deployment with extensive URL redirects in `vercel.json`

### Submodules

- `submodules/arbitrum-sdk/` — TypeScript SDK source; TypeDoc generates `docs/sdk/` from this
- `submodules/stylus-by-example/` — Stylus examples; synced via `yarn sync-stylus-content`

### Scripts

`scripts/` contains tooling for content generation and maintenance:

- `generate-doc-manifest.ts` — Scans all docs, outputs compact JSON manifest to `.audit/doc-manifest.json`
- `audit-docs.ts` — Documentation quality auditing
- `sync-stylus-content.js` — Copies content from stylus-by-example submodule
- `build-glossary.ts` — Generates glossary page from `docs/partials/glossary/_*.mdx` files
- `precompile-reference-generator.ts` — Generates precompile reference tables
- `update-variable-references.ts` — Propagates globalVars.js values into docs
- `markdown-preprocessor.js` — Custom MDX preprocessing for Docusaurus

## Style conventions

- Sentence-case for titles, headers, sidebar labels
- Address reader as "you"; informal professional tone
- Descriptive link text (avoid "click here")
- Prettier formatting via `@offchainlabs/prettier-config`; MDX files use mdx parser
- Markdown linting via markdownlint with many rules relaxed (see `.markdownlint.json`)
- Prism syntax highlighting supports: solidity, rust, bash, toml (in addition to defaults)
2 changes: 1 addition & 1 deletion docs/build-decentralized-apps/03-public-chains.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ chains, their differences, and the technology stacks that these chains use.

### Arbitrum One

**Arbitrum One** is a child chain Optimistic Rollup chain that implements the <a data-quicklook-from="arbitrum-rollup-protocol">Arbitrum Rollup Protocol</a> and settles to Ethereum's <a data-quicklook-from="parent-chain">Parent chain</a>. It lets you build high-performance Ethereum dApps with low transaction costs and Ethereum-grade security guarantees, introducing no additional trust assumptions. This is made possible by the [Nitro](/how-arbitrum-works/deep-dives/geth.mdx) technology stack, a "Geth-at-the-core" architecture that gives Arbitrum One (and Nova) advanced calldata compression, separate contexts for common execution and fault proving, Ethereum parent chain gas compatibility, and more.
**Arbitrum One** is a child chain Optimistic Rollup chain that implements the <a data-quicklook-from="arbitrum-rollup-protocol">Arbitrum Rollup Protocol</a> and settles to Ethereum's <a data-quicklook-from="parent-chain">Parent chain</a>. It lets you build high-performance Ethereum dApps with low transaction costs and Ethereum-grade security guarantees, introducing no additional trust assumptions. This is made possible by the [Nitro](/how-arbitrum-works/reference/geth.mdx) technology stack, a "Geth-at-the-core" architecture that gives Arbitrum One (and Nova) advanced calldata compression, separate contexts for common execution and fault proving, Ethereum parent chain gas compatibility, and more.

### Arbitrum Nova

Expand Down
16 changes: 8 additions & 8 deletions docs/build-decentralized-apps/04-cross-chain-messaging.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ The Arbitrum protocol and related tooling makes it easy for developers to build

## Ethereum-to-Arbitrum messaging

Arbitrary parent to child chain contract calls can be created via the Inbox's `createRetryableTicket` method; upon publishing the parent chain transaction, the child chain side will typically get included within minutes. Commonly, the child chain execution will automatically succeed, but if reverts, and it can be rexecuted via a call to the `redeem` method of the [`ArbRetryableTx`](/build-decentralized-apps/precompiles/02-reference.mdx#arbretryabletx) precompile.
Arbitrary parent to child chain contract calls can be created via the Inbox's `createRetryableTicket` method; upon publishing the parent chain transaction, the child chain side will typically get included within minutes. Commonly, the child chain execution will automatically succeed, but if it reverts, it can be rexecuted via a call to the `redeem` method of the [`ArbRetryableTx`](/build-decentralized-apps/precompiles/02-reference.mdx#arbretryabletx) precompile.

For details and protocol specification, see [Parent to child chain messages](/how-arbitrum-works/deep-dives/l1-to-l2-messaging.mdx).

For an example of retryable tickets in action, see the [`Greeter`](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/greeter) tutorial, which uses the [Arbitrum SDK](../../sdk).
- **How-to guide**: [How to bridge from parent chain to child chain](/build-decentralized-apps/how-to-bridge-from-parent-chain.mdx)
- **Protocol details**: [Parent to child chain messaging](/how-arbitrum-works/deep-dives/l1-to-l2-messaging.mdx)
- **Example**: [`Greeter` tutorial](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/greeter) using the [Arbitrum SDK](../../sdk)

## Arbitrum-to-Ethereum messaging

Similarly, child chain contracts can send Arbitrary messages for execution on the parent chain. These are initiated via calls to the [`ArbSys`](/build-decentralized-apps/precompiles/02-reference.mdx#arbsys) precompile contract's `sendTxToL1` method. Upon confirmation (about one week later), they can execute by retrieving the relevant data via a call to `NodeInterface` contract's `constructOutboxProof` method, and then executing them via the `Outbox`'s `executeTransaction` method.

For details and protocol specification, see [Child to parent chain messages](/how-arbitrum-works/deep-dives/l2-to-l1-messaging.mdx).
Similarly, child chain contracts can send arbitrary messages for execution on the parent chain. These are initiated via calls to the [`ArbSys`](/build-decentralized-apps/precompiles/02-reference.mdx#arbsys) precompile contract's `sendTxToL1` method. Upon confirmation (about one week later), they can be executed by retrieving the relevant data via a call to the `NodeInterface` contract's `constructOutboxProof` method, and then executing them via the `Outbox`'s `executeTransaction` method.

For a demo, see the [Outbox Tutorial](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/outbox-execute).
- **How-to guide**: [How to bridge to parent chain from child chain](/build-decentralized-apps/how-to-bridge-to-parent-chain.mdx)
- **Protocol details**: [Child to parent chain messaging](/how-arbitrum-works/deep-dives/l2-to-l1-messaging.mdx)
- **Example**: [Outbox Tutorial](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/outbox-execute)
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ When calling [`eth_getTransactionByHash`](https://ethereum.org/en/developers/doc

### Transaction types

In addition to the [three transaction types](https://ethereum.org/en/developers/docs/transactions/#types-of-transactions) currently supported on Ethereum, Arbitrum adds additional types listed below and [documented in full detail here](/how-arbitrum-works/deep-dives/geth.mdx#transaction-types).
In addition to the [three transaction types](https://ethereum.org/en/developers/docs/transactions/#types-of-transactions) currently supported on Ethereum, Arbitrum adds additional types listed below and [documented in full detail here](/how-arbitrum-works/reference/geth.mdx#transaction-types).

On RPC calls that return transactions, the `type` field will reflect the custom codes where applicable.

Expand Down
2 changes: 1 addition & 1 deletion docs/build-decentralized-apps/custom-gas-token-sdk.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ You should use `EthBridger` when bridging the native token between the parent ch

### Registering a custom token in the Token Bridge

When [registering a custom token in the Token Bridge](/build-decentralized-apps/token-bridging/03-token-bridge-erc20.mdx#setting-up-your-token-with-the-generic-custom-gateway) of a custom-gas-token Arbitrum chain, there's an additional step to perform before calling `registerTokenToL2`.
When [registering a custom token in the Token Bridge](/how-arbitrum-works/deep-dives/token-bridging.mdx#setting-up-your-token-with-the-generic-custom-gateway) of a custom-gas-token Arbitrum chain, there's an additional step to perform before calling `registerTokenToL2`.

Since the Token Bridge [router](https://github.com/OffchainLabs/token-bridge-contracts/blob/main/contracts/tokenbridge/ethereum/gateway/L1OrbitGatewayRouter.sol#L142-L144) and the [generic-custom gateway](https://github.com/OffchainLabs/token-bridge-contracts/blob/main/contracts/tokenbridge/ethereum/gateway/L1OrbitCustomGateway.sol#L203-L210) expect to have allowance to transfer the native token from the `msg.sender()` to the inbox contract, it's usually the token in the parent chain who handles those approvals. In the [TestCustomTokenL1](https://github.com/OffchainLabs/token-bridge-contracts/blob/main/contracts/tokenbridge/test/TestCustomTokenL1.sol#L158-L168), we offer as an example of implementation. We see that the contract transfers the native tokens to itself and then approves the router and gateway contracts. If we follow that implementation, we only need to send an approval transaction to the native token to allow the `TestCustomTokenL1` to transfer the native token from the caller of the `registerTokenToL2` function to itself.

Expand Down
Loading
Loading