> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt. # Library docs generator Beta > Generate MDX documentation pages from your Python or C++ library source code and include them in your Fern Docs site. The library docs generator parses your **Python or C++** library source code and generates MDX documentation pages for modules, classes, functions, methods, and parameters. Generated pages are added to your Fern Docs site with hierarchical navigation. Cross-links are automatic. When a fully qualified identifier appears in a code block — for example, in a class signature or type annotation — the generator links it to the page documenting that symbol, so readers can jump straight to the definition. ## Configuration #### Define your libraries in \`docs.yml\` Add a `libraries` entry to your `docs.yml` file. Each library needs an `input` source, an `output.path` (where generated MDX files are written), and a `lang` (`python` or `cpp`). The input source can be a `git` URL or a local `path`. A `git` input is parsed on Fern's servers by default, or on your machine with the `--local` flag. A `path` input requires `--local`. A `git` input reads the repository's default branch. Set `ref` to a branch, tag, or commit SHA to generate from source that hasn't merged yet. #### git input **`docs.yml`** ```yaml docs.yml libraries: plant-core: input: git: https://github.com/acme/plant-core-cpp # repository URL subpath: packages/plant-core # optional, for monorepos ref: feature/new-planting-api # optional, defaults to the default branch output: path: ./static/plant-core-docs # relative to fern/ directory lang: cpp # python or cpp config: doxyfile: ./Doxyfile # optional, C++ only ``` #### path input **`docs.yml`** ```yaml docs.yml libraries: plant-core: input: path: ../plant-core-cpp # local library source, relative to fern/ directory output: path: ./static/plant-core-docs # relative to fern/ directory lang: cpp # python or cpp config: doxyfile: ./Doxyfile # optional, C++ only ``` You can define [multiple libraries](#multiple-libraries-example) in the same file. #### Add to navigation Point a [`folder:` entry](/learn/docs/configuration/navigation#add-a-folder) in your navigation at the same directory you set as `output.path`. Fern discovers every MDX file in that folder and mirrors its subfolder structure into sidebar sections. **`docs.yml`** ```yaml docs.yml {8} navigation: - section: Getting started contents: - page: Overview path: ./pages/overview.mdx - section: Plant SDK Reference contents: - folder: ./static/plant-sdk-docs ``` #### Generate the library docs Run the [`fern docs md generate`](/learn/cli-api-reference/cli-reference/docs-commands#fern-docs-md-generate) command to generate MDX files from your library source code: #### Remote parsing ```bash fern docs md generate ``` The command sends the repository URL to Fern's servers for parsing. Requires a `git` input. #### Local parsing ```bash fern docs md generate --local ``` The `--local` flag parses the source on your machine instead of on Fern's servers, which is useful for iterating on documentation without pushing to a remote repository, and doesn't require you to be logged in to Fern. Both input types work: a `path` input is read in place, and a `git` input is checked out at its `ref` using your local git credential configuration. Local parsing runs each parser inside a Docker container, so [Docker](https://docs.docker.com/get-docker/) must be running on your machine. Verify with `docker ps`. For C++ libraries, the parser uses the source root (your `path` directory, or the repository root for a `git` input) as its scope. Input directives in your Doxyfile don't change that scope: Fern honors only [a few Doxyfile settings](#configuration-reference) and ignores the rest. If you have multiple libraries configured, `fern docs md generate` processes all libraries in parallel. Use `--library plant-sdk` to generate docs for a specific library only. The generated docs form a navigation section with pages for each module, class, function, and type in your library. For C++ libraries, groups defined with `@defgroup`, `@ingroup`, or `@addtogroup` also get index pages in a `groups/` folder inside `output.path`: each lists the group's description, its members by kind, and its subgroups (nested as subfolders). Member documentation stays on the symbol pages, groups with no members are skipped, and the `folder:` navigation entry picks the group pages up without changes. #### Preview locally Run the local development server to see your library docs alongside the rest of your site: ```bash fern docs dev ``` You can also generate a shareable preview URL: ```bash fern generate --docs --preview ``` #### Publish Publish your library documentation: ```bash fern generate --docs ``` #### Multiple libraries example You can define and reference multiple libraries in the same `docs.yml`: **`docs.yml`** ```yaml docs.yml libraries: plant-python-sdk: input: git: https://github.com/acme/plant-sdk-python output: path: ./static/python-docs lang: python plant-core: input: git: https://github.com/acme/plant-core-cpp output: path: ./static/cpp-docs lang: cpp navigation: - section: Python SDK Reference contents: - folder: ./static/python-docs - section: C++ API Reference contents: - folder: ./static/cpp-docs ``` ## Customize generated docs (optional) You can reorganize the output directory to restructure the sidebar navigation. Move, rename, or nest files and subfolders, and Fern picks up the new layout on the next `fern docs dev` or publish. For example, splitting `./static/plant-sdk-docs` into `getting-started/` and `reference/` subfolders produces two sidebar sections: **`docs.yml`** ```yaml docs.yml {4,6} navigation: - section: Plant SDK Reference contents: - folder: ./static/plant-sdk-docs/getting-started title: Getting started - folder: ./static/plant-sdk-docs/reference title: API reference ``` You can also edit page content by modifying the MDX files directly — generated pages are [standard MDX](/learn/docs/writing-content/markdown-basics), so you can add prose, examples, callouts, or any [component](/learn/docs/writing-content/components/overview). Re-running `fern docs md generate` overwrites everything in `output.path`, so commit your customizations first, and keep hand-edited pages outside the output directory if you plan to regenerate. ## Configuration reference **`input.git`** `string` GitHub URL of the repository containing the library source code. Parsed on Fern's servers, or on your machine with `--local`. Mutually exclusive with `input.path`. --- **`input.subpath`** `string` Path within the repository to the library source. Only valid with `input.git`. Useful for monorepos. --- **`input.ref`** `string` Git ref to check out: a branch, tag, or commit SHA. Only valid with `input.git`. Defaults to the repository's default branch. --- **`input.path`** `string` Local filesystem path to the library source, relative to the `fern/` directory. Requires `--local` flag. Mutually exclusive with `input.git`. --- **`output.path`** `string` — required Directory where the generated MDX files are written, relative to the `fern/` directory. --- **`lang`** `string` — required The language of the library. Supported values: `python`, `cpp`. --- **`config.doxyfile`** `string` Path to a custom [Doxyfile](https://www.doxygen.nl/manual/config.html). C++ only. Fern reads four settings from it and applies them to its own doxygen configuration: `ALIASES`, `PREDEFINED`, `FILE_PATTERNS`, and `OPTIMIZE_OUTPUT_FOR_C`. `ALIASES` supports parameterized macros and backslash line continuations. Every other setting is ignored, including `INPUT`, `INPUT_FILTER`, `GENERATE_XML`, and the `@INCLUDE` and `@INCLUDE_PATH` directives. Publishing fails when one of the four supported settings has an invalid value: a space or shell metacharacter in `FILE_PATTERNS`, a value other than `YES` or `NO` for `OPTIMIZE_OUTPUT_FOR_C`, an `ALIASES` entry that isn't an alias definition, a trailing backslash, or doxygen's `$(VAR)` environment-variable expansion. Doxyfile content over 262,144 characters is also rejected. --- > Generate MDX documentation pages from your Python or C++ library source code and include them in your Fern Docs site.