# LangChain Documentation Build System
This repository contains the consolidated documentation build pipeline for LangChain projects, serving as the single source for all LangChain-related documentation. The system uses a custom Python-based build pipeline that processes MDX source files and deploys to two separate hosting platforms: Mintlify for the main docs site at docs.langchain.com and Vercel for the API reference documentation at reference.langchain.com.
The build pipeline preprocesses documentation files from the `/src` directory and generates versioned output for multiple programming languages (Python and JavaScript/TypeScript) while handling format conversion from MkDocs and Docusaurus formats to Mintlify's MDX format. The system includes a development server with hot reload capabilities, file watchers for automatic rebuilds, and comprehensive migration tools for converting legacy documentation formats. All documentation follows Mintlify's component-based syntax with YAML frontmatter and supports specialized code fences for language-specific content rendering.
## Development Server
Start development mode with file watching and live reload
```bash
# Start the development server
make dev
# Or use the docs CLI directly
docs dev
# Skip initial build and use existing build directory
docs dev --skip-build
```
```python
# Development command implementation
async def dev_command(args: Any | None) -> int:
"""Start development mode with file watching and mint dev."""
logger.info("Starting development mode...")
skip_build = getattr(args, "skip_build", False) if args else False
src_dir = Path("src")
build_dir = Path("build")
if not skip_build:
logger.info("Performing initial build...")
build_result = build_command(args)
if build_result != 0:
logger.error("Initial build failed")
sys.exit(1)
# Start file watcher
watcher = FileWatcher(src_dir, build_dir)
# Start mint dev in background
mint_process = await asyncio.create_subprocess_exec(
"mint", "dev", "--port", "3000",
cwd=build_dir,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
logger.info("Watching for file changes...")
await watcher.start()
```
## Build Documentation
Build all documentation from source to build directory
```bash
# Build documentation
make build
# Or use the docs CLI
docs build
# Watch for changes after building
docs build --watch
```
```python
# Build command implementation
def build_command(args: Any, src_dir: str = "src", build_dir: str = "build") -> int:
"""Build documentation from source to build directory."""
logger.info("Building documentation...")
src_dir_path = Path(src_dir)
build_dir_path = Path(build_dir)
if not src_dir_path.exists():
logger.error("Error: src directory not found")
return 1
build_dir_path.mkdir(exist_ok=True)
builder = DocumentationBuilder(src_dir_path, build_dir_path)
builder.build_all()
logger.info("Documentation built successfully in %s", build_dir_path)
return 0
```
```python
# Builder creates language-specific versions
class DocumentationBuilder:
def __init__(self, src_dir: Path, build_dir: Path):
self.src_dir = src_dir
self.build_dir = build_dir
self.copy_extensions = {".mdx", ".md", ".json", ".svg", ".png", ".jpg"}
def build_all(self):
"""Build versioned documentation for Python and JavaScript."""
if self.build_dir.exists():
shutil.rmtree(self.build_dir)
self.build_dir.mkdir(parents=True, exist_ok=True)
# Build language versions
self._build_langgraph_version("oss/python", "python")
self._build_langgraph_version("oss/javascript", "js")
# Build unversioned content
self._build_unversioned_content("langgraph-platform", "langgraph-platform")
self._build_unversioned_content("labs", "labs")
```
## Migrate from MkDocs Format
Convert MkDocs markdown and notebook files to Mintlify format
```bash
# Migrate a single file
docs migrate path/to/file.md
# Migrate an entire directory
docs migrate path/to/directory/
# Preview changes without writing files
docs migrate path/to/file.md --dry-run
# Specify output location
docs migrate path/to/file.md --output path/to/output.md
```
```python
# Migration processes markdown and notebooks
def _process_single_file(
file_path: Path,
output_path: Path,
*,
dry_run: bool,
migration_type: str = "mkdocs"
) -> bool:
"""Process a single file for migration."""
try:
extension = file_path.suffix.lower()
content = file_path.read_text()
if extension in {".md", ".markdown", ".mdx"}:
if migration_type == "docusaurus":
mint_markdown = convert_docusaurus_to_mintlify(content, file_path)
else:
mint_markdown = to_mint(content, str(file_path))
elif extension == ".ipynb":
markdown = convert_notebook(file_path)
mint_markdown = to_mint(markdown, str(file_path))
_, mint_markdown = drop_suffix_from_links(mint_markdown)
if dry_run:
print(f"=== {file_path} ===")
print(mint_markdown)
else:
output_path.parent.mkdir(parents=True, exist_ok=True)
with output_path.open("w", encoding="utf-8") as file:
file.write(mint_markdown)
logger.info("Converted %s -> %s", file_path, output_path)
return True
except ParseError as e:
logger.error("Parse error while processing file: %s", str(e))
return False
```
## Migrate from Docusaurus Format
Convert Docusaurus files including MDX and specialized syntax
```bash
# Convert Docusaurus files
docs migrate-docusaurus path/to/file.mdx
# Migrate directory with Docusaurus content
docs migrate-docusaurus path/to/docs/ --output build/docs/
# Preview Docusaurus conversion
docs migrate-docusaurus path/to/file.mdx --dry-run
```
```python
# Docusaurus migration handles additional syntax
def _find_files_to_migrate(input_path: Path, migration_type: str = "mkdocs") -> list[Path]:
"""Find all files to migrate in the given path."""
if input_path.is_file():
return [input_path]
# File patterns based on migration type
if migration_type == "docusaurus":
patterns = ["**/*.ipynb", "**/*.md", "**/*.markdown", "**/*.mdx"]
else:
patterns = ["**/*.ipynb", "**/*.md", "**/*.markdown"]
files: list[Path] = []
for pattern in patterns:
files.extend(input_path.glob(pattern))
return sorted(files)
```
## Move Files with Link Updates
Move documentation files and automatically update cross-references
```bash
# Move file and update all links pointing to it
docs mv old/path/file.md new/path/file.md
# Preview changes without moving
docs mv old/path/file.md new/path/file.md --dry-run
```
```python
# File movement with link tracking
def mv_command(args) -> None:
"""Handle the mv command for moving files with link updates."""
move_file_with_link_updates(args.old_path, args.new_path, dry_run=args.dry_run)
```
## Configuration Management
Configure documentation site with Mintlify docs.json
```json
{
"$schema": "https://mintlify.com/docs.json",
"theme": "willow",
"name": "Docs by LangChain",
"description": "Documentation for LangChain, LangGraph, LangGraph Platform, LangSmith",
"colors": {
"primary": "#2F6868",
"light": "#84C4C0",
"dark": "#84C4C0"
},
"logo": {
"light": "/images/brand/langchain-docs-teal.svg",
"dark": "/images/brand/langchain-docs-lilac.svg"
},
"integrations": {
"gtm": {
"tagId": "GTM-MBBX68ST"
}
},
"footer": {
"links": [
{
"header": "Resources",
"items": [
{"label": "Forum", "href": "https://forum.langchain.com/"},
{"label": "Changelog", "href": "https://changelog.langchain.com/"}
]
}
]
}
}
```
## Check for Broken Links
Validate documentation links before publishing
```bash
# Check for broken links (excludes integrations)
make mint-broken-links
# Check all directories including integrations
make mint-broken-links-all
# Manual check from build directory (safer than running from root)
cd build
mint broken-links
```
## Code Quality and Testing
Run linting, formatting, and test suite
```bash
# Format code automatically
make format
# Check for linting issues
make lint
# Run the test suite
make test
# Lint markdown files
make lint_md
# Fix markdown issues
make lint_md_fix
```
```python
# Python code formatting with ruff
# pyproject.toml configuration
[tool.ruff]
line-length = 88
extend-exclude = ["scripts/update_mdx.py", "pipeline/tools/notebook/convert.py"]
[tool.ruff.lint]
select = ["ALL"]
ignore = ["COM812", "C901", "PLR0915", "PLR0912"]
# Test configuration
[tool.pytest.ini_options]
minversion = "8.0"
addopts = "-ra -q -v --durations=5"
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
asyncio_mode = "auto"
```
## Build Reference Documentation
Build API reference docs for Python and JavaScript
```bash
# Build all reference documentation
make build-references
# Preview reference docs with Vercel
make preview-references
```
## Install Dependencies
Set up development environment with all required packages
```bash
# Install all dependencies including test dependencies
make install
# Manual installation with uv
uv sync --all-groups
# Install global Mintlify CLI
npm i -g mint
```
```toml
# pyproject.toml - Project dependencies
[project]
name = "docs-monorepo"
version = "0.1.0"
requires-python = ">=3.13.0,<4.0.0"
dependencies = [
"watchdog>=3.0.0",
"tqdm>=4.66.0",
"nbformat>=5.0.0",
"pyyaml>=6.0.2",
"nbconvert>=7.16.6"
]
[dependency-groups]
test = [
"requests",
"ruamel-yaml>=0.18.15",
"mypy>=1.17.0,<2.0.0",
"ruff>=0.13.0,<1.0.0",
"pytest>=8.3.4",
"pytest-asyncio>=0.25.3",
"pytest-cov>=6.0.0",
"pytest-mock>=3.14.0",
"pytest-socket>=0.7.0",
"pytest-timeout>=2.3.1"
]
[project.scripts]
docs = "pipeline.cli:main"
```
## Documentation Structure
Organize MDX files with required frontmatter
```mdx
---
title: Page Title
sidebarTitle: Sidebar Label
description: Concise page summary for SEO
---
# Page Heading
Content with Mintlify components:
Description of the feature or concept.
```bash pip
pip install langchain
```
```bash uv
uv add langchain
```
Important cautionary information for users.
```
## Language-Specific Content
Use code fences to render content for specific languages
```mdx
:::python
```python
from langchain.agents import create_agent
agent = create_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[get_weather],
system_prompt="You are a helpful assistant"
)
```
:::
:::js
```typescript
import { createAgent } from "langchain";
const agent = createAgent({
model: "anthropic:claude-3-7-sonnet-latest",
tools: [getWeather]
});
```
:::
```
## Clean Build Artifacts
Remove generated files and Python cache
```bash
# Clean all build artifacts
make clean
```
```makefile
clean:
@echo "Cleaning build artifacts..."
@rm -rf build/
@rm -rf __pycache__/
@find . -name "*.pyc" -delete
@find . -name "*.pyo" -delete
@find . -name "*.pyd" -delete
@find . -name "__pycache__" -type d -exec rm -rf {} +
```
---
This documentation build system provides comprehensive tooling for managing multi-language, versioned technical documentation across the LangChain ecosystem. The primary workflow involves editing MDX files in the `/src` directory, using `make dev` for local development with automatic rebuilds and hot reload, and running `make build` to generate production artifacts. The pipeline handles format conversion from legacy systems, maintains cross-references when moving files, and generates separate builds for Python and JavaScript audiences while sharing common content for platform-agnostic documentation.
For production deployments, the system integrates with two hosting platforms: Mintlify deploys from the `/build` directory for the main documentation site, while Vercel hosts the API reference documentation built from the `/reference` directory. The build process enforces code quality standards through automated linting and formatting checks, validates internal links to prevent broken references, and provides migration utilities for consolidating documentation from external projects. Development follows a PR workflow where all tests must pass before merging, with preview deployments available through the Mintlify dashboard for sharing work-in-progress changes with stakeholders.