Installation and Project Structure
|
This content was generated with the assistance of AI and should be verified against the official documentation of each tool before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
This page was written against Docusaurus 3.10.2 (create-docusaurus 3.10.2) and checked on 2026-10-26. It scaffolds a
site for Pocket Units, a tiny units-conversion library for C# and Python, then walks through the generated project:
which folder produces which URL, what each file is for, and what the npm scripts and the docusaurus command do.
Commands and files below were run with Node.js v24.21.0 and npm 11.19.0, except where a sentence says otherwise.
What you need
A Docusaurus site is a React application that is rendered to static HTML at build time. The installation page of the
official documentation lists a single requirement: Node.js 20.0 or above (check it with node -v). Node.js 18 support
ended with Docusaurus 3.9. The generated site depends on React 19. npm ships with Node.js; Yarn, pnpm and Bun also work.
Scaffolding a site
The create-docusaurus tool creates a new directory and installs the dependencies. It can be run anywhere, in an empty
repository or inside an existing one. The usual form names the site directory and the template:
npx create-docusaurus@latest my-website classic --typescript
Source: Docusaurus docs: Installation
The arguments are, in order, the site name, the template and an optional root directory:
-
The name is used as the site path and as the
namefield of the generatedpackage.json. It may be absolute or relative to the root directory. -
The template is
classic(recommended),facebook(a Meta-specific variant), a Git repository URL starting withhttps://orgit@, or a local path whose files are copied. -
The root directory is used to resolve the site path and defaults to the current directory.
The options documented for the tool are listed below. Running npx create-docusaurus@3.10.2 --help prints the same set.
| Option | Meaning |
|---|---|
|
Use the TypeScript variant of a named template. Only |
|
Use the JavaScript variant. |
|
One of |
|
Create the files but do not install dependencies. |
|
Only for Git repository templates: |
The same site can be created with the package manager’s own initializer: npm init docusaurus, yarn create docusaurus,
pnpm create docusaurus or bunx create-docusaurus. The official page also mentions a Fast Track tutorial and an online
playground at docusaurus.new for trying the tool without installing anything.
Real output of the command above, reduced to its closing summary:
[INFO] Creating new Docusaurus project...
[INFO] Installing dependencies with npm...
[SUCCESS] Created my-website.
[INFO] Inside that directory, you can run several commands:
`npm start`
Starts the development server.
`npm run build`
Bundles your website into static files for production.
`npm run serve`
Serves the built website locally.
`npm run deploy`
Publishes the website to GitHub pages.
We recommend that you begin by typing:
`cd my-website`
`npm start`
The scaffolded site pins the Docusaurus packages to the exact release that was current when it was created and uses a caret range for React:
{
"dependencies": {
"@docusaurus/core": "3.10.2",
"@docusaurus/faster": "3.10.2",
"@docusaurus/preset-classic": "3.10.2",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.10.2",
"@docusaurus/tsconfig": "3.10.2",
"@docusaurus/types": "3.10.2",
"@types/react": "^19.0.0",
"typescript": "~6.0.2"
},
"engines": {
"node": ">=20.0"
}
}
Source: Docusaurus docs: Installation
All packages in the @docusaurus/ namespace must use the same version. The official upgrade instructions are to change
the versions in package.json, run the package manager’s install command, and check the result with
npx docusaurus --version, which prints 3.10.2 here. The @canary npm dist-tag gives access to unreleased
features. At the check date the latest tag was 3.10.2, the last release of the 3.x line, and version 4 existed only as
canary builds.
The scaffold already contains two things that older tutorials do not mention: the @docusaurus/faster package, and
future: { v4: true } in the configuration. The second is a single switch that turns on a group of flags preparing
the site for Docusaurus 4, among them the faster toolchain. The effect is visible in the dev server banner, which
reports the Rspack bundler (Rspack 1.7.12 in this run). Both are covered in
Docusaurus Faster and v4 readiness.
The generated project
The official page draws the tree of a JavaScript site. The TypeScript variant generated here has the same folders with
TypeScript and MDX files, and a few more entries. The listing shows every file, except the images in static/img, the
two screenshots in docs/tutorial-extras/img and the banner image of the welcome post:
my-website
├── blog
│ ├── 2019-05-28-first-blog-post.mdx
│ ├── 2019-05-29-long-blog-post.mdx
│ ├── 2021-08-01-mdx-blog-post.mdx
│ ├── 2021-08-26-welcome
│ │ ├── docusaurus-plushie-banner.jpeg
│ │ └── index.mdx
│ ├── authors.yml
│ └── tags.yml
├── docs
│ ├── intro.mdx
│ ├── tutorial-basics
│ │ ├── _category_.json
│ │ ├── congratulations.mdx
│ │ ├── create-a-blog-post.mdx
│ │ ├── create-a-document.mdx
│ │ ├── create-a-page.mdx
│ │ ├── deploy-your-site.mdx
│ │ └── markdown-features.mdx
│ └── tutorial-extras
│ ├── _category_.json
│ ├── img
│ ├── manage-docs-versions.mdx
│ └── translate-your-site.mdx
├── src
│ ├── components
│ │ └── HomepageFeatures
│ │ ├── index.tsx
│ │ └── styles.module.css
│ ├── css
│ │ └── custom.css
│ └── pages
│ ├── index.module.css
│ ├── index.tsx
│ └── markdown-page.mdx
├── static
│ ├── .nojekyll
│ └── img
├── .gitignore
├── README.md
├── docusaurus.config.ts
├── package-lock.json
├── package.json
├── sidebars.ts
└── tsconfig.json
Each entry has a role, summarised here and detailed in the pages named in the last column.
| Path | Purpose | More |
|---|---|---|
|
Blog posts, one Markdown or MDX file or one folder with an |
|
|
The documentation. Folders become sidebar categories, files become pages. A |
|
|
Everything that is not documentation: React pages, custom components and CSS. The location is a convention, not a requirement. |
|
|
Any JSX, TSX, Markdown or MDX file here becomes a standalone page. The classic template ships |
|
|
React components shared by pages. The template has one, |
|
|
Global styles. It is loaded because the preset option |
|
|
Copied unchanged to the root of the build output. The template adds |
|
|
The site configuration: metadata, |
|
|
The order and grouping of documents in the sidebars. |
|
|
Dependencies and scripts. A Docusaurus site is an ordinary React application, so any npm package can be added. |
This page |
|
TypeScript settings that extend |
|
|
Ignores |
This page |
Folders that appear later and are not part of the scaffold are i18n/ (translations, created by write-translations or
by hand), versioned_docs/, versioned_sidebars/ and versions.json (created by docs:version), and the generated
.docusaurus/ and build/ directories.
From folders to URLs
The plugins of the classic preset turn the folders into routes. The generated site maps as follows:
Figure: folders of the scaffolded project and the routes they produce.
The documentation page on the docs feature gives the same mapping for a fresh site: docs are served under /docs, and
blog posts under /blog with the date in the URL unless a slug is set. The three sample posts of the template set a
slug in their front matter (for example slug: first-blog-post), so they are served at /blog/first-blog-post,
/blog/long-blog-post, /blog/mdx-blog-post and /blog/welcome. Setting the docs option routeBasePath to / serves the documentation at the site root ("docs-only
mode"); the blog can be turned off with blog: false in the preset options. Both are shown in
Configuration.
Scripts and the docusaurus command
The scaffold defines these scripts in package.json, each calling the docusaurus binary:
{
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"build": "docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc"
}
}
Source: Docusaurus docs: CLI
The typecheck script exists only in the TypeScript variant. npx docusaurus --help lists, besides the scripts above, the
command docs:version <version>, which tags a new documentation version. Options of each command, as printed by
--help in 3.10.2:
| Command | What it does | Options |
|---|---|---|
|
Starts the development server with hot reloading. The default address is http://localhost:3000. |
|
|
Produces the static site in |
|
|
Serves an existing build locally to check it before publishing. |
|
|
Builds and pushes to the GitHub Pages branch. Deployment is covered in a separate page. |
|
|
Copies or wraps a theme component for customization. |
|
|
Removes generated assets, caches and build artifacts. |
none |
|
Writes the JSON translation files for the default or a given locale. |
|
|
Adds explicit heading IDs to Markdown files. |
|
Source: Docusaurus docs: CLI
To pass an option through npm, separate it with two dashes, as the official page does for the host option:
npm run start -- --host 0.0.0.0
Source: Docusaurus docs: CLI
Not every feature works the same in development: the official page notes that some functionality, anchor links among
it, only works in the production build. A development-mode production bundle with full React error messages is
available with docusaurus build --dev.
Running, building and checking the site
From the site directory, npm start opens a browser on port 3000. Running it with --no-open and a different port
printed the following:
[INFO] Starting the development server...
[SUCCESS] Docusaurus website is running at: http://localhost:3124/
client (Rspack 1.7.12) compiled successfully
The production build and its output:
npm run typecheck
npm run build
> my-website@0.0.0 build
> docusaurus build
[INFO] [en] Creating an optimized production build...
[SUCCESS] Generated static files in "build".
[INFO] Use `npm run serve` command to test your build locally.
The result is a folder of static files that any static hosting service can serve. For the scaffold it contains
404.html, index.html, sitemap.xml, an assets/ folder with hashed JavaScript and CSS, and one folder per route
group: docs/, blog/, markdown-page/ and img/. npm run serve -- --no-open -p 3123 served the build, and both
the pages and files from static/ answered with status 200.
Adding Pocket Units content
The Pocket Units documentation fits the scaffold without changing any configuration. The commands and files below add a docs category, one blog post, a standalone page and a static download to a copy of the generated site.
{
"label": "Pocket Units",
"position": 3,
"link": {
"type": "generated-index",
"description": "A tiny units-conversion library for C# and Python."
}
}
---
sidebar_position: 1
title: Overview
---
# Pocket Units
Pocket Units converts lengths between metres, feet and inches. It ships as a C# package and a Python package.
```python
from pocket_units import convert
print(convert(1.0, "m", "ft"))
```
---
sidebar_position: 2
---
# Installation
Install the Python package with `pip install pocket-units`.
---
title: Pocket Units is released
authors: [alberto]
tags: [release]
---
The first release of Pocket Units is available.
{/* truncate */}
It converts lengths between metres, feet and inches.
---
title: About Pocket Units
---
# About
Pocket Units is a small demonstration library.
The blog post refers to an author and a tag that must be defined in blog/authors.yml and blog/tags.yml. Because the
scaffold sets onInlineAuthors and onInlineTags to warn, an author or tag that is not declared in those files is
reported at build time. The two entries appended to the generated files were:
# blog/authors.yml
alberto:
name: Alberto
title: Maintainer
url: https://example.com
# blog/tags.yml
release:
label: Release
permalink: /release
description: Release announcements
Finally, a file at static/files/units.csv (the single line metre,foot,inch) becomes available at /files/units.csv.
The next build succeeded and produced these routes among the routes of the site, as listed in build/sitemap.xml:
/about
/blog/2026/10/26/pocket-units-released
/blog/tags/release
/docs/category/pocket-units
/docs/pocket-units/installation
/docs/pocket-units/overview
Note how the blog URL (the post sets no slug) takes its date from the folder name, how the docs URLs follow the folder names while the sidebar
order follows sidebar_position and the category position, and how the generated-index link type created the
extra page /docs/category/pocket-units.
Pitfalls and version notes
-
Markdown files are compiled as MDX. With the scaffolded configuration, an HTML comment fails the build. The blog post above written with the older truncate marker (an HTML comment) stopped the build with "Client bundle compiled with errors" and the cause "Unexpected character
!(U+0021) before name", followed by a hint to use the JSX comment form. Write the marker as{/* truncate */}in new content. The migration guide lists HTML comments as syntax that is being phased out. -
Explicit heading IDs. By default
npx docusaurus write-heading-idswrites IDs in the classic form{#getting-started}. In the scaffolded site (which hasfuture: { v4: true }) running it over the whole site and then building failed with "Could not parse expression with acorn" in every changed MDX file. The command also accepts--syntax mdx-comment, which writes{/* #getting-started */}; a heading written that way built correctly and produced the expected anchor. The first positional argument of the command is the site directory, so a file list needsnpx docusaurus write-heading-ids . docs/intro.mdx --syntax mdx-comment; passing a file as the first argument fails with "No config file found in site dir". -
Broken Markdown links fail the build. Adding a link to a missing file produced the warning "Markdown link with URL
./nope.md… couldn’t be resolved" and then an error "Docusaurus found broken links!", because the scaffold setsonBrokenLinks: 'throw'. Setting that option towarnlets the build pass. -
Placeholder metadata. The scaffold uses
https://your-docusaurus-site.example.comas the siteurlandfacebook/docusaurusas organization and project, and itseditUrlvalues point at the Docusaurus repository. Replace them before publishing. The sitemap in the example above still contains the placeholder address. -
Clear after upgrades. The documentation recommends
npm run clearbefore reporting a bug, after upgrading versions, or whenever the site misbehaves. In this run it removed.docusaurus, the bundler cache innode_modules/.cacheandbuild. -
The package manager. The generated lockfile depends on the manager that created the site. The official tree shows a Yarn lockfile; here, with npm, it is
package-lock.json. -
Monorepos. When the documentation lives next to an existing project, run
npx create-docusaurusin the monorepo root. On hosts such as Netlify or Vercel set the base directory to the folder that holds the site (for examplewebsite/). The official page describes this layout but this page did not build one. -
Dropped and added versions. Node.js 18 was dropped in 3.9; the minimum is Node.js 20. React 19 is the generated default. Version 4 has not been released; the scaffold’s
future.v4flag is the preparation for it.