Package Management

npm packages, often referred to as dependencies, are software libraries for Node.js. When installed, these packages may provide additional or alternate functionality for Antora or Asciidoctor in the form of extensions.

This page explains how to add npm packages to your project for the purpose of building your Antora-based site.

Overview

There are several methods you can use to specify which packages the plugin should install. These methods are mutually exclusive, except where noted.

  • the plugin configuration in pom.xml

    • This configuration can be populated using user properties if not already defined in the plugin configuration.

  • package.json, with or without package-lock.json

    • When a qualifying package.json is present, the plugin ignores packages specified using any other method. The playbookProvider parameter is also ignored.

  • PACKAGES comment line in a playbook retrieved by the playbook provider

    • Additional packages can still be added or replaced using the additionalPackages parameter, but not the packages parameter.

You should choose which method you’d like to use for your project and stick with it.

Register and enable extensions

Even if an extension is installed, Antora won’t use it unless it’s registered and enabled. To learn about registering and enabling Antora and Asciidoctor extensions, consult the following resources:

packages parameter

Packages can be defined using the packages parameter in the plugin configuration in the project’s pom.xml file. These packages are installed in addition to the the antora package itself. This is the preferred method for managing packages in your playbook project.

pom.xml
<configuration>
  <packages>
    <package>@antora/lunr-extension</package>
  </packages>
</configuration>

The value of the packages parameter contains a list of Node.js packages you want to install. The value of each entry is the name of the package followed by an optional version. The version is separated from the name by @ (e.g., @antora/lunr-extension or @antora/lunr-extension@1.0.0-alpha.8). For example:

pom.xml
<configuration>
  <packages>
    <package>@antora/lunr-extension@1.0.0-alpha.8</package>
  </packages>
</configuration>

The version can be an exact version (e.g., 1.0.0), a version tag (e.g., latest), or a version range specifier (e.g., ~2.1). This syntax is the same as when installing dependencies using npm i.

Additional packages may be specified using the additionalPackages parameter or the antora.additionalPackages user property mapped to this parameter.

The antora package, as well as any packages listed in the configuration, are automatically downloaded and installed into a cache directory. In this scenario, the node_modules folder, package.json file, and package-lock.json file will not be created in the project.

If you want to hide the details of using Node.js and npm in your project, this is the right option for you. If you also want to externalize the Antora playbook, the PACKAGES comment may be more suitable.

package.json

The second way to define packages is using a package.json file. The packages can be defined in either the dependencies or devDependencies property. The package.json file must list Antora as a dependency, either antora (preferred) or @antora/site-generator.

package.json
"dependencies": {
  "antora": "latest",
  "@antora/lunr-extension": "latest"
}

When a qualifying package.json file is present, meaning it contains either a dependencies or devDependencies property with at least one entry, the packages and additionalPackages parameters in the plugin’s configuration are ignored. Instead, the plugin will automatically run npm i --no-package-lock to install the dependencies. This command will populate the node_modules folder adjacent to the package.json file without creating a package-lock.json file (since one didn’t already exist).

The settings in .npmrc are honored when the plugin runs npm i. You can use this file to tune how npm operates. For example, you can set audit=false to suppress the package audit.

If the @antora/cli package is not installed after the plugin runs npm i, the plugin will automatically download and install it into a private area when invoking the antora command via npx.

With package-lock.json

The third way to define additional Node.js packages is with both the package.json file and package-lock.json file. This is a variation of the previous approach, except the plugin will run npm ci instead of npm i. The benefit of using a package-lock.json file is that it locks the versions of the packages that npm installs.

The settings in .npmrc are honored when the plugin runs npm i. You can use this file to tune how npm operates. For example, you can set audit=false to suppress the package audit.

Again, if the @antora/cli package is not installed after the plugin runs npm ci, the plugin will automatically download and install it into a private area when invoking the antora command via npx.

PACKAGES comment

Finally, you can configure packages using the PACKAGES comment line in a playbook template that’s retrieved by the playbook provider feature of the plugin. This is the preferred method for managing packages in your content branches.

If the package.json file is detected at the project root (i.e., the location of pom.xml), and it contains either a dependencies or devDependencies property, the plugin will not use the playbook provider and, as a consequence, will not discover the PACKAGES comment in the playbook template. The assumption is that if a qualifying package.json file is present, the playbook provider is not applicable since the project is managing its own configuration.

The packages must be separated by the space character. Each entry must conform to the syntax described in the packages parameter section.

The PACKAGES comment line is only recognized when the playbook is retrieved through this mechanism. If you’re not using the playbook provider, this magic comment line is not recognized.

Specifying the antora package in the PACKAGES comment line implicitly sets the version of Antora used by the plugin. Additional packages may still be specified using the additionalPackages parameter or the antora.additionalPackages user property mapped to this parameter.

In this scenario, Antora will be installed into a cache folder inside the Node.js installation. Any packages defined in the PACKAGES comment or additionalPackages parameter will be installed using the same npx command.

To learn how to manage packages using the PACKAGES comment line and playbook provider, see Declare packages in a playbook template.

Precedence

The following table outlines the precedence rules when packages are specified using multiple methods.

Declaration Location Precedence

package.json

If package.json is present, and it has a dependencies or devDependencies property with at least one entry, it overrides all package declarations made using other methods.

packages parameter in the plugin configuration

If the same package is declared using the additionalPackages parameter, the package specified in the additionalPackages parameter takes precedence. The packages parameter is ignored when the playbook provider is used.

PACKAGES comment line in a playbook retrieved using the playbook provider

If the same package is declared using the PACKAGES comment line and the additionalPackages parameter, the package specified in the additionalPackages parameter takes precedence.

The PACKAGES comment in the playbook is ignored if the playbook isn’t retrieved using the playbook provider feature.