Self-hosted plugin management software. Discover, install, version, and update PF4J plugins — with a catalog UI, REST API, and client plugin.
$ curl -O https://www.plugwerk.io/deploy/docker-compose.yml
$ export PLUGWERK_VERSION=1.0.0
$ export PLUGWERK_AUTH_JWT_SECRET=$(openssl rand -base64 32)
$ export PLUGWERK_AUTH_ENCRYPTION_KEY=$(openssl rand -base64 32)
$ docker compose up -d
✓ Plugwerk running at http://localhost:8080
From upload to installation — Plugwerk covers the full plugin lifecycle.
Browse, search, and filter plugins by tags and status. Grid and list view with download counts and ratings.
SemVer versioning with SHA-256 artifact integrity. Upload via Web UI, REST API, or CI/CD pipeline.
Multi-product, multi-org support. Each namespace has its own catalog, roles, and API keys.
Role-based access control per namespace. Multi-issuer OIDC for Keycloak, Auth0, Azure AD, and more.
Approve or reject plugin releases before they reach your users. Configurable per namespace.
Serves a plugins.json catalog feed. Familiar format for
teams migrating from pf4j-update.
Your host application embeds the Plugwerk Client Plugin — a self-contained PF4J plugin — which talks to the Plugwerk Server. The server holds the catalog, artifact storage, and access control. No app restart, no SDK lock-in.
Version history, compatibility info, download stats, and one-click installation.
Plugwerk versus shipping plugins by hand and versus
pf4j-update.
| Capability | Hand-rolled distribution | pf4j-update | Plugwerk |
|---|---|---|---|
| Plugin catalog with search | |||
| Versioning (SemVer + dependencies) | |||
| Artifact integrity (SHA-256) | |||
| Namespace isolation (multi-product / multi-org) | |||
| RBAC (Admin / Member / Read-Only) | |||
| OIDC multi-issuer authentication | |||
| Review & approval workflow | |||
Drop-in plugins.json /
pf4j-update compatibility
| |||
| Web UI for plugin management |
The Plugwerk Client Plugin is a PF4J plugin with its own isolated classloader — no dependency conflicts with your host application.
plugins.json catalog feedvar config = new PlugwerkConfig.Builder(
"https://myplugwerk.host",
"acme-corp"
)
.apiKey("pwk_...")
.build();
// Connect — marketplace is AutoCloseable
PlugwerkPlugin plugin = (PlugwerkPlugin)
pluginManager.getPlugin(PlugwerkPlugin.PLUGIN_ID).getPlugin();
try (PlugwerkMarketplace marketplace = plugin.connect(config)) {
// Browse the catalog
var plugins = marketplace.catalog().listPlugins();
// Search by keyword
var results = marketplace.catalog()
.searchPlugins(new SearchCriteria.Builder().query("crm").build());
// Install a specific version
marketplace.installer()
.install("com.acme.crm-connector", "3.0.0")
.onSuccess(s -> log.info("Installed: {}", s.getPluginId()))
.onFailure(f -> log.warn("Failed: {}", f.getReason()));
}
All library modules are available on Maven Central under the
io.plugwerk group.
PF4J plugin with isolated classloader — client for discovery, install, and update.
io.plugwerk:plugwerk-client-plugin:1.0.0:pf4j@zip Extension point interfaces — PlugwerkMarketplace, Catalog, Installer, UpdateChecker.
io.plugwerk:plugwerk-spi:1.0.0 MANIFEST.MF parser and validator for plugin metadata.
io.plugwerk:plugwerk-descriptor:1.0.0 Generated DTOs and interfaces from the OpenAPI 3.1 specification.
io.plugwerk:plugwerk-api-model:1.0.0 // SPI interfaces (compile-time)
dependencies {
implementation("io.plugwerk:plugwerk-spi:1.0.0")
}
// Client plugin ZIP (runtime — deploy to PF4J plugins dir)
val plugwerkPlugin by configurations.creating
dependencies {
plugwerkPlugin("io.plugwerk:plugwerk-client-plugin:1.0.0:pf4j@zip")
} Plugwerk is open source and free to self-host. Set it up in under 5 minutes.