Skip to main content

Overview

Fumadocs UI uses Tailwind CSS v4 with a comprehensive design token system for theming. All components are styled using CSS variables prefixed with --color-fd-*, making customization straightforward.

Setup

Installation

Fumadocs UI requires Tailwind CSS v4:
npm install tailwindcss@next

Import Styles

app/layout.tsx
import 'fumadocs-ui/style.css';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

Color System

Design Tokens

Fumadocs uses semantic color tokens that automatically adapt to light and dark modes:
CSS Variables
/* Light mode */
--color-fd-background: hsl(0, 0%, 96%);
--color-fd-foreground: hsl(0, 0%, 3.9%);
--color-fd-muted: hsl(0, 0%, 96.1%);
--color-fd-muted-foreground: hsl(0, 0%, 45.1%);
--color-fd-card: hsl(0, 0%, 94.7%);
--color-fd-card-foreground: hsl(0, 0%, 3.9%);
--color-fd-popover: hsl(0, 0%, 98%);
--color-fd-popover-foreground: hsl(0, 0%, 15.1%);
--color-fd-primary: hsl(0, 0%, 9%);
--color-fd-primary-foreground: hsl(0, 0%, 98%);
--color-fd-secondary: hsl(0, 0%, 93.1%);
--color-fd-secondary-foreground: hsl(0, 0%, 9%);
--color-fd-accent: hsla(0, 0%, 82%, 50%);
--color-fd-accent-foreground: hsl(0, 0%, 9%);
--color-fd-border: hsla(0, 0%, 80%, 50%);
--color-fd-ring: hsl(0, 0%, 63.9%);
--color-fd-overlay: hsla(0, 0%, 0%, 0.2);

/* Status colors (static) */
--color-fd-info: oklch(62.3% 0.214 259.815);
--color-fd-warning: oklch(76.9% 0.188 70.08);
--color-fd-error: oklch(63.7% 0.237 25.331);
--color-fd-success: oklch(72.3% 0.219 149.579);
--color-fd-idea: oklch(70.5% 0.209 60.849);

Tailwind Usage

Use the fd- prefix to access design tokens:
<div className="bg-fd-background text-fd-foreground">
  <h1 className="text-fd-primary">Heading</h1>
  <p className="text-fd-muted-foreground">Muted text</p>
</div>

Built-in Themes

Fumadocs provides several pre-built color themes:

Neutral

Default grayscale theme

Ocean

Blue ocean-inspired palette

Purple

Vibrant purple theme

Emerald

Fresh green theme

Ruby

Rich red theme

Catppuccin

Popular pastel theme

Solar

Solarized-inspired theme

Dusk

Soft purple-gray theme

Aspen

Nature-inspired theme

Using Built-in Themes

app/layout.tsx
// Replace the default style.css with a themed version
import 'fumadocs-ui/css/ocean.css';
// or
import 'fumadocs-ui/css/purple.css';
// or
import 'fumadocs-ui/css/emerald.css';

Custom Themes

Create a Custom Theme

Override CSS variables in your global CSS file:
app/globals.css
@import 'fumadocs-ui/style.css';

@layer theme {
  :root {
    /* Custom light mode colors */
    --color-fd-primary: hsl(262, 83%, 58%);
    --color-fd-primary-foreground: hsl(0, 0%, 100%);
    --color-fd-accent: hsla(262, 83%, 58%, 0.1);
    --color-fd-accent-foreground: hsl(262, 83%, 58%);
  }

  .dark {
    /* Custom dark mode colors */
    --color-fd-primary: hsl(262, 83%, 68%);
    --color-fd-primary-foreground: hsl(0, 0%, 9%);
    --color-fd-accent: hsla(262, 83%, 68%, 0.15);
    --color-fd-accent-foreground: hsl(262, 83%, 68%);
  }
}

Component-Specific Theming

Target specific components with custom tokens:
/* Custom sidebar colors */
.dark #nd-sidebar {
  --color-fd-muted: hsl(0, 0%, 16%);
  --color-fd-secondary: hsl(0, 0%, 18%);
  --color-fd-muted-foreground: hsl(0, 0%, 72%);
}

/* Custom card styles */
[data-card] {
  --color-fd-card: hsl(220, 15%, 95%);
  --color-fd-border: hsl(220, 15%, 80%);
}

Dark Mode

Setup

Dark mode is enabled by default via next-themes:
app/layout.tsx
import { RootProvider } from 'fumadocs-ui/provider/base';

export default function RootLayout({ children }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <RootProvider
          theme={{
            attribute: 'class',
            defaultTheme: 'system',
            enableSystem: true,
          }}
        >
          {children}
        </RootProvider>
      </body>
    </html>
  );
}

Theme Toggle Options

<DocsLayout
  tree={pageTree}
  themeSwitch={{
    enabled: true,
    mode: 'light-dark-system', // or 'light-dark'
  }}
/>

Force Theme

Disable theme switching:
<RootProvider
  theme={{
    enabled: false,
  }}
>
  {children}
</RootProvider>

Typography

Font Configuration

Configure fonts in your layout:
app/layout.tsx
import { Inter, JetBrains_Mono } from 'next/font/google';
import { RootProvider } from 'fumadocs-ui/provider/base';

const inter = Inter({ subsets: ['latin'], variable: '--font-sans' });
const mono = JetBrains_Mono({ subsets: ['latin'], variable: '--font-mono' });

export default function RootLayout({ children }) {
  return (
    <html lang="en" className={`${inter.variable} ${mono.variable}`}>
      <body>
        <RootProvider>{children}</RootProvider>
      </body>
    </html>
  );
}

Tailwind Font Configuration

app/globals.css
@theme {
  --font-family-sans: var(--font-sans), system-ui, sans-serif;
  --font-family-mono: var(--font-mono), 'Courier New', monospace;
}

Animations

Built-in Animations

Fumadocs includes several CSS animations:
/* Collapsible animations */
--animate-fd-collapsible-down: fd-collapsible-down 150ms cubic-bezier(0.45, 0, 0.55, 1);
--animate-fd-collapsible-up: fd-collapsible-up 150ms cubic-bezier(0.45, 0, 0.55, 1);

/* Accordion animations */
--animate-fd-accordion-down: fd-accordion-down 200ms ease-out;
--animate-fd-accordion-up: fd-accordion-up 200ms ease-out;

/* Navigation menu animations */
--animate-fd-nav-menu-in: fd-nav-menu-in 200ms ease;
--animate-fd-nav-menu-out: fd-nav-menu-out 200ms ease;

Custom Animations

@keyframes custom-fade-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.custom-animation {
  animation: custom-fade-in 300ms ease-out;
}

Responsive Design

All components use Tailwind’s responsive utilities:
<div className="px-4 md:px-6 xl:px-8">
  <h1 className="text-2xl md:text-3xl xl:text-4xl">Responsive Heading</h1>
</div>

CSS Variables Reference

Color Tokens

Layout Variables

Advanced Customization

Per-Component Theming

/* Custom callout colors */
.callout[data-type="custom"] {
  --callout-color: hsl(280, 100%, 70%);
  border-left: 3px solid var(--callout-color);
}

/* Custom code block styles */
.shiki {
  --color-fd-card: hsl(220, 13%, 13%);
  border-radius: 12px;
}

Gradient Backgrounds

.gradient-background {
  background: linear-gradient(
    135deg,
    var(--color-fd-primary) 0%,
    var(--color-fd-accent) 100%
  );
}

Best Practices

  1. Always test your theme in both light and dark modes
  2. Use semantic tokens (fd-primary, fd-muted) instead of direct colors
  3. Maintain sufficient contrast ratios for accessibility (WCAG AA: 4.5:1)
  4. Use HSL color format for easier adjustments
  5. Test with real content to ensure readability

Examples

Brand Color Theme

app/globals.css
@import 'fumadocs-ui/style.css';

@layer theme {
  :root {
    --color-fd-primary: hsl(217, 91%, 60%);
    --color-fd-primary-foreground: hsl(0, 0%, 100%);
    --color-fd-accent: hsla(217, 91%, 60%, 0.1);
    --color-fd-accent-foreground: hsl(217, 91%, 60%);
  }

  .dark {
    --color-fd-primary: hsl(217, 91%, 70%);
    --color-fd-accent: hsla(217, 91%, 70%, 0.15);
  }
}

High Contrast Theme

@layer theme {
  .high-contrast {
    --color-fd-background: hsl(0, 0%, 100%);
    --color-fd-foreground: hsl(0, 0%, 0%);
    --color-fd-border: hsl(0, 0%, 0%);
    --color-fd-primary: hsl(0, 0%, 0%);
  }

  .dark.high-contrast {
    --color-fd-background: hsl(0, 0%, 0%);
    --color-fd-foreground: hsl(0, 0%, 100%);
    --color-fd-border: hsl(0, 0%, 100%);
    --color-fd-primary: hsl(0, 0%, 100%);
  }
}

Build docs developers (and LLMs) love