CLI and Node library to generate documentation for Salesforce Apex classes.
ApexDocs is a non-opinionated documentation generator for Salesforce Apex classes. It can output documentation in Markdown format, which allows you to use the Static Site Generator of your choice to create a documentation site that fits your needs, hosted in any static web hosting service.
ApexDocs generates Markdown files, which can be integrated into any Static Site Generation (SSG) engine, (e.g. Jekyll, Vitepress, Hugo, Docosaurus, etc.) to create a documentation site that fits your needs.
This gives you the flexibility to create beautiful sites by leveraging your preferred SSG engine, which usually provides a wide range of themes, dark mode support, and other features out of the box.

These are examples of documentation sites generated using Vitepress.
Head over to the examples/vitepress folder to see the code.
The extra flexibility also lets you integrate the output documentation with your existing documentation site, allowing you to match the look and feel of your existing site.
<img src="https://github.com/cesarParra/apexdocs/raw/v3.24.0/imgs/integration.png" alt="Integration" width="70%" />
OpenApi REST definitions can be visualized using a tool like ReDoc, Swagger UI, or any other OpenApi viewer.
<img src="https://github.com/cesarParra/apexdocs/raw/v3.24.0/imgs/redocly.png" alt="OpenApi" width="70%" />
This repo contains several other example implementations in the examples directory, showcasing how to integrate
with different tools.
Here are some live projects using ApexDocs:
@RestResource classesnpm i -g @cparra/apexdocs
Run the following command to generate markdown files for your global Salesforce Apex classes and custom objects:
apexdocs markdown -s force-app
# Use sfdx-project.json as the source of directories
apexdocs markdown --useSfdxProjectJson
# Specify multiple source directories
apexdocs markdown --sourceDir force-app force-lwc force-utils
Run the following command to generate an OpenApi REST specification for your Salesforce Apex classes
annotated with @RestResource:
apexdocs openapi -s force-app
Run the following command to generate a changelog for your Salesforce Apex classes:
apexdocs changelog --previousVersionDir force-app-previous --currentVersionDir force-app
markdown
| Flag | Alias | Description | Default | Required |
|---|---|---|---|---|
--sourceDir |
-s |
The directory or directories where the source files are located. | N/A | * |
--useSfdxProjectJson |
N/A | Read source directories from sfdx-project.json packageDirectories. Cannot be used with --sourceDir. |
false |
* |
--sfdxProjectPath |
N/A | Path to directory containing sfdx-project.json (defaults to current directory). Only used with --useSfdxProjectJson. |
process.cwd() |
No |
--targetDir |
-t |
The directory where the generated files will be placed. | docs |
No |
--scope |
-p |
A list of scopes to document. Values should be separated by a space, e.g --scope global public namespaceaccessible. | [global] |
No |
--customObjectVisibility |
-v |
Controls which custom objects are documented. Values should be separated by a space. | [public] |
No |
--defaultGroupName |
N/A | The default group name to use when a group is not specified. | Miscellaneous |
No |
--namespace |
N/A | The package namespace, if any. If provided, it will be added to the generated files. | N/A | No |
--sortAlphabetically |
N/A | Sorts files appearing in the Reference Guide alphabetically, as well as the members of a class, interface or enum alphabetically. If false, the members will be displayed in the same order as the code. | false |
No |
--includeMetadata |
N/A | Whether to include the file's meta.xml information: Whether it is active and the API version | false |
No |
--linkingStrategy |
N/A | The strategy to use when linking to other classes. Possible values are relative, no-link, and none |
relative |
No |
--customObjectsGroupName |
N/A | The name under which custom objects will be grouped in the Reference Guide | Custom Objects |
No |
--triggersGroupName |
N/A | The name under which triggers will be grouped in the Reference Guide | Triggers |
No |
--experimentalLwcSupport |
N/A | Whether to document LWC files or not. | false |
No |
--lwcGroupName |
N/A | The name under which Lightning Web Components will be grouped in the Reference Guide | Lightning Web Components |
No |
--includeFieldSecurityMetadata |
N/A | Whether to include the compliance category and security classification for fields in the generated files. | false |
No |
--includeInlineHelpTextMetadata |
N/A | Whether to include the inline help text for fields in the generated files. | false |
No |
--parallelReflection |
N/A | Parallelize CPU-heavy reflection via worker threads. | true |
No |
--parallelReflectionMaxWorkers |
N/A | Maximum number of worker threads to use for parallel reflection. Defaults to a reasonable value based on CPU count. | N/A | No |
--debug |
N/A | Enable debug logging. Prints file-by-file parsing progress and success/failure. | false |
No |
Note: The
*in the Required column indicates that one of the source directory options must be specified: ---sourceDir(single directory or array of directories) ---useSfdxProjectJson(read from sfdx-project.json)These options are mutually exclusive - you cannot use more than one at the same time.
The linking strategy determines how ApexDocs will link to other classes in your documentation. For example,
if I have class A that links through class B (e.g. through an {@link B} tag, the @see tag,
takes it as a param, returns it from a method, etc.), the linking strategy will determine how the link to class B is
created.
These are the possible values for the linkingStrategy flag:
relativeCreate a relative link to the class file.
So if both classes are in the same directory, the link will be created as
[B](B.md).
If the classes are in different directories, the link will be created as [B](../path/to/B.md)
no-linkDoes not create a link at all. The class name will be displayed as plain text.
noneDoes not apply any kind of logic. Instead, the links will be determined by the path to the file
from the root of the documentation site OR by whatever path you have returned in the transformReference hook
for the file.
apexdocs markdown -s force-app -t docs -p global public namespaceaccessible -n MyNamespace
openapi
| Flag | Alias | Description | Default | Required |
|---|---|---|---|---|
--sourceDir |
-s |
The directory where the source files are located. | N/A | Yes |
--targetDir |
-t |
The directory where the generated files will be placed. | docs |
No |
--fileName |
N/A | The name of the OpenApi file. | openapi.json |
No |
--namespace |
N/A | The package namespace, if any. This will be added to the API file Server Url. | N/A | No |
--title |
N/A | The title of the OpenApi file. | Apex REST API |
No |
--apiVersion |
N/A | The version of the API. |
$ claude mcp add apexdocs \
-- python -m otcore.mcp_server <graph>