MUI Docs Infra

Warning

This is an internal project, and is not intended for public use. No support or stability guarantees are provided.

Load Server Types

A server-side function for loading and processing TypeScript types with syntax highlighting. This function coordinates the type extraction pipeline and applies HAST transformations for rendering.

Overview

loadServerTypes is the primary server-side entry point for type documentation processing. It:

  1. Loads type data — either by calling syncTypes to extract from TypeScript source, or by reading an existing types.md via loadServerTypesText
  2. Computes anchor slugs for all types
  3. Applies highlightTypes to highlight markdown code blocks in descriptions/examples
  4. Applies highlightTypesMeta to convert type strings to syntax-highlighted HAST

The sync option controls which path is used in step 1:

  • sync: false (default): Calls loadServerTypesText to read and parse an existing types.md file. This is the fast path used in production and during development when types have already been generated.
  • sync: true: Calls syncTypes to extract types from TypeScript source, format them, and write types.md to disk. This is the full extraction path used when types need to be regenerated.

Both paths produce the same TypesSourceData structure, so the rest of the pipeline is identical regardless of how the data was loaded. TypesSourceData extends OrganizeTypesResult<TypesMeta> and includes exports, additionalTypes, variantOnlyAdditionalTypes, externalTypes, typeNameMap, and allDependencies. This shared contract means loadServerTypesMeta (extracting from TypeScript source) and loadServerTypesText (parsing from types.md) are interchangeable from this function's perspective.

Usage

Default: Load from existing types.md

import { loadServerTypes } from '@mui/internal-docs-infra/pipeline/loadServerTypes';

const result = await loadServerTypes({
  typesMarkdownPath: '/absolute/path/to/types.md',
  rootContext: '/absolute/path/to/project',
  variants: { Default: '@base-ui/react/checkbox' },
  formattingOptions: {
    shortTypeUnionPrintWidth: 40,
    defaultValueUnionPrintWidth: 40,
  },
});

// result.exports — Record<string, ExportData> with highlighted types
// result.additionalTypes — HighlightedTypesMeta[] for top-level types
// result.variantOnlyAdditionalTypes — Record<string, HighlightedTypesMeta[]> for types-only module variants
// result.anchorMap — Record<string, string> for linking type references
// result.allDependencies — string[] of files to watch

With sync: Extract and regenerate types.md

const result = await loadServerTypes({
  typesMarkdownPath: '/absolute/path/to/types.md',
  rootContext: '/absolute/path/to/project',
  variants: { Default: '@base-ui/react/checkbox' },
  sync: true, // Extract from TS source and write types.md
});

When to Use

Use loadServerTypes when:

  • Building type documentation with syntax highlighting
  • Creating precomputed type data for webpack loaders
  • Processing types in API routes or custom build tools
  • You need HighlightedTypesMeta with HAST fields ready for rendering

Use syncTypes directly when:

  • You need raw type data without highlighting (plain text typeText)
  • You want to apply custom highlighting or transformations
  • You only need to update the types.md file

Use loadServerTypesText directly when:

  • You need the parsed type data from an existing types.md without any highlighting

Performance

With sync: false (default)

Reads and parses types.md — typically fast since no TypeScript compilation is involved.

With sync: true

Inherits performance characteristics from syncTypes:

  • First request: ~500-1200ms to create TypeScript program and parse types
  • Subsequent requests: ~100-140ms using cached program and file data

Highlighting Overhead

  • highlightTypes: Typically adds 10-50ms for markdown code block highlighting
  • highlightTypesMeta: Typically adds 5-20ms for type string → HAST conversion

Processing Pipeline

1. Load type data

Controlled by the sync option:

  • sync: false (default): Calls loadServerTypesText to read and parse the types.md file at typesMarkdownPath
  • sync: true: Delegates to syncTypes which loads TypeScript configuration, resolves source files, processes types via worker threads, formats types as plain text, and writes types.md to disk

Both produce a TypesSourceData containing exports, additionalTypes, variantOnlyAdditionalTypes, externalTypes, variantTypeNames, typeNameMap, and allDependencies.

2. Compute slugs

Computes URL anchor slugs for all types. Dotted names like Accordion.Trigger have their common component prefix stripped (producing trigger). Non-dotted names are lowercased as-is.

3. Apply highlightTypes

Transforms markdown content within type descriptions and examples with syntax highlighting. Processes:

  • Component, hook, and function descriptions (markdown with code blocks)
  • Prop/parameter/property examples and descriptions
  • Data attribute and CSS variable descriptions

Also builds a highlightedExports map used by the next stage for expanding type references.

Note: Type strings (typeText, defaultText) remain as plain text at this stage.

4. Apply highlightTypesMeta

Converts plain text type fields to syntax-highlighted HAST:

  • Converts typeTexttype (syntax-highlighted HAST)
  • Derives shortType from the highlighted type structure (e.g., "Union", "function")
  • Generates detailedType with expanded type references (when types reference other exported types)
  • Converts defaultTextdefault (syntax-highlighted HAST)
  • Extracts JSDoc comments from detailedType HAST into extractedProperties — a map of dot-notation property paths (e.g., "appearance.theme") to structured data including description, typeText, optional, @default, @deprecated, @see, and @example

Each export's types are processed in parallel via Promise.all. A shared rawTypeProperties map is built from all raw types so that named return type references can be expanded into property tables.

Hiding JSDoc Comments

JSDoc comments in detailedType HAST are separated into their own frames marked with data-frame-type="comment". This lets you hide the raw comments with CSS while displaying the extracted data in a richer format:

span.frame[data-frame-type='comment'] {
  display: none;
}

5. Build anchorMap

Constructs a map from type names to anchor hrefs (e.g., "Accordion.Trigger""#trigger"). Both dotted names and flat names from typeNameMap (e.g., "AccordionTrigger") are included, enabling linking from either naming convention.

Deep dive: To understand the TypeScript extraction pipeline in detail, see loadServerTypesMeta. For how types.md files are generated and written, see syncTypes.

Types

Server-side function for loading and processing TypeScript types.

This function:

  1. Either syncs types from source (sync: true) or loads from existing types.md (sync: false)
  2. Applies syntax highlighting to markdown content via highlightTypes
  3. Highlights type fields with HAST via highlightTypesMeta

The pipeline is:

  • sync: true: syncTypes extracts types, formats to plain text, generates markdown
  • sync: false: loadServerTypesText reads and parses an existing types.md file
  • highlightTypes: highlights markdown code blocks, builds highlightedExports map
  • highlightTypesMeta: converts type text to HAST, derives shortType/detailedType
PropertyTypeDescription
sync
boolean | undefined

When true, calls syncTypes to extract types from TypeScript source, generate markdown, and write to disk before highlighting.

When false, loads types from an existing types.md file using loadServerTypesText, skipping type extraction and markdown generation.

serializeHast
boolean | undefined

When true, replaces HAST Root nodes in the result with { hastJson: string } wrappers. This defers tree allocation from module-evaluation time to render time: V8 only creates a string instead of the full object graph, and JSON.parse at render time provides both deserialization and a free deep clone (eliminating the need for structuredClone).

typesMarkdownPath
string

Absolute path to the types.md file to generate

rootContext
string

Root context directory (workspace root)

variants
Record<string, string> | undefined

Map of variant name to file path (relative or package path). For single component: { Default: './Component' } For multiple: { CssModules: './css-modules/Component', Tailwind: './tailwind/Component' }

watchSourceDirectly
boolean | undefined

When true, resolves library paths to their source files for watching. Useful during development to watch the original source rather than built files.

formattingOptions
FormatInlineTypeOptions | undefined

Options for formatting types in tables

socketDir
string | undefined

Directory path for socket and lock files used for IPC between workers. Useful for Windows where the default temp directory may not support Unix domain sockets.

performanceLogging
boolean | undefined

Enable performance logging

updateParentIndex
| {
    baseDir?: string;
    onlyUpdateIndexes?: boolean;
    markerDir?: string;
    errorIfOutOfDate?: boolean;
    indexFileName?: string;
  }
| undefined

Options for updating the parent index page with component metadata. When provided, will call syncPageIndex to update the parent directory’s page.mdx with props, dataAttributes, and cssVariables extracted from the component types.

These options are passed through to syncPageIndex.

externalTypesPattern
string | undefined

Optional regex pattern string to filter which external types to include. External types are named union types (like Orientation = 'horizontal' | 'vertical') that are referenced in props but not exported from the component’s module.

When not provided, ALL qualifying named union types (unions of literals) will be collected automatically. This is the recommended behavior for most projects.

When provided, only external types whose names match this pattern will be collected.

ordering
OrderingConfig | undefined

Custom ordering configuration for sorting props, data attributes, exports, etc.

descriptionReplacements
DescriptionReplacement[] | undefined

Pattern/replacement pairs to apply to JSDoc descriptions. Each entry has a pattern (regex string) and replacement string.

Return Type
HighlightedClassProperty
type HighlightedClassProperty = {
  /** Whether this is a static property */
  isStatic?: boolean;
  /** Whether this property is readonly */
  readonly?: boolean;
  /** Description with syntax highlighting as HAST */
  description?: HastField;
  /** Example with syntax highlighting as HAST */
  example?: HastField;
  /** See-also links as HAST */
  see?: HastField;
  /** Syntax-highlighted type as HAST */
  type: HastField;
  /** Short simplified type for table display (e.g., "Union", "function") */
  shortType?: HastField;
  /** Plain text version of shortType for accessibility */
  shortTypeText?: string;
  /** Default value with syntax highlighting as HAST */
  default?: HastField;
  /** Detailed expanded type view (only when different from basic type) */
  detailedType?: HastField;
  /** Plain text version of description for markdown generation */
  descriptionText?: string;
  /** Plain text type string */
  typeText: string;
  /** Plain text default value */
  defaultText?: string;
  /** Whether the property is required */
  required?: true;
  /** Plain text version of example for markdown generation */
  exampleText?: string;
  /**
   * Plain text version of
   * @see for markdown generation
   */
  seeText?: string;
}
HighlightedClassTypeMeta
type HighlightedClassTypeMeta = {
  /** Description with syntax highlighting as HAST */
  description?: HastField;
  constructorParameters: HighlightedParameter[];
  properties: Record<string, HighlightedClassProperty>;
  methods: Record<string, HighlightedMethod>;
  name: string;
  /** Plain text version of description for markdown generation */
  descriptionText?: string;
  /** Type parameters (generics) if any */
  typeParameters?: string[];
}
HighlightedComponentTypeMeta
type HighlightedComponentTypeMeta = {
  props: Record<string, HighlightedProperty>;
  name: string;
  description?: HastRoot;
  /** Plain text version of description for markdown generation */
  descriptionText?: string;
  dataAttributes: Record<string, FormattedEnumMember>;
  cssVariables: Record<string, FormattedEnumMember>;
}
HighlightedEnumMemberMeta
type HighlightedEnumMemberMeta = {
  /** Description with syntax highlighting as HAST */
  description?: HastField;
  name: string;
  descriptionText?: string;
  value?: string | number;
}
HighlightedFunctionTypeMeta
type HighlightedFunctionTypeMeta = {
  parameters?: HighlightedParameter[];
  returnValue: Record<string, HighlightedProperty> | HastField;
  /** Expanded return type with resolved type references (only when returnValue is HastRoot) */
  returnValueDetailedType?: HastField;
  /** Description of the return value as HAST */
  returnValueDescription?: HastField;
  /** Original type name when return value was expanded from a named type reference */
  returnValueTypeName?: string;
  /** Expanded properties from a single-parameter type (anonymous or named) */
  expandedProperties?: Record<string, HighlightedProperty>;
  /** Type name of the expanded properties, when they came from a named type reference */
  expandedTypeName?: string;
  name: string;
  description?: HastRoot;
  /** Plain text version of description for markdown generation */
  descriptionText?: string;
  /** Plain text version of returnValue for markdown generation (when returnValue is string) */
  returnValueText?: string;
  /** Plain text version of returnValueDescription for markdown generation */
  returnValueDescriptionText?: string;
}
HighlightedHookTypeMeta
type HighlightedHookTypeMeta = {
  parameters?: HighlightedParameter[];
  returnValue: Record<string, HighlightedProperty> | HastField;
  /** Expanded return type with resolved type references (only when returnValue is HastRoot) */
  returnValueDetailedType?: HastField;
  /** Description of the return value as HAST */
  returnValueDescription?: HastField;
  /** Original type name when return value was expanded from a named type reference */
  returnValueTypeName?: string;
  /** Expanded properties from a single-parameter type (anonymous or named) */
  expandedProperties?: Record<string, HighlightedProperty>;
  /** Type name of the expanded properties, when they came from a named type reference */
  expandedTypeName?: string;
  name: string;
  description?: HastRoot;
  /** Plain text version of description for markdown generation */
  descriptionText?: string;
  /** Plain text version of returnValue for markdown generation (when returnValue is string) */
  returnValueText?: string;
  /** Plain text version of returnValueDescription for markdown generation */
  returnValueDescriptionText?: string;
}
HighlightedMethod
type HighlightedMethod = {
  /** Description with syntax highlighting as HAST */
  description?: HastField;
  parameters: HighlightedParameter[];
  returnValue: HastField;
  returnValueDescription?: HastField;
  name: string;
  descriptionText?: string;
  returnValueDescriptionText?: string;
  isStatic: boolean;
}
HighlightedParameter
type HighlightedParameter = {
  /** Description with syntax highlighting as HAST */
  description?: HastField;
  /** Example with syntax highlighting as HAST */
  example?: HastField;
  /** See-also links as HAST */
  see?: HastField;
  /** Syntax-highlighted type as HAST */
  type: HastField;
  /** Short simplified type for table display (e.g., "Union", "function") */
  shortType?: HastField;
  /** Plain text version of shortType for accessibility */
  shortTypeText?: string;
  /** Default value with syntax highlighting as HAST */
  default?: HastField;
  /** Detailed type with expanded type references as HAST */
  detailedType?: HastField;
  /** Parameter name */
  name: string;
  /** Plain text version of description for markdown generation */
  descriptionText?: string;
  /** Plain text type string */
  typeText: string;
  /** Plain text default value */
  defaultText?: string;
  /** Plain text version of example for markdown generation */
  exampleText?: string;
  /**
   * Plain text version of
   * @see for markdown generation
   */
  seeText?: string;
  /** Whether the parameter is optional */
  optional?: true;
}
HighlightedProperty
type HighlightedProperty = {
  /** Description with syntax highlighting as HAST */
  description?: HastField;
  /** Example with syntax highlighting as HAST */
  example?: HastField;
  /** See-also links as HAST */
  see?: HastField;
  /** Syntax-highlighted type as HAST */
  type: HastField;
  /** Short simplified type for table display (e.g., "Union", "function") */
  shortType?: HastField;
  /** Plain text version of shortType for accessibility */
  shortTypeText?: string;
  /** Default value with syntax highlighting as HAST */
  default?: HastField;
  /** Detailed expanded type view (only when different from basic type) */
  detailedType?: HastField;
  /** Plain text version of description for markdown generation */
  descriptionText?: string;
  /** Plain text type string */
  typeText: string;
  /** Plain text default value */
  defaultText?: string;
  /** Whether the property is required */
  required?: true;
  /** Plain text version of example for markdown generation */
  exampleText?: string;
  /**
   * Plain text version of
   * @see for markdown generation
   */
  seeText?: string;
}
HighlightedRawTypeMeta
type HighlightedRawTypeMeta = {
  /** Description with syntax highlighting as HAST */
  description?: HastField;
  /** The formatted type declaration as syntax-highlighted HAST */
  formattedCode: HastField;
  /** For enum types, the individual members with their values and descriptions */
  enumMembers?: HighlightedEnumMemberMeta[];
  /**
   * Highlighted properties extracted from the type.
   * JSDoc comments are extracted from the formattedCode via `extractTypeProps`
   * and added here with syntax-highlighted HAST fields.
   * Property paths use dot-notation for nested objects (e.g., `appearance.theme`).
   */
  properties?: Record<string, HighlightedProperty>;
  /** Display name for this type (may include dots like "Component.Root.State") */
  name: string;
  /** Plain text version of description for markdown generation */
  descriptionText?: string;
  /**
   * For re-exports, information about the component this type re-exports from.
   * When set, indicates this should be rendered as a link to the component.
   */
  reExportOf?: ReExportInfo;
  /** For DataAttributes types, the component name this type belongs to. */
  dataAttributesOf?: string;
  /** For CssVars types, the component name this type belongs to. */
  cssVarsOf?: string;
}
HighlightedTypesMeta
type HighlightedTypesMeta = (
  | { type: 'component'; data: HighlightedComponentTypeMeta }
  | { type: 'hook'; data: HighlightedHookTypeMeta }
  | { type: 'function'; data: HighlightedFunctionTypeMeta }
  | { type: 'class'; data: HighlightedClassTypeMeta }
  | { type: 'raw'; data: HighlightedRawTypeMeta }
) & {
  name: string;
  /** The anchor slug for linking to this type (e.g., "trigger" or "trigger.state") */
  slug?: string;
  /** Alternative names this type can be looked up by (e.g., flat export name like "AccordionRootProps") */
  aliases?: string[];
}
LoadServerTypesOptions
type LoadServerTypesOptions = {
  /**
   * When true, calls syncTypes to extract types from TypeScript source,
   * generate markdown, and write to disk before highlighting.
   *
   * When false, loads types from an existing types.md file using
   * loadServerTypesText, skipping type extraction and markdown generation.
   * @default false
   */
  sync?: boolean;
  /**
   * When true, replaces HAST Root nodes in the result with `{ hastJson: string }`
   * wrappers. This defers tree allocation from module-evaluation time to render
   * time: V8 only creates a string instead of the full object graph, and
   * `JSON.parse` at render time provides both deserialization and a free deep
   * clone (eliminating the need for `structuredClone`).
   * @default false
   */
  serializeHast?: boolean;
  /** Absolute path to the types.md file to generate */
  typesMarkdownPath: string;
  /** Root context directory (workspace root) */
  rootContext: string;
  /**
   * Map of variant name to file path (relative or package path).
   * For single component: `{ Default: './Component' }`
   * For multiple: `{ CssModules: './css-modules/Component', Tailwind: './tailwind/Component' }`
   */
  variants?: Record<string, string>;
  /**
   * When true, resolves library paths to their source files for watching.
   * Useful during development to watch the original source rather than built files.
   */
  watchSourceDirectly?: boolean;
  /** Options for formatting types in tables */
  formattingOptions?: FormatInlineTypeOptions;
  /**
   * Directory path for socket and lock files used for IPC between workers.
   * Useful for Windows where the default temp directory may not support Unix domain sockets.
   */
  socketDir?: string;
  /** Enable performance logging */
  performanceLogging?: boolean;
  /**
   * Options for updating the parent index page with component metadata.
   * When provided, will call syncPageIndex to update the parent directory's page.mdx
   * with props, dataAttributes, and cssVariables extracted from the component types.
   *
   * These options are passed through to syncPageIndex.
   */
  updateParentIndex?: {
    baseDir?: string;
    onlyUpdateIndexes?: boolean;
    markerDir?: string;
    errorIfOutOfDate?: boolean;
    indexFileName?: string;
  };
  /**
   * Optional regex pattern string to filter which external types to include.
   * External types are named union types (like `Orientation = 'horizontal' | 'vertical'`)
   * that are referenced in props but not exported from the component's module.
   *
   * When not provided, ALL qualifying named union types (unions of literals) will be
   * collected automatically. This is the recommended behavior for most projects.
   *
   * When provided, only external types whose names match this pattern will be collected.
   * @example undefined // Collect all qualifying external types (recommended)
   * @example '^(Orientation|Alignment|Side)$' // Only include specific types
   */
  externalTypesPattern?: string;
  /** Custom ordering configuration for sorting props, data attributes, exports, etc. */
  ordering?: OrderingConfig;
  /**
   * Pattern/replacement pairs to apply to JSDoc descriptions.
   * Each entry has a `pattern` (regex string) and `replacement` string.
   */
  descriptionReplacements?: DescriptionReplacement[];
}
LoadServerTypesResult
type LoadServerTypesResult = {
  /** Export data where each export has a main type and related additional types */
  exports: Record<string, ExportData>;
  /** Top-level non-namespaced types not claimed by any variant-only group */
  additionalTypes: HighlightedTypesMeta[];
  /**
   * Types belonging to variant-only groups (variants with no main export).
   * Keyed by variant name, containing the types from that variant.
   */
  variantOnlyAdditionalTypes: Record<string, HighlightedTypesMeta[]>;
  /**
   * Maps variant names to the type names that originated from that variant.
   * Used for namespace imports (e.g., `* as Types`) to filter additionalTypes
   * to only show types from that specific module.
   */
  variantTypeNames: Record<string, string[]>;
  /** All dependencies that should be watched for changes */
  allDependencies: string[];
  /** Type name map from variant processing */
  typeNameMap?: Record<string, string>;
  /**
   * Platform-scoped anchor maps for linking type references in code.
   * Keys include both dotted names ("Accordion.Trigger") and flat names ("AccordionTrigger").
   */
  anchorMap: { js?: Record<string, string>; css?: Record<string, string> };
}
SerializedHastRoot

A JSON-serialized wrapper around a HastRoot. Defers tree allocation to render time: V8 stores only a string, and JSON.parse at render time provides both deserialization and a free deep clone.

type SerializedHastRoot = { hastJson: string }