# How to Use Docusaurus Preset Configurations: Complete Guide with Examples

> Learn how to use Docusaurus preset configurations. Simplify your setup by bundling plugins, themes, and options for a complete documentation site with one reference. Get the complete guide.

- Repository: [Meta/docusaurus](https://github.com/facebook/docusaurus)
- Tags: how-to-guide
- Published: 2026-03-04

---

**Docusaurus preset configurations are reusable bundles that combine plugins, themes, and default options into a single configuration entry, allowing you to initialize a complete documentation site by referencing one preset name instead of manually wiring individual components.**

When building documentation sites with the `facebook/docusaurus` framework, you typically need to register multiple plugins and themes to handle content, navigation, and styling. Docusaurus preset configurations streamline this process by packaging these elements into composable units that the core server expands automatically during the build pipeline.

## What Are Docusaurus Preset Configurations?

**Presets** are higher-level abstractions that aggregate related **plugins**, **themes**, and default site options into a single importable function. Rather than listing `@docusaurus/plugin-content-docs`, `@docusaurus/plugin-content-blog`, and `@docusaurus/theme-classic` separately in your configuration file, you declare a single preset entry that returns all three.

The preset system is implemented in the core server package at [`packages/docusaurus/src/server/plugins/presets.ts`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus/src/server/plugins/presets.ts). This file contains the registry logic that maps preset names (like `"classic"`) to their implementation functions and handles the merging of preset-generated configuration into your site.

### The Preset Registry and Core Architecture

Docusaurus maintains an internal **preset registry** that resolves string names or module paths to preset functions. When the development server or build process starts, the core loads each preset defined in the `presets` array of your configuration file.

| Component | Purpose | Source Location |
|-----------|---------|-----------------|
| **Preset Registry** | Maps preset names to implementation functions and validates the preset contract. | [`packages/docusaurus/src/server/plugins/presets.ts`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus/src/server/plugins/presets.ts) |
| **Preset Context** | Provides runtime information including site directory paths, site configuration, and version metadata to the preset function. | [`packages/docusaurus/src/server/plugins/presets.ts`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus/src/server/plugins/presets.ts) |
| **Preset Function** | User-defined or built-in function that receives context and options, then returns plugins, themes, and config overrides. | User modules or core packages |
| **Return Shape** | Standardized object containing `plugins`, `themes`, and optional `config` keys that Docusaurus merges into the final site config. | Defined in [`presets.ts`](https://github.com/facebook/docusaurus/blob/main/presets.ts) |

### The Preset Context and Return Shape

Every preset function receives two arguments: the **preset context** (containing paths and site metadata) and an **options** object (containing user-specified overrides). The function must return an object adhering to the following structure:

```javascript
{
  plugins: PluginConfig[],  // Array of plugin entries to register
  themes: ThemeConfig[],      // Array of theme entries to load
  config?: Partial<SiteConfig>  // Optional site configuration overrides
}

```

This return value is merged with your root [`docusaurus.config.js`](https://github.com/facebook/docusaurus/blob/main/docusaurus.config.js) settings, with later presets in the array taking precedence over earlier ones.

## How Docusaurus Resolves Presets

The resolution process occurs during the server initialization phase in [`packages/docusaurus/src/server/plugins/presets.ts`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus/src/server/plugins/presets.ts). The core executes the following steps:

1. **Reads the `presets` array** from [`docusaurus.config.js`](https://github.com/facebook/docusaurus/blob/main/docusaurus.config.js)
2. **Loads the preset module** (resolving strings like `"classic"` to built-in implementations or requiring custom file paths)
3. **Invokes the preset function** with the preset context and user-provided options
4. **Merges the returned values** into the site's plugin and theme registries, applying configuration overrides

This architecture allows you to share complete documentation setups across projects or distribute them via npm as "starter kit" packages.

## Using the Built-In Classic Preset

The **classic preset** is the most commonly used configuration in Docusaurus projects. It bundles the documentation plugin, blog plugin, and the classic theme into a single entry.

To use it, reference `"classic"` in your [`docusaurus.config.js`](https://github.com/facebook/docusaurus/blob/main/docusaurus.config.js):

```javascript
// docusaurus.config.js
module.exports = {
  title: 'My Documentation',
  url: 'https://example.com',
  baseUrl: '/',
  
  presets: [
    [
      'classic',
      /** @type {import('@docusaurus/preset-classic').Options} */
      ({
        docs: {
          sidebarPath: require.resolve('./sidebars.js'),
          editUrl: 'https://github.com/example/repo/edit/main/',
        },
        blog: {
          showReadingTime: true,
          postsPerPage: 5,
        },
        theme: {
          customCss: require.resolve('./src/css/custom.css'),
        },
      }),
    ],
  ],
};

```

The string `'classic'` resolves to the implementation exported by `@docusaurus/preset-classic`, which internally returns the standard set of content plugins and the classic theme. The options object configures each bundled plugin according to the `Options` type interface.

## Creating Custom Docusaurus Presets

You can author custom presets to standardize configurations across multiple documentation sites in an organization.

### Defining a Custom Preset Function

Create a JavaScript file that exports a function receiving `context` and `options`:

```javascript
// my-preset/index.js
module.exports = function myPreset(context, options) {
  return {
    plugins: [
      require.resolve('@docusaurus/plugin-content-docs'),
      require.resolve('@docusaurus/plugin-content-blog'),
      require.resolve('./local-search-plugin'), // Custom local plugin
    ],
    themes: [
      require.resolve('@docusaurus/theme-classic'),
    ],
    config: {
      themeConfig: {
        navbar: {
          title: 'Enterprise Docs',
          items: [
            { to: '/docs/intro', label: 'Documentation', position: 'left' },
            { to: '/blog', label: 'Release Notes', position: 'left' },
          ],
        },
        footer: {
          style: 'dark',
          copyright: `Copyright © ${new Date().getFullYear()} My Organization`,
        },
      },
    },
  };
};

```

This example demonstrates the pattern found in the test fixtures at [`packages/docusaurus/src/server/plugins/__tests__/__fixtures__/presets/preset-plugins.ts`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/presets/preset-plugins.ts), where presets return multiple plugins and configuration overrides.

### Applying Custom Presets in Your Configuration

Reference your local or npm-published preset using `require.resolve`:

```javascript
// docusaurus.config.js
module.exports = {
  // ... other config
  
  presets: [
    [
      require.resolve('./my-preset'),
      {
        // Preset-specific options passed to the function's `options` parameter
        blogEnabled: true,
      },
    ],
  ],
};

```

### Overriding Preset Options

When using any preset, you can selectively override its default behavior by providing an options object. The preset function receives these options and typically merges them with internal defaults before constructing the plugin list:

```javascript
presets: [
  [
    'classic',
    {
      // Disable the blog entirely
      blog: false,
      
      // Configure docs with custom path
      docs: {
        routeBasePath: '/',
        sidebarPath: require.resolve('./sidebars.js'),
      },
      
      // Keep theme but use custom CSS
      theme: {
        customCss: require.resolve('./src/css/enterprise-theme.css'),
      },
    },
  ],
];

```

## Summary

- **Docusaurus preset configurations** bundle plugins, themes, and site settings into single reusable units managed in [`packages/docusaurus/src/server/plugins/presets.ts`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus/src/server/plugins/presets.ts).
- The **classic preset** provides the standard documentation, blog, and theming setup via a single configuration entry.
- Custom presets follow a standard contract: export a function that receives **preset context** and returns `{ plugins, themes, config }`.
- Presets are resolved in order from the `presets` array, with later entries overriding earlier configuration values.
- You can mix built-in presets with custom local presets to create standardized documentation stacks for enterprise environments.

## Frequently Asked Questions

### What is the difference between a Docusaurus preset and a plugin?

A **plugin** is a single functional unit that loads content or modifies the build process (like generating documentation pages). A **preset** is a higher-level aggregator that returns multiple plugins, themes, and configuration values. While plugins do the actual work, presets are convenience packages that wire multiple plugins together with sensible defaults, as implemented in the core preset loading logic at [`packages/docusaurus/src/server/plugins/presets.ts`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus/src/server/plugins/presets.ts).

### Can I use multiple presets in one Docusaurus project?

Yes, you can declare multiple entries in the `presets` array. Docusaurus processes them sequentially and merges their returned plugins, themes, and configuration objects. Be aware that if two presets register conflicting plugins or theme settings, the later preset in the array will take precedence during the merge operation performed by the preset resolution system.

### How do I override specific options in the classic preset?

Pass a configuration object as the second element in your preset entry array. The classic preset accepts options for `docs`, `blog`, `pages`, and `theme` keys. These options are passed directly to the respective plugins after being merged with the preset's internal defaults. For example, setting `blog: false` disables the blog plugin entirely, while providing a `theme.customCss` path overrides the default stylesheet location.

### Where are built-in presets like "classic" defined?

The `"classic"` preset name resolves to `@docusaurus/preset-classic`, which is maintained in the `facebook/docusaurus` monorepo. The mapping from the string name to the actual module occurs in the preset registry within [`packages/docusaurus/src/server/plugins/presets.ts`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus/src/server/plugins/presets.ts). Additionally, the repository includes test fixtures such as [`packages/docusaurus/src/server/plugins/__tests__/__fixtures__/presets/preset-plugins.ts`](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/presets/preset-plugins.ts) that demonstrate how presets structure their return objects for both plugins and themes.