For AI agents: a documentation index is available at /llms.txt. Markdown versions of pages are available by appending .md to any documentation URL.
Skip to main content

Quickstart

Follow this quickstart to learn the essential workflow to create and deploy a Besu plugin.

Prerequisites

Steps

1. Set up your project

A Besu plugin is a standalone Java project; create a new directory for it.

Besu provides a Gradle plugin to simplify the plugin developer experience. It automatically adds and manages dependencies, and packages the plugin artifacts when you distribute the project.

In your plugin project, apply the latest version of the Gradle plugin (net.consensys.besu-plugin-distribution) and set the Besu version you want to compile your plugin against:

build.gradle
plugins {
id 'net.consensys.besu-plugin-distribution' version '0.2.1'
}

besuPlugin {
besuVersion = '26.6.0'
}

Generate the Gradle wrapper so the project builds with a consistent Gradle version:

gradle wrapper

2. Implement the plugin class

Create a class that implements BesuPlugin. The three required methods are register, start, and stop.

Besu calls register(ServiceManager) early in startup. ServiceManager is the interface through which your plugin accesses all Besu services. Store ServiceManager in a field if your plugin needs to retrieve services later.

The getName method is optional; it defaults to the fully qualified class name, but overriding it with a short string gives your plugin a readable identifier.

ExamplePlugin.java
package example;

import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;

public class ExamplePlugin implements BesuPlugin {
private ServiceManager serviceManager;

@Override
public String getName() {
return "example";
}

@Override
public void register(final ServiceManager serviceManager) {
this.serviceManager = serviceManager;
}

@Override
public void start() {}

@Override
public void stop() {}
}

3. Register the plugin for discovery

Besu discovers plugin classes using Java's ServiceLoader. Register your plugin by including a service provider entry for BesuPlugin. You can generate the entry using Google's @AutoService annotation processor:

ExamplePlugin.java
package example;

import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import com.google.auto.service.AutoService;

@AutoService(BesuPlugin.class)
public class ExamplePlugin implements BesuPlugin { ... }

4. Register CLI options

Use the register method to add plugin CLI options to the Besu command line. Retrieve the PicoCLIOptions service and call addPicoCLIOptions, passing a short namespace string and the object whose fields carry PicoCLI @Option annotations.

ExamplePlugin.java
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import picocli.CommandLine.Option;

public class ExamplePlugin implements BesuPlugin {
private ServiceManager serviceManager;

@Option(names = "--plugin-example-enabled", description = "Enable the example plugin feature.")
private boolean enabled = false;

@Override
public void register(final ServiceManager serviceManager) {
this.serviceManager = serviceManager;
serviceManager
.getService(PicoCLIOptions.class)
.ifPresent(cli -> cli.addPicoCLIOptions("example", this));
}
...
}
Important

Plugin CLI option names must use the prefix --plugin-<namespace>-, where <namespace> is the value you pass to addPicoCLIOptions. For example, passing "example" means every @Option name must start with --plugin-example-.

5. Retrieve services and start

Use start to retrieve Besu services and begin runtime work. Services that expose runtime data (such as events, metrics, and world state) only become available at start. Learn more about when services are available.

The following example retrieves BesuEvents:

ExamplePlugin.java
import org.hyperledger.besu.plugin.services.BesuEvents;

@Override
public void start() {
serviceManager
.getService(BesuEvents.class)
.ifPresent(events -> {
// Subscribe to block, transaction, or sync events.
});
}

6. Clean up in stop

Use stop to remove event subscriptions and release any resources your plugin holds. Besu calls stop during shutdown and when disabling individual plugins.

ExamplePlugin.java
@Override
public void stop() {
// Remove event subscriptions and release resources.
}

7. Build and deploy the plugin

The Gradle plugin provides a distZip task that packages your plugin into a ZIP file containing only the plugin JAR and any extra dependencies not already provided by Besu. Build the distribution:

./gradlew distZip

Create a plugins directory at the root of your Besu installation if it doesn't already exist. Then unzip the archive into it. The -j flag flattens the ZIP so all JARs land directly in plugins/:

unzip -j build/distributions/example.zip -d /path/to/besu/plugins/
tip

If you installed Besu using Homebrew or docker, see Deploy a plugin.

Start Besu. It loads all JARs found in the plugins directory automatically. To load only specific plugins, use --plugins.

Next steps