This document provides an overview of the technologies used in the Node.js website and explains key architectural decisions.
- Core Technologies
- Repository Structure
- Architecture Decisions
- Configuration Files
- Development Environment
- Performance Optimizations
- Testing Infrastructure
The Node.js Website is built with React and Next.js:
- React: UI rendering engine for component-based development
- Next.js: Full-stack framework providing SSG, routing, and build optimization
We chose Next.js because it is:
- Versatile and hackable for custom requirements
- Stable with strong community maintenance
- Well-suited as a long-term framework choice
- Capable of supporting static builds (a requirement from the Node.js Technical Steering Committee)
- PostCSS: CSS preprocessing with plugin-based architecture
- Tailwind CSS: Utility-first CSS framework and design system foundation
- CSS Modules: Scoped styling for components
postcss-calc: Resolvescalc()expressions at build time@tailwindcss/postcss: Enables Tailwind integration
- MDX: Markdown with JSX component support
- Remark: Markdown processing plugins
- Rehype: HTML processing plugins
remark-gfm: GitHub Flavored Markdown supportremark-headings: Generates metadata for table of contentsrehype-autolink-headings: Automatic anchor links for headingsrehype-slug: Automatic ID generation for headings
- Radix UI: Accessible, unstyled component primitives
- Hero Icons: SVG icon library
- Shiki: Syntax highlighting for code blocks
- Minimalistic, component-focused approach
- Built-in WAI-ARIA and accessibility features
- Allows focus on design without accessibility implementation overhead
- Modular package structure
next-intl: i18n library with Next.js integration- ICU Message Syntax: Translation message format
- Storybook: Component development and visual testing
- Chromatic: Automated visual regression testing
- Husky: Git hooks for code quality
nodejs.org/
├── apps/
│ └── site/ # Main website application
│ ├── components/ # Website-specific React components
│ ├── layouts/ # Page layout templates
│ ├── pages/ # Content pages (Markdown/MDX)
│ │ ├── en/ # English content (source)
│ │ └── {locale}/ # Translated content
│ ├── public/ # Static assets
│ │ └── static/ # Images, documents, etc.
│ ├── hooks/ # React hooks
│ ├── providers/ # React context providers
│ ├── types/ # TypeScript definitions
│ ├── next-data/ # Build-time data fetching
│ ├── scripts/ # Utility scripts
│ ├── snippets/ # Code snippets for download page
│ └── tests/ # Test files
│ └── e2e/ # End-to-end tests
└── packages/
├── ui-components/ # Reusable UI components
│ ├── styles/ # Global stylesheets
│ └── .storybook/ # Storybook configuration
├── i18n/ # Internationalization
│ ├── locales/ # Translation files
│ └── config.json # Locale configuration
├── rehype-shiki/ # Syntax highlighting plugin
...
The website supports fully static builds to ensure independence from third-party services:
- Content can be served without external dependencies
- Maintains availability even if hosting providers change
The website uses a custom rendering system instead of Next.js default routing:
- Catches all routes and renders them through a custom system
- Enables dynamic page generation from Markdown files
- Supports incremental static generation (ISG)
This file handles:
- Discovering all source pages in
apps/site/pages/en - Identifying translated pages
- Generating localized paths for untranslated content
- Creating fallback pages that show English content with translated menus and UI elements
Responsible for:
- Node.js release data fetching
- Blog post metadata generation
- RSS feed creation
- Build-time indexing
We use a custom i18n solution because:
- Need comprehensive locale and page listing capabilities
- Use subfolder content structure (
/pages/en/,/pages/fr/) vs. extension-based (file.en.md) - Maintain consistency with previous website structure
- Ensure long-term maintainability
next.middleware.js: Handles browser locale detection and redirects- Falls back to
/enfor unsupported locales - Provides seamless user experience across languages
// Each page specifies its layout in frontmatter
---
title: Page Title
layout: layout-name
---
// Layouts wrap content and provide structure
const Layout: FC<{ children: ReactNode }> = ({ children }) => (
<div className="layout">
<Header />
<main>{children}</main>
<Footer />
</div>
);- Markdown files → MDX compiler
- Rehype/Remark plugins → Content transformation
- Shiki integration → Syntax highlighting
- Layout system → Page structure
- i18n integration → Localized rendering
Handles URL rewriting and redirects:
// Internal rewrites (same content, different URL)
{ source: '/old-path', destination: '/new-path' }
// External redirects (different domain)
{ source: '/docs', destination: 'https://nodejs.org/docs' }
// Locale template support
{ source: '/:locale/old-path', destination: '/:locale/new-path' }Configuration file supporting:
- Internal and external redirects
- Locale templating with
/:localeplaceholder - Simple template engine for dynamic paths
Website metadata configuration:
- RSS feed definitions
- Social media information
- Build-time metadata
- Uses JSON format for easy collaboration
The .vscode directory provides:
extensions.json: Recommended extensions for optimal developmentsettings.json: Consistent formatting and linting configuration
Benefits:
- Uniform developer experience
- Automatic code formatting and linting
- Tailwind CSS IntelliSense
- Works with GitHub Codespaces
pnpm build: Production build for Vercelpnpm deploy: Export build for legacy serverspnpm dev: Development server
- Automatic deployments for branches (excluding
dependabot/*andgh/*) - Custom install script:
pnpm install --prod --frozen-lockfile - Dependency management: Build-time dependencies must be in
dependencies, notdevDependencies - Sponsorship maintained by OpenJS Foundation
- Individual packages published to npm registry
- Automated publishing via GitHub Actions
- Triggered after successful CI or manual workflow dispatch
- Automatic: After merging to main (via merge queue)
- Manual: Workflow dispatch for specific packages
- Notifications: Slack alerts for manual triggers
- Build-time page generation reduces server load
- Incremental Static Regeneration (ISR) for dynamic content
- Optimized asset handling and compression
- Code splitting at component and route levels
- Dynamic imports for large components
- Tree shaking for unused code elimination
- Next.js Image component for automatic optimization
- WebP conversion and responsive images
- Lazy loading for performance
- Storybook integration with Chromatic
- Automated visual diff detection
- Component isolation and testing
- Playwright for full application testing
- Critical user journey validation
- Cross-browser compatibility testing