Warning
This is an internal project, and is not intended for public use. No support or stability guarantees are provided.
The core server-side function for loading and formatting TypeScript type metadata. This function extracts types from your source files and returns structured data ready for documentation generation or rendering.
loadServerTypesMeta handles the TypeScript → formatted types pipeline:
DataAttributes and CssVars meta files from entrypoints and re-exported directoriesThis function is separated from syncTypes to allow direct access to formatted types without markdown generation. Use this when you need type metadata but don't need to write a types.md file.
This function and loadServerTypesText both produce a TypesSourceData structure — the shared contract that loadServerTypes consumes. See the loadServerTypes overview for details on this shared structure.
Note: Type highlighting is handled separately by
loadServerTypes, which callssyncTypes(which uses this function) and then applieshighlightTypesandhighlightTypesMetato convert plain text types to syntax-highlighted HAST.
import { loadServerTypesMeta } from '@mui/internal-docs-infra/pipeline/loadServerTypesMeta';
const result = await loadServerTypesMeta({
typesMarkdownPath: '/absolute/path/to/types.md',
rootContext: '/absolute/path/to/project',
variants: { Default: '@base-ui/react/checkbox' },
formattingOptions: {
shortTypeUnionPrintWidth: 40,
defaultValueUnionPrintWidth: 40,
},
});
// Organized type exports (e.g., { Root: { type, additionalTypes }, Trigger: { type, additionalTypes } })
result.exports;
// Top-level types not attached to a specific export (e.g., standalone type aliases)
result.additionalTypes;
// Files to watch for changes
result.allDependencies;
// External types referenced in props but not publicly exported (e.g., Orientation = 'horizontal' | 'vertical')
result.externalTypes;
// Derived name for display
result.resourceName;
When documenting types from multiple exports, pass each as a separate variant entry. Each variant is a named entrypoint whose types are extracted independently then merged:
const result = await loadServerTypesMeta({
typesMarkdownPath: '/absolute/path/to/types.md',
rootContext: '/absolute/path/to/project',
variants: {
Checkbox: '@base-ui/react/checkbox',
Button: '@base-ui/react/button',
},
});
// Which type names originated from each variant
result.variantTypeNames; // { Checkbox: ['Root', 'Root.Props', ...], Button: ['Root', ...] }
// Per-variant typeNameMaps (flat name → dotted name)
result.variantTypeNameMaps;
Use descriptionReplacements to transform or strip patterns from extracted JSDoc descriptions. Each entry specifies a regex pattern, a replacement string, and optional flags. Replacements are applied to all descriptions: components, hooks, functions, classes, props, parameters, enum members, and raw types.
const result = await loadServerTypesMeta({
typesMarkdownPath: '/absolute/path/to/types.md',
rootContext: '/absolute/path/to/project',
variants: { Default: '@base-ui/react/checkbox' },
// Strip "Documentation: <url>" suffixes from descriptions
descriptionReplacements: [{ pattern: '\\n\\nDocumentation:.*$', replacement: '', flags: 'm' }],
});
By default, all qualifying external types (named unions of literals referenced in props) are collected. Use externalTypesPattern to limit which ones are included:
const result = await loadServerTypesMeta({
typesMarkdownPath: '/absolute/path/to/types.md',
rootContext: '/absolute/path/to/project',
variants: { Default: '@base-ui/react/checkbox' },
externalTypesPattern: '^(Orientation|Alignment|Side)$',
});
| Function | Purpose | Writes Files | Returns |
|---|---|---|---|
loadServerTypesMeta | Load & format types | ❌ | Organized plain-text types |
syncTypes | Sync types.md file | ✅ types.md | Plain-text types + exports structure |
loadServerTypes | Full pipeline with highlighting | ✅ types.md | HAST-highlighted types |
~500-1200ms to create the TypeScript program and parse types (depends on project size)
~100-140ms using the cached language service and file data
~87-92% improvement vs. creating separate language services per process, thanks to the socket-based IPC sharing a single TypeScript program
Loads tsconfig.json with support for extends inheritance. Results are cached with a file watcher that invalidates the cache on changes, so config updates take effect without restarting the dev server.
Resolves variant paths to actual file system locations, handling three categories:
paths configuration (e.g., @base-ui/react/*)watchSourceDirectly is enabled (auto-detected when tsconfig path aliases are used), follows .d.ts.map source maps to locate the original TypeScript source files instead of declaration files.Recursively walks entrypoint directories and re-exported directories to discover DataAttributes and CssVars files. Re-exported directories are found by parsing relative exports (e.g., export * from '../menu/') from the entrypoint source files.
Type extraction is offloaded to a dedicated worker thread. Inside the worker:
LanguageServiceHost singleton that caches file contents and tracks versions for incremental updatestypescript-api-extractor's parseFromProgram, which extracts components, hooks, functions, classes, type aliases, and interfaces with their full type treesAccordionRootState → Accordion.Root.State), only when both the flat and dotted names exist as exportsBefore formatting, builds a map from original type names to their canonical export names. This map is derived from two sources on the parsed exports:
reexportedFrom — when a component is re-exported under a new name (e.g., AlertDialog.Trigger re-exports DialogTrigger)extendsTypes — when an interface extends another (e.g., AlertDialog.Root.Props extends Dialog.Props)This map drives the type rewriting in the next step, ensuring that type references in documentation use the canonical namespaced names rather than internal names from the source library.
Converts raw TypeScript exports to formatted metadata based on their detected category:
formatComponentData) — extracts props, data attributes, CSS variables. Matches DataAttributes/CssVars by original component name, with a fallback that searches by short name and prefers candidates whose prefix appears in the component's namespace.formatHookData) — extracts parameters/properties and return value. Handles overloads by picking the longest signature and marking extra parameters as optional.formatFunctionData) — same structure as hooks, without the use name prefix requirement.formatClassData) — extracts constructor parameters, properties, and methods.formatRawData) — formats the type declaration as code. Special handling for enums (member tables), DataAttributes, and CssVars types.Each formatter calls rewriteTypeStringsDeep at the end, which applies the type compatibility map from step 5 to normalize all type references. Rewrites use word-boundary matching to prevent partial replacements (e.g., Dialog won't match inside AlertDialog).
During formatting, formatType also collects external types — types referenced in props that aren't publicly exported from the component's module. This includes named union types (e.g., Orientation = 'horizontal' | 'vertical'), named function types, and external type references that resolve to unions or literals. Collection happens inline during type formatting rather than as a separate tree walk, so only types that actually appear in the formatted output are collected.
Note: When a hook or function has a single anonymous object parameter (e.g.,
function useHook(params: { enabled: boolean })), the object's fields are expanded into individual properties instead of being listed as a single parameter. This provides a cleaner documentation layout for options-style APIs.
For single-variant exports with sub-components (e.g., Accordion.Root, Accordion.Trigger), groups types by component:
// Before: { Default: { types: [Accordion.Root, Accordion.Trigger, ...] } }
// After: { "Accordion.Root": { types: [...] }, "Accordion.Trigger": { types: [...] } }
Grouping only activates when there are actual sub-components — 2-part names that are components, hooks, functions, or classes (not just raw type suffixes like Button.Props). Once active:
Accordion.Root.State): grouped under the first two parts (Accordion.Root)Accordion.Root): becomes its own groupToolbar.Orientation): remain in the "Default" groupDirectionProvider): remain in the "Default" groupSeveral normalization passes clean up the type list:
DirectionProvider exported from both index.ts and DirectionProvider.tsx), keeps one entry, preferring component/hook types over raw typesAccordionRootState when Accordion.Root.State is present), since the type name map confirms they represent the same typeAccordion.Root.State gets alias AccordionRootState), so consumers can look up types by either nameIdentifies when raw type exports are re-exports of component data by matching the pattern {ComponentName}.{Suffix}:
Button.Props → marked as re-export of Button's props tableCheckbox.DataAttributes → marked as re-export of Checkbox's data attributesCheckbox.CssVars → marked as re-export of Checkbox's CSS variablesTypes are organized into an exports structure for UI consumption via organizeTypesByExport, which separates main types (components, hooks, functions, classes) from additional types (raw types like Props, State) and computes slugs for anchor linking.
The function uses a worker-based architecture for efficient TypeScript processing:
LanguageServiceHost singleton)typescript-api-extractorThe worker manager uses a Symbol.for() key on the process object to ensure the singleton persists across Turbopack module contexts, where each compilation gets a separate globalThis scope but shares the same Node.js process. The TypeScript language service in the worker uses a simpler globalThis singleton since worker threads have a single module context.
For multi-process environments (e.g., Next.js with multiple workers):
Loads and formats TypeScript types from source files.
This function handles:
The result can be used by syncTypes for markdown generation or by other consumers.
| Property | Type | Description |
|---|---|---|
| typesMarkdownPath | | Absolute path to the types.md file (used for deriving paths) |
| rootContext | | Root context directory (workspace root) |
| variants | | Map of variant name to file path (relative or package path).
Each variant is an entrypoint whose types are extracted independently then merged.
For single component: |
| watchSourceDirectly | | When true, resolves library paths to their source files for watching. Useful during development to watch the original source rather than built files. |
| formattingOptions | | Options for formatting types in tables |
| socketDir | | 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. |
| externalTypesPattern | | Optional regex pattern string to filter which external types to include.
External types are named union types (like 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 | | Custom ordering configuration for sorting props, data attributes, exports, etc. |
| descriptionReplacements | | Pattern/replacement pairs to apply to JSDoc descriptions.
Each entry has a |
Promise<LoadServerTypesMetaResult>type ClassTypeMeta = {
name: string;
description?: HastRoot;
/** Plain text version of description for markdown generation */
descriptionText?: string;
/** Constructor parameters */
constructorParameters: FormattedParameter[];
/** Public instance properties */
properties: Record<string, FormattedProperty>;
/** Public instance methods */
methods: Record<string, FormattedMethod>;
/** Type parameters (generics) if any */
typeParameters?: string[];
}type ComponentTypeMeta = {
name: string;
description?: HastRoot;
/** Plain text version of description for markdown generation */
descriptionText?: string;
props: Record<string, FormattedProperty>;
dataAttributes: Record<string, FormattedEnumMember>;
cssVariables: Record<string, FormattedEnumMember>;
}type DescriptionReplacement = {
/** Regex pattern string to match in descriptions */
pattern: string;
/** Replacement string (supports regex replacement syntax like $1) */
replacement: string;
/** Regex flags (e.g. 'g', 'm', 'gm'). Defaults to no flags. */
flags?: string;
}type FormatInlineTypeOptions = {
/**
* Maximum line width before union types in shortType fields are split across multiple lines.
* When a union type exceeds this width, it will be formatted with each
* member on a separate line with leading pipe characters.
* @default 40
*/
shortTypeUnionPrintWidth?: number;
/**
* Maximum line width before union types in defaultValue fields are split across multiple lines.
* When a union type exceeds this width, it will be formatted with each
* member on a separate line with leading pipe characters.
* @default 40
*/
defaultValueUnionPrintWidth?: number;
/**
* Maximum line width for Prettier formatting of type definitions.
* @default 60
*/
typePrintWidth?: number;
}type FormattedEnumMember = {
/** Description of the enum member as parsed markdown HAST */
description?: Root;
/** Plain text version of description for markdown generation */
descriptionText?: string;
/**
* Type annotation from JSDoc
* @type tag
*/
type?: string;
}type FormattedParameter = {
/** Parameter name */
name: string;
/** Plain text type string */
typeText: string;
/** Plain text default value */
defaultText?: string;
/** Whether the parameter is optional */
optional?: true;
/** Description from JSDoc as parsed markdown HAST */
description?: Root;
/** Plain text version of description for markdown generation */
descriptionText?: string;
/** Example usage as parsed markdown HAST */
example?: Root;
/** Plain text version of example for markdown generation */
exampleText?: string;
/** @see as parsed markdown HAST */
see?: Root;
/**
* Plain text version of
* @see for markdown generation
*/
seeText?: string;
}type FormattedProperty = {
/** Plain text type string */
typeText: string;
/** Plain text default value */
defaultText?: string;
/** Whether the property is required */
required?: true;
/** Description as parsed markdown HAST */
description?: Root;
/** Plain text version of description for markdown generation */
descriptionText?: string;
/** Example usage as parsed markdown HAST */
example?: Root;
/** Plain text version of example for markdown generation */
exampleText?: string;
/** @see as parsed markdown HAST */
see?: Root;
/**
* Plain text version of
* @see for markdown generation
*/
seeText?: string;
}type FunctionTypeMeta = {
name: string;
description?: HastRoot;
/** Plain text version of description for markdown generation */
descriptionText?: string;
/** Ordered function parameters */
parameters?: FormattedParameter[];
/**
* Expanded properties from a single anonymous object parameter.
* When populated, `parameters` should be omitted and headings should
* say "Properties" instead of "Parameters".
*/
expandedProperties?: Record<string, FormattedProperty>;
/** Return value - either plain text string or object with properties (like hook return values) */
returnValue: Record<string, FormattedProperty> | string;
/** Plain text version of returnValue for markdown generation (when returnValue is string) */
returnValueText?: string;
/** Description of the return value (parsed markdown as HAST) */
returnValueDescription?: HastRoot;
/** Plain text version of returnValueDescription for markdown generation */
returnValueDescriptionText?: string;
}type HookTypeMeta = {
name: string;
description?: HastRoot;
/** Plain text version of description for markdown generation */
descriptionText?: string;
/** Ordered function parameters */
parameters?: FormattedParameter[];
/**
* Expanded properties from a single anonymous object parameter.
* When populated, `parameters` should be omitted and headings should
* say "Properties" instead of "Parameters".
*/
expandedProperties?: Record<string, FormattedProperty>;
returnValue: Record<string, FormattedProperty> | string;
/** Plain text version of returnValue for markdown generation (when returnValue is string) */
returnValueText?: string;
/** Description of the return value (parsed markdown as HAST) */
returnValueDescription?: HastRoot;
/** Plain text version of returnValueDescription for markdown generation */
returnValueDescriptionText?: string;
}type LoadServerTypesMetaOptions = {
/** Absolute path to the types.md file (used for deriving paths) */
typesMarkdownPath: string;
/** Root context directory (workspace root) */
rootContext: string;
/**
* Map of variant name to file path (relative or package path).
* Each variant is an entrypoint whose types are extracted independently then merged.
* For single component: `{ Default: '@base-ui/react/checkbox' }`
* For multiple: `{ Checkbox: '@base-ui/react/checkbox', Button: '@base-ui/react/button' }`
*/
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;
/**
* 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[];
}type LoadServerTypesMetaResult = {
/** All dependencies that should be watched for changes */
allDependencies: string[];
/** Type name map from variant processing */
typeNameMap?: Record<string, string>;
/**
* External types discovered during formatting.
* These are types referenced in props/params that are not publicly exported,
* but whose definitions are useful for documentation (e.g., union types).
* Map from type name to its definition string.
*/
externalTypes: Record<string, string>;
/** Resource name derived from the types path */
resourceName: string;
/** Export data where each export has a main type and related additional types */
exports: Record<string, { type: TypesMeta; additionalTypes: TypesMeta[] }>;
/** Top-level non-namespaced types not claimed by any variant-only group */
additionalTypes: TypesMeta[];
/**
* Types belonging to variant-only groups (variants with no main export).
* Keyed by variant name, each entry contains the types from that variant.
* These are separated from `additionalTypes` to avoid duplication.
*/
variantOnlyAdditionalTypes: Record<string, TypesMeta[]>;
/**
* 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[]>;
/**
* Maps variant names to their per-variant typeNameMaps.
* Used for Canonical Types annotations showing which variants contain each type.
*/
variantTypeNameMaps: Record<string, Record<string, string>>;
}type RawTypeMeta = {
/** Display name for this type (may include dots like "Component.Root.State") */
name: string;
/** Description parsed from JSDoc as HAST */
description?: HastRoot;
/** Plain text version of description for markdown generation */
descriptionText?: string;
/**
* The formatted type declaration as plain text (e.g., "type ButtonProps = { ... }").
* Will be highlighted to HAST in loadServerTypes.
*/
formattedCode: string;
/**
* For enum types, the individual members with their values and descriptions.
* When present, indicates this type should be rendered as an enum table.
*/
enumMembers?: EnumMemberMeta[];
/**
* 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;
/**
* For object types, the individual properties with their types and descriptions.
* Used by the enhancement stage to convert named return type references into property tables.
*/
properties?: Record<string, FormattedProperty>;
}type ReExportInfo = {
/** Display name of the component (e.g., "Trigger" from "Accordion.Trigger") */
name: string;
/** Anchor slug for linking (e.g., "#trigger") */
slug: string;
/** What kind of type this re-exports */
suffix: 'props' | 'css-variables' | 'data-attributes';
}type TypesMeta = (
| { type: 'class'; data: ClassTypeMeta }
| { type: 'component'; data: ComponentTypeMeta }
| { type: 'hook'; data: HookTypeMeta }
| { type: 'function'; data: FunctionTypeMeta }
| { type: 'raw'; data: RawTypeMeta }
) & {
name: string;
slug?: string;
/** Alternative names this type can be looked up by (e.g., flat export name like "AccordionRootState") */
aliases?: string[];
}loadServerTypes — Full pipeline with syntax highlightingsyncTypes — Sync types.md file from metadataloadPrecomputedTypes — Webpack/Turbopack loader that uses syncTypestypescript-api-extractor — Underlying type extraction library