Library docs generator Beta
Library docs generator Beta
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. Both input types are parsed on your machine by default. A git input can also be parsed on Fern’s servers with the --remote flag.
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
path input
You can define multiple libraries in the same file.
Generate the library docs
Run the fern docs md generate command to generate MDX files from your library source code:
Local parsing
Remote parsing
By default, the command parses the source on your machine, 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 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. config.include and config.exclude narrow the scan to paths inside the source root but can’t reach outside it, and Fern honors only a few Doxyfile settings.
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. To also browse the reference by source file, set config.organize-by: header.
C++ pages also reflect C idioms: a struct declared with typedef struct X {...} X; shows the typedef line on its page, values of an anonymous enum { A, B }; are listed under “Anonymous enumerations” on the enums index page, and array fields keep their extents (char id[64]).
Multiple libraries example
You can define and reference multiple libraries in the same docs.yml:
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:
You can also edit page content by modifying the MDX files directly — generated pages are standard MDX, so you can add prose, examples, callouts, or any component. 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
GitHub URL of the repository containing the library source code. Parsed on your machine by default, or on Fern’s servers with --remote. Mutually exclusive with input.path.
Path within the repository to the library source. Only valid with input.git. Useful for monorepos.
Git ref to check out: a branch, tag, or commit SHA. Only valid with input.git. Defaults to the repository’s default branch.
Local filesystem path to the library source, relative to the fern/ directory. Parsed on your machine; not supported with --remote. Mutually exclusive with input.git.
Directory where the generated MDX files are written, relative to the fern/ directory.
The language of the library. Supported values: python, cpp.
config.organize-by
How C++ pages are organized. C++ only; generation fails if it’s set on a library with another lang. Supported values:
kind: Groups pages by symbol kind, in folders such asfunctions/andstructs/.header: Keeps thekindlayout and adds aheaders/folder with an index page and one page per source header. Each header page shows its#includeline and the file’s Doxygen description, links to the classes, functions, enums, typedefs, variables, and macros it declares, and lists the headers it includes.
config.include
Files or directories to scan, relative to the source root (input.path, or input.subpath within a git repository). C++ only. When set, only these paths are parsed (doxygen’s INPUT), which keeps vendored and internal code in a large source tree out of the generated docs. Generation fails if a path is absolute, contains .., resolves outside the source root, or doesn’t exist.
config.exclude
Files, directories, or glob patterns to leave out of the scan. C++ only. Paths are relative to the source root and become doxygen’s EXCLUDE. Entries containing * or ? are matched against full file paths as doxygen’s EXCLUDE_PATTERNS, for example */detail/* or *_priv.h. A path that doesn’t exist is skipped with a warning.
config.exclude-symbols
Symbol names or glob patterns to leave out of the generated docs, for example INTERNAL_* or detail::* (doxygen’s EXCLUDE_SYMBOLS). C++ only.
Path to a custom Doxyfile. C++ only. Fern reads these settings from it and applies them to its own doxygen configuration: ALIASES, PREDEFINED, FILE_PATTERNS, OPTIMIZE_OUTPUT_FOR_C, and the source selection settings INPUT, EXCLUDE, EXCLUDE_PATTERNS, and EXCLUDE_SYMBOLS. ALIASES supports parameterized macros and backslash line continuations. When both are set, config.include replaces the Doxyfile’s INPUT list, and config.exclude and config.exclude-symbols add to its exclusions.
Every other setting is ignored, including INPUT_FILTER, GENERATE_XML, and the @INCLUDE and @INCLUDE_PATH directives. Publishing fails when a supported setting 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, an INPUT or EXCLUDE path that’s absolute or contains .., a trailing backslash, or doxygen’s $(VAR) environment-variable expansion. Doxyfile content over 262,144 characters is also rejected.
config.slug-style
How symbol names become page filenames and URLs. C++ only; generation fails if it’s set on a library with another lang. Supported values:
compact: Keeps the symbol name as the filename, and the URL drops underscores.doca_pcc_dev_get_port_counter_idbecomes/docapccdevgetportcounterid.hyphenated: Replaces underscores with hyphens, so the URL keeps word boundaries.doca_pcc_dev_get_port_counter_idbecomes/doca-pcc-dev-get-port-counter-id.
Changing this value on an existing site renames every generated page, so links to the old URLs need redirects. When two symbols map to the same URL, the public name keeps the plain URL and the _-prefixed name gets a -2 suffix.