A ground-up rebuild of the NATS documentation, built with
Docusaurus. It reorganizes the docs around
Diátaxis: Core Concepts, hands-on Tutorials, long-form
Learn deep dives, and per-version generated Reference (from nats-server and
jsm.go source), plus interactive message-flow animations and multi-language
code examples pulled from the client repositories.
What is this repository?
- A rebuilt NATS documentation site
- Written in Markdown/MDX with React components
- Reference docs generated per NATS version from upstream source
- Builds to a static site (
npm run build) servable by any static host
For new contributors:
- 📝 Editing docs? See Common Tasks
- 💻 Adding code examples? See Contributing
- 🔧 Technical deep dive? See Development
- ❓ Having issues? See Troubleshooting
- Node.js 18 or higher
- npm 8 or higher (comes with Node.js)
- Clone this repository:
git clone https://github.com/nats-io/nats.docs.v2.git
cd nats.docs.v2- Install dependencies:
npm install- Start the development server:
npm start- Open your browser to http://localhost:3000
The dev server supports hot reloading - most changes are reflected immediately without restarting.
To create a production build:
npm run buildThis generates static content in the build/ directory that can be served by any static hosting service.
Documentation pages are located in the docs/ directory and written in Markdown (.md) or MDX (.mdx).
To edit an existing page:
- Find the file in
docs/(e.g.,docs/concepts/getting-started/index.md) - Make your changes
- Save the file - changes appear immediately in your browser (hot reload)
- Commit and push your changes
Example file locations:
- Getting Started:
docs/concepts/getting-started/index.md - Concepts:
docs/concepts/*.md - Learn deep dives:
learn/<chapter>/*.md(own docs instance, served at/learn) - Tutorials:
tutorials/*.md(own docs instance, served at/tutorials) - Reference:
reference_versioned_docs/version-<ver>/**(generated — do not hand-edit; fix the generators undertools/config-generatorandscripts/instead)
Note: The docs/ directory maps to the root URL path /. For example:
docs/concepts/getting-started/index.md→http://localhost:3000/concepts/getting-starteddocs/concepts/publish-subscribe.md→http://localhost:3000/concepts/publish-subscribe
Where do code examples live?
-
Programming language examples (Go, Rust, JavaScript, Python, Java, C#): Always in their respective client repositories
- Go →
nats.gorepository - Rust →
nats.rsrepository - JavaScript/TypeScript →
nats.jsrepository - Java →
nats.javarepository
- Go →
-
CLI-only examples: In this documentation repository
- Location:
static/examples/snippets/cli/[page]/[snippet].sh - Only use this for examples that have no programming language equivalents
- Location:
Two ways to add examples:
Option 1: Inline examples (for unique, one-off snippets)
Use Docusaurus tabs directly in your MDX file:
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
<Tabs groupId="lang">
<TabItem value="cli" label="CLI" default>
\`\`\`bash
nats pub hello "Hello NATS!"
\`\`\`
</TabItem>
<TabItem value="go" label="Go">
\`\`\`go
nc.Publish("hello", []byte("Hello NATS!"))
\`\`\`
</TabItem>
</Tabs>Option 2: Multi-repository examples (for reusable, tested code - PREFERRED)
See the Adding Code Examples section in Contributing below.
Before committing, run TypeScript type checking:
npm run typechecknpm start # Start dev server (http://localhost:3000)
npm run build # Build production site
npm run typecheck # Run TypeScript type checking
npm run fetch-examples # Fetch code examples from GitHub repos
npm run generate-docs:all-versions # Generate per-version reference docs (nats-server + jsm.go)
npm run serve # Serve production build locally
npm run clear # Clear Docusaurus cachenpm run build produces a fully static site in build/ that any static host
can serve. No CI deployment pipeline is wired up in this repository yet.
For GitHub Pages, Docusaurus's built-in deploy command works:
USE_SSH=true npm run deploy
# or
GIT_USER=<Your GitHub username> npm run deployReference documentation is generated per NATS version from upstream source code. Each version checks out matching tags of both nats-server and jsm.go submodules (tag mapping in scripts/doc-versions.json), parses errors/headers/monitor schemas, vendors JSON schemas, and writes a version-scoped doc tree.
What gets generated (per version):
reference_versioned_docs/version-<ver>/jetstream/errors.mdreference_versioned_docs/version-<ver>/system/errors.mdreference_versioned_docs/version-<ver>/jetstream/api/headers.mdreference_versioned_docs/version-<ver>/config/**(fromtools/config-generator)reference_versioned_docs/version-<ver>/**/*(schema-refs pages fromscripts/schema-refs.json)reference_versioned_sidebars/version-<ver>-sidebars.jsonsrc/schemas/vendor/v<ver>/**(vendored JSON schemas)
Prerequisites:
- Go + Node (to run the generators)
nats-serverandjsm.gosubmodules initialized
git submodule update --initGenerate documentation:
# Generate all versions listed in scripts/doc-versions.json
npm run generate-docs:all-versions
# Or a single version
npm run generate-docs:v2.11
npm run generate-docs:v2.12
# Dry-run the parser (stdout only; no docs-out required)
npm run generate-docs:dry-runWhen to regenerate:
- After bumping a version's tag in
scripts/doc-versions.json - When adding or changing entries in
scripts/schema-refs.json - When modifying generation templates in
scripts/templates/ - Before committing reference doc changes
This site is built with:
- Docusaurus - Static site generator optimized for documentation
- React - UI components and interactive elements
- MDX - Markdown with JSX for rich documentation pages
- TypeScript - Type-safe configuration and components
nats.docs.v2/
├── docs/ # Core Concepts pages (served at "/")
│ └── concepts/
├── learn/ # Learn deep dives (own docs instance, "/learn")
├── tutorials/ # Hands-on tutorials (own docs instance, "/tutorials")
├── reference_versioned_docs/ # Generated per-version Reference ("/reference")
├── src/
│ ├── components/ # React components
│ │ └── NatsFlow/ # Interactive flow diagrams
│ ├── plugins/ # Docusaurus plugins (NatsFlow client module)
│ └── css/ # Global styles
├── static/
│ ├── examples/snippets/
│ │ └── cli/ # Committed CLI examples (other languages fetched)
│ ├── js/
│ │ └── nats-flow-loader.js # Mounts NatsFlow animations client-side
│ └── img/ # Images and assets
├── scripts/ # fetch-examples, generate-version, rehype plugins
├── tools/config-generator/ # Go generator for the config reference tree
├── docusaurus.config.ts # Site configuration
├── sidebars.ts # + sidebars-learn/tutorials/reference.ts
└── package.json # Dependencies and scripts
Important notes:
docs/content is served at the root URL path (/)static/examples/snippets/cli/is committed; the Go/Rust/JS/Python/Java/C# subtrees andmetadata.jsonare fetched bynpm run fetch-examplesand gitignoredscripts/rehype-nats-example.mjsrendersnats-exampledivs into language tabs at build time (restart the dev server after fetching new examples — the plugin cachesmetadata.json)
The documentation uses a multi-repository example system:
For programming language examples (Go, Rust, JavaScript, Python, Java, C#):
- Code examples live in the actual NATS client repositories (nats.go, nats.rs, nats.js, nats.py, nats.java, nats.net)
- All examples are on the
doc-examplesbranch in each repository scripts/fetch-examples.jsfetches examples from GitHub- Examples are saved to
static/examples/snippets/[language]/and indexed inmetadata.json scripts/rehype-nats-example.mjsrenders the language tabs at build time frommetadata.json- Documentation pages use
<div class="nats-example" data-type="..." data-languages="..."></div>tags
For CLI examples:
- CLI snippets always live in this repo at
static/examples/snippets/cli/[page]/[snippet].shand are committed to git npm run fetch-examplesauto-scans that directory intometadata.jsonalongside the fetched languages
Why this approach?
- Programming language examples are tested, working code from actual client libraries
- Examples can be run and validated in their native repositories
- Single source of truth - if the client library changes, examples stay in sync
- CLI-only examples live in docs repo because they're just shell commands, not library code
docusaurus.config.ts
- Main site configuration
- Navbar and footer settings
- Plugin configuration
- Theme settings
- Deployment configuration
sidebars.ts
- Documentation sidebar navigation structure
- Controls the order and grouping of doc pages
- Uses file paths relative to
docs/directory
package.json
- Dependencies and versions
- npm scripts (start, build, fetch-examples, etc.)
- Project metadata
scripts/fetch-examples.js
- Configuration for code examples from GitHub
- Maps example names to file paths in client repos
- Defines which examples to fetch and where to find them
scripts/rehype-nats-example.mjs
- Build-time rehype plugin that replaces
nats-exampledivs with language tabs - Reads
static/examples/snippets/metadata.json(caches it — restart the dev server afternpm run fetch-examples)
Main branches:
main- Production branch, auto-deploys to GitHub Pages- Feature branches - Create from
mainfor your work
Workflow:
- Create a feature branch:
git checkout -b your-feature-name - Make your changes and commit regularly
- Push to GitHub:
git push origin your-feature-name - Open a Pull Request targeting
main - PR gets a Netlify preview URL automatically
- After review and approval, merge to
main - Changes auto-deploy to production
For code examples in client repos:
All examples must be on the doc-examples branch in the respective repository (nats.go, nats.rs, nats.js).
Generated files (excluded by .gitignore):
static/examples/snippets/go/- Fetched from nats.go repositorystatic/examples/snippets/rust/- Fetched from nats.rs repositorystatic/examples/snippets/javascript/- Fetched from nats.js repositorystatic/examples/snippets/metadata.json- Generated by fetch scriptbuild/- Production build output.docusaurus/- Docusaurus cachenode_modules/- npm dependencies
Files you SHOULD commit:
- Documentation pages in
docs/ - React components in
src/ - CLI examples in
static/examples/snippets/cli/(source of truth for CLI examples) - Configuration files (
docusaurus.config.ts,sidebars.ts, etc.) - Static assets in
static/(images, fonts, etc.)
Important: The static/examples/snippets/ directory structure:
static/examples/snippets/
├── cli/ # ✅ COMMIT - CLI examples (source of truth)
│ └── [page]/
│ └── [snippet].sh
├── go/ # ❌ DON'T COMMIT - Fetched from nats.go repo
├── rust/ # ❌ DON'T COMMIT - Fetched from nats.rs repo
├── javascript/ # ❌ DON'T COMMIT - Fetched from nats.js repo
├── python/ java/ csharp/ # ❌ DON'T COMMIT - Fetched from nats.py / nats.java / nats.net
└── metadata.json # ❌ DON'T COMMIT - Generated by fetch script
Where programming language examples live:
- Go:
nats.go· Rust:nats.rs· JavaScript/TypeScript:nats.js· Python:nats.py· Java:nats.java· C#:nats.net— each on itsdoc-examplesbranch
File format:
- Use
.mdfor simple pages with plain Markdown - Use
.mdxfor pages that need React components (tabs, NatsFlow animations, etc.)
Front matter: Every documentation page should have front matter at the top:
---
title: Page Title
sidebar_label: Short Label # Optional, for sidebar
---Best practices:
- Start simple: Begin with core concepts before diving into details
- Show, don't just tell: Use code examples and animations to illustrate concepts
- Be consistent: Follow the style guide in CLAUDE.md
- Link liberally: Connect related concepts with internal links
- Test examples: All code should be runnable and tested
- Use active voice: "NATS delivers messages" not "Messages are delivered by NATS"
- Keep it current: Use realistic examples with
demo.nats.io
Language order for code examples: Always show examples in this order: CLI, JavaScript/TypeScript, Go, Python, Java, Rust, C#/.NET
When to use NatsFlow animations:
- Message flow patterns (pub/sub, request/reply)
- Timing and sequencing diagrams
- Fan-out and load balancing visualization
When to use code examples:
- API syntax and usage
- Configuration examples
- Step-by-step tutorials
This documentation site uses a multi-repository example system that pulls code examples from the actual NATS client repositories. This ensures examples are tested, working code.
Important principle:
- Programming language examples (Go, Rust, JavaScript, Python, Java, C#) → Always add to respective client repositories
- CLI-only examples (no programming language versions) → Add to this documentation repository
If you're creating a multi-language example that includes CLI + Go + Rust + JavaScript, the CLI portion goes in this repo (static/examples/snippets/cli/), while Go/Rust/JS go in their respective client repos.
For the best experience, clone the client repositories alongside this docs repository:
~/coding/
├── nats.docs.v2/ # This repository
├── nats.go-docs/ # Go examples
├── nats.rs-docs/ # Rust examples
└── nats.js-docs/ # JavaScript/TypeScript examplesClone the repositories:
cd ~/coding
git clone https://github.com/nats-io/nats.go nats.go-docs
git clone https://github.com/nats-io/nats.rs nats.rs-docs
git clone https://github.com/nats-io/nats.js nats.js-docsSwitch to the doc-examples branch in each:
cd nats.go-docs && git checkout -b doc-examples origin/doc-examples
cd ../nats.rs-docs && git checkout -b doc-examples origin/doc-examples
cd ../nats.js-docs && git checkout -b doc-examples origin/doc-examplesExamples follow the pattern [page]-[snippet]:
getting-started-publish- Publish example on the getting-started pagebasics-subscribe- Subscribe example on the basics page
CLI examples are stored locally in this repository. This includes:
- CLI portions of multi-language examples
- CLI-only examples (examples with no programming language equivalents)
Location:
static/examples/snippets/cli/[page]/[snippet].shExample:
# static/examples/snippets/cli/getting-started/publish.sh
#!/bin/bash
# Publish a message to demo.nats.io
nats pub --server=demo.nats.io hello "Hello NATS!"After creating CLI examples:
- CLI examples are committed directly to this repository (not fetched from GitHub)
- They do not need to be pushed to a separate branch
- Just commit and push to your feature branch in this repo
Repository: nats.go (cloned as ~/coding/nats.go-docs)
Branch: doc-examples
Location: ~/coding/nats.go-docs/examples/docs/[page]-[snippet]/main.go
// examples/docs/getting-started-publish/main.go
package main
import (
"log"
"github.com/nats-io/nats.go"
)
func main() {
// Connect to NATS demo server
nc, err := nats.Connect("demo.nats.io")
if err != nil {
log.Fatal(err)
}
defer nc.Close()
// Publish a message
err = nc.Publish("hello", []byte("Hello NATS!"))
if err != nil {
log.Fatal(err)
}
log.Println("Message published to hello")
}After creating examples:
cd ~/coding/nats.go-docs
go fmt ./examples/docs/getting-started-publish/main.go
git add examples/docs/getting-started-publish/
git commit -m "Add getting-started-publish example"
git push origin doc-examplesRepository: nats.rs (cloned as ~/coding/nats.rs-docs)
Branch: doc-examples
Location: ~/coding/nats.rs-docs/async-nats/examples/docs_[page]_[snippet].rs
Note: Use underscores instead of hyphens in filenames.
// async-nats/examples/docs_getting_started_publish.rs
use async_nats;
#[tokio::main]
async fn main() -> Result<(), async_nats::Error> {
// Connect to NATS demo server
let client = async_nats::connect("demo.nats.io").await?;
// Publish a message
client.publish("hello", "Hello NATS!".into()).await?;
client.flush().await?;
println!("Message published to hello");
Ok(())
}After creating examples:
cd ~/coding/nats.rs-docs/async-nats
cargo +nightly fmt
cd ..
git add async-nats/examples/docs_getting_started_publish.rs
git commit -m "Add getting-started-publish example"
git push origin doc-examplesRepository: nats.js (cloned as ~/coding/nats.js-docs)
Branch: doc-examples
Location: ~/coding/nats.js-docs/examples/docs/[page]-[snippet]/index.ts
// examples/docs/getting-started-publish/index.ts
// import the connect function from a transport
import { connect } from "@nats-io/transport-deno";
// connect to NATS demo server
const nc = await connect({ servers: "demo.nats.io:4222" });
// publish a message to the 'hello' subject
nc.publish("hello", "Hello NATS!");
console.log("Message published to hello");
// drain the connection (flushes and closes)
await nc.drain();After creating examples:
cd ~/coding/nats.js-docs
git add examples/docs/getting-started-publish/
git commit -m "Add getting-started-publish example"
git push origin doc-examplesFor examples that need setup code but you only want to show a specific section in the docs:
func main() {
// Setup code here
nc, _ := nats.Connect("demo.nats.io")
defer nc.Close()
// NATS-DOC-START
// This is the code that will be extracted
nc.Publish("hello", []byte("Hello!"))
// NATS-DOC-END
// More code here
}If no markers are present, the entire file is used (recommended for "getting started" examples).
Add your examples to scripts/fetch-examples.js:
const EXAMPLES_CONFIG = {
go: {
examples: {
"getting-started-publish":
"examples/docs/getting-started-publish/main.go",
// ... add more
},
},
rust: {
examples: {
"getting-started-publish":
"async-nats/examples/docs_getting_started_publish.rs",
// ... add more
},
},
javascript: {
examples: {
"getting-started-publish":
"examples/docs/getting-started-publish/index.ts",
// ... add more
},
},
};After pushing examples to GitHub, fetch them into this repo:
npm run fetch-examplesThis downloads examples from GitHub and saves them to static/examples/snippets/.
In your MDX files:
### Publisher Example
<div
class="nats-example"
data-type="getting-started-publish"
data-languages="cli,js,go,java,rust,csharp"
></div>Languages are shown in the order specified. CLI should always be first with default attribute.
For multi-language examples (CLI + Go + Rust + JS):
- Create CLI example in this repository:
static/examples/snippets/cli/[page]/[snippet].sh - Create Go example in
~/coding/nats.go-docsrepository ondoc-examplesbranch - Create Rust example in
~/coding/nats.rs-docsrepository ondoc-examplesbranch - Create JavaScript example in
~/coding/nats.js-docsrepository ondoc-examplesbranch - Format code in each repository (go fmt, cargo fmt, etc.)
- Commit and push CLI example to this repo, other examples to
doc-examplesbranch in client repos - Update
scripts/fetch-examples.jsto register new Go/Rust/JS examples - Fetch examples:
npm run fetch-examples(pulls Go/Rust/JS from GitHub) - Use in docs: Add
<div class="nats-example" data-type="..." data-languages="cli,js,go,java,rust,csharp"></div> - Test locally:
npm startand verify all tabs appear correctly
For CLI-only examples:
- Create CLI example in this repository:
static/examples/snippets/cli/[page]/[snippet].sh - Commit and push to this repo
- Use in docs: Add
<div class="nats-example" data-type="..." data-languages="cli"></div> - Test locally:
npm startand verify example appears
See CLAUDE.md for detailed documentation style guidelines including:
- Code example structure
- Tab ordering (CLI, JavaScript/TypeScript, Go, Python, Java, Rust, C#/.NET)
- Comment style
- When to use NatsFlow animations vs code examples
Issue: npm start fails or shows port conflicts
Solutions:
- Check if port 3000 is already in use:
lsof -i :3000
- Kill any existing process:
lsof -i :3000 | grep LISTEN | awk '{print $2}' | xargs kill
- Clear Docusaurus cache and try again:
npm run clear npm start
Issue: <div class="nats-example"> tags show "No examples available"
Possible causes and solutions:
-
Examples not fetched from GitHub:
npm run fetch-examples
Check that
static/examples/snippets/metadata.jsonexists and contains your example. -
Wrong data-type attribute: Verify the
data-typematches the example name inscripts/fetch-examples.js. For example, if the config has"getting-started-publish", use:<div class="nats-example" data-type="getting-started-publish" ...></div>
-
CLI examples missing: CLI examples are stored in this repository at
static/examples/snippets/cli/[page]/[snippet].sh.If a CLI example doesn't appear:
- Check that the file exists:
static/examples/snippets/cli/[page]/[snippet].sh - Verify the file is committed to git (CLI examples should be in the repository)
- Re-run
npm run fetch-examples(it scans the CLI tree intometadata.json) and restart the dev server — the rehype plugin cachesmetadata.json
- Check that the file exists:
Issue: npm run typecheck shows errors
Solutions:
- Make sure
docusaurus.config.tsand other TypeScript files have correct types - Check imports in MDX files - use
@site/prefix for absolute imports:import { NatsFlow } from "@site/src/components/NatsFlow";
- Restart your IDE's TypeScript server if errors persist after fixing
Issue: Changes to files don't appear in the browser
Solutions:
- Restart the dev server (
Ctrl+C, thennpm start) - Hard refresh the browser (
Cmd+Shift+Ron Mac,Ctrl+Shift+Ron Windows/Linux) - Check the terminal for build errors
- Clear cache:
npm run clearthennpm start
Issue: npm run build fails
Common causes:
- Broken links: Check for invalid internal links in markdown files
- Type errors: Run
npm run typecheckto identify issues - Missing dependencies: Run
npm installto ensure all packages are installed - Code example issues: Run
npm run fetch-examplesto refresh examples
Issue: Pushed new examples but they don't appear in docs
For programming language examples (Go, Rust, JavaScript, Python, Java, C#): Examples are fetched from GitHub, not local repositories. You need to:
- Push your changes to the
doc-examplesbranch in the client repo (nats.go, nats.rs, or nats.js) - Wait a moment for GitHub to process the push
- Run
npm run fetch-examplesin this repository to pull from GitHub - Refresh your browser
Note: The fetch script pulls from GitHub's raw content URLs, so changes must be pushed to be visible.
For CLI examples:
CLI examples are stored directly in this repository at static/examples/snippets/cli/, so they don't need to be fetched:
- Commit your CLI example to this repository
- Changes appear immediately after saving (hot reload)
- No need to run
npm run fetch-examplesfor CLI-only changes
Issue: <div class="nats-flow" data-scenario="..."> not rendering
Solutions:
- Verify the
data-scenarioname:*Animatedscenarios must be exported fromsrc/components/NatsFlow/scenarios/index.tsand registered insrc/plugins/nats-flow/client-module.tsx - Check the browser console for JavaScript errors
- See
src/components/NatsFlow/README.mdfor the full authoring and wiring guide
- Check Docusaurus documentation
- Review CLAUDE.md for style guidelines
- Check existing documentation pages for examples
- Look at
src/components/NatsFlow/README.mdfor animation component details
The original code and documentation in this repository are licensed under the MIT License.
Parts of this repository derive from Apache-2.0-licensed upstream projects, and those portions remain under the Apache License 2.0 — see NOTICE for details and LICENSE-APACHE for the license text:
- Documentation content derived from nats-io/nats.docs
- Reference documentation and JSON schemas generated from nats-io/nats-server and nats-io/jsm.go