Open-source project
reactjs/react.dev avatar
reactjs/react.dev

Running react.dev locally: markdown under src/content and a check-all that rewrites your files

The React documentation website

11,834 stars7,977 forksJavaScriptCC-BY-4.0

At a glance

What is it?
react.dev is the source of the React documentation website, a Next.js app whose prose is markdown under ./src/content and whose examples run in Sandpack. Contributors get hot reload and a check-all that rewrites their tree, and nothing that installs as a package.
Who is it for?
Read this repository when you are writing or reviewing React's own documentation, since nothing inside it turns into a reusable docs tool. Teams that need per version output or an installable plugin system should look at a generator instead.
Can I use it commercially?
Yes, with credit. CC-BY-4.0 allows commercial use as long as you credit the authors and indicate what you changed. It is written for creative content, so check how it applies to any code.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • reactjs/react.dev11,834 ★ · +30
Star history
Repository2026-09-222026-11-14
reactjs/react.dev11.8k11.8k

30 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The prose is markdown under ./src/content and the dev server watches it

react.dev is not a library you install. It is the source of the React documentation website, and the repository is a Next.js application: pages and components live in src, prose lives as markdown files under ./src/content, and the dev script points a remote watcher straight at that directory.

json
"dev": "next-remote-watch ./src/content"

Content pages get their own lint pass, separate from component code:

json
"lint": "next lint && eslint \"src/content/**/*.md\""

Two passes with two tools. next lint covers the JavaScript and TypeScript under src, and the second invocation runs ESLint over markdown files, which is the reason the root carries .eslintrc and .eslintignore next to .prettierrc. The runtime dependencies describe what a reader actually gets: @docsearch/react ^3.8.3 for site search, @radix-ui/react-context-menu ^2.1.5 for context menus, and @codesandbox/sandpack-react pinned to exactly 2.13.5 for the examples you can edit inside the page. Styling goes through tailwind.config.js and postcss.config.js, and vercel.json sits at the root for hosting.

Five prerequisites, and one of them is a fork

The prerequisite list names five things, and one of them is a fork of the repo, which tells you what this repository is for. Git, Yarn, and any Node version starting with v16.8.0 or greater, plus a clone of react.dev on your machine. No binary gets downloaded anywhere in the process.

bash
cd react.dev
yarn

Yarn reads the committed yarn.lock, so a fresh clone installs pinned versions instead of whatever matches today. The root also holds two dotfiles, .env.development and .env.production, whose contents the README does not describe.

Then the site comes up:

bash
yarn dev
open http://localhost:3000

Next.js serves it on port 3000, and that port is the only one this repository names.

check-all rewrites your tree, ci-check only reports

Before you push, the contribution flow asks for one command.

bash
yarn check-all

What it expands to decides whether your diff survives review:

json
"check-all": "npm-run-all prettier lint:fix tsc rss",
"ci-check": "npm-run-all prettier:diff --parallel lint test:eslint-local-rules tsc lint-heading-ids rss deadlinks"

check-all is not a checker. The prettier script it runs is format:source, which writes files, and lint:fix ends in eslint --fix over the markdown tree. Your working tree changes while the command runs, and the push step stages everything with git add -A, so an unrelated reformat lands in the same commit as your edit. ci-check is the read-only shape: prettier:diff only lists differences, and it adds three tasks check-all never runs, the heading anchor linter at scripts/headingIdLinter.js, the eslint-local-rules test suite, and the dead link checker at scripts/deadLinkChecker.js.

Plugin edits need .cache deleted before the server shows them

Hot reload covers two paths, components in src and markdown files in content. Plugins sit outside both, and the failure is quiet: a plugin edit stays invisible until you delete the .cache directory and restart the server. A contributor can lose an afternoon editing a file the running process never reads again.

Git hooks arrive through the same install step, and that step checks where it is running:

json
"postinstall": "yarn --cwd eslint-local-rules install && is-ci || husky install .husky"

is-ci short-circuits husky install .husky whenever the environment reports itself as CI. Inside a container or CI image that sets CI, your local commit hooks are never installed, and yarn finishes without ever saying the hook step was skipped. Nothing else in the root layout tells you the hooks are missing.

Fonts and OG images arrive after next build, not before

The production build is four commands in a fixed order.

json
"prebuild:rsc": "node scripts/buildRscWorker.mjs",
"build": "node scripts/buildRscWorker.mjs && next build && node --experimental-modules ./scripts/downloadFonts.mjs && node ./scripts/generateOgImages.mjs"

The build script begins with the same worker script that prebuild:rsc runs. Font download and OG image generation come after next build, which means your pages are already compiled before either network step starts.

That ordering decides how a build fails. A machine that cannot reach a font host ends up with compiled pages, no downloaded fonts and no social images, rather than an early error you could read before waiting out the compile. The --experimental-modules flag is also passed by hand to the font script, so that step is tied to a Node release that accepts the flag, a narrower constraint than the v16.8.0 floor stated for contributors.

private: true and no releases leave nothing to install

package.json marks the project "private": true at "version": "1.0.0", and the repository has no GitHub releases. There is no react.dev version to depend on and no tarball to fetch, which leaves main as the only moving target a contributor tracks:

bash
git checkout main
git pull origin main
git checkout -b the-name-of-my-branch

Dependency ranges differ inside that one file. @codesandbox/sandpack-react sits at 2.13.5 with no caret, so the code sandbox cannot move under a docs page until somebody edits package.json by hand. @headlessui/react is ^1.7.0 and @docsearch/react is ^3.8.3, free to float inside their major versions, and yarn.lock settles the rest in practice. Nothing here explains how to refresh that lockfile, so a dependency bump stays a manual step. The last push to the repository was 2026-10-27.

Content carries CC-BY-4.0, the site code carries no stated licence

Two licence facts live in different files. package.json carries "license": "CC", and LICENSE-DOCS.md holds the terms for content submitted to react.dev, CC-BY-4.0.

For anyone planning to reuse the prose, CC-BY-4.0 is an attribution obligation and LICENSE-DOCS.md is where it is recorded, so read that file before republishing a tutorial page. For anyone planning to reuse the site itself, the picture is thinner: no licence is stated for src, scripts or plugins, and "private": true in package.json only blocks publishing, it grants nothing. That is a gap in the documentation rather than a permission, so the answer belongs to the maintainers.

Translations follow one tracked issue instead of a per locale directory scheme. Contributors who want to translate react.dev are sent to issue 4135 for current translation efforts, which means a new language starts with coordination, not with a directory you can create yourself.

Markdown plus Sandpack where Docusaurus would give MDX and versions

Pages are markdown with React components around them, and the runnable examples come from @codesandbox/sandpack-react at 2.13.5, pinned to an exact version. Teams who want a docs tool usually reach for a generator such as Docusaurus, which reads MDX so a component can live in the same file as the prose, and which treats versioning and extra plugins as packages to add.

react.dev is the other shape. You get one site owned end to end, with markdown under ./src/content, Tailwind for styling, and a check chain written for this repository alone. What you do not get is a generator: nothing here emits docs sites for other projects, and there is no API for adding a page type or a syntax without editing src yourself. Teams that need per version output should stay with a generator. Teams editing React's own pages are the audience this repository was built for.

Editorial conclusion

Read this repository when you are writing or reviewing React's own documentation, since nothing inside it turns into a reusable docs tool. Teams that need per version output or an installable plugin system should look at a generator instead. Before your first commit, run yarn check-all and read the diff it produces, because it edits your files rather than only reporting on them.

Frequently asked questions

What is react.dev?

It is the React documentation website, and the reactjs/react.dev repository holds the source code and documentation behind it. Locally it is a Next.js app you start with yarn dev and open at http://localhost:3000.

How do I run the react.dev documentation site on my own machine?

Clone the repository, install Git, Yarn and any Node version starting with v16.8.0 or greater, then run yarn in the project root. Start the server with yarn dev and open http://localhost:3000 in a browser.

What does yarn check-all do before a react.dev commit?

It runs npm-run-all prettier lint:fix tsc rss, which rewrites files through Prettier and the ESLint fixers, type checks with tsc, and regenerates RSS with scripts/generateRss.js. Because it writes to your tree, stage only the edits you meant to make.

Why do my react.dev plugin changes not show up in the browser?

Hot reload covers components in src and markdown in content, and plugin work may need the .cache directory removed and the server restarted. Without that step the running server keeps serving the earlier build, so the edit looks ignored.

Can I reuse react.dev documentation content in another project?

Content submitted to react.dev is CC-BY-4.0 licensed, as recorded in LICENSE-DOCS.md. No licence is stated for the site code in src or scripts, so check with the maintainers before reusing either.

Official sources

  1. Issues
  2. License: CC-BY-4.0
  3. Project website
  4. reactjs/react.dev on GitHub
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/reactjs-react-dev.svg)](https://hysenlabs.com/projects/reactjs-react-dev)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/reactjs-react-dev.svg)](https://hysenlabs.com/projects/reactjs-react-dev)

Was this useful?