Skip to content

dlahoza/pluginart

Repository files navigation

pluginart logo

pluginart

pluginart is a CLI plus Go, Python, and TypeScript runtimes for building language-agnostic plugin systems. Hosts manage plugins from pluginart.toml. Plugins run as binaries, Docker containers, or remote TCP services. All calls use a FlatBuffers-based wire protocol with contract-hash verification at handshake time.

Install

go install github.com/dlahoza/pluginart/cmd/pluginart@latest
brew install flatbuffers

Runtime packages are published as:

  • Go: github.com/dlahoza/pluginart/pkg/runtime
  • PyPI: pluginart
  • npm: pluginart

Mental Model

The schema defines payload tables and method names. Generated clients give host code method wrappers. The host runtime starts, health-checks, restarts, calls, and shuts down plugins. Go, Python, and TypeScript generation hide the pluginart RPC envelope while still using FlatBuffers payload builders.

Quickstart: Go Host

pluginart gen bindings --target host --lang go --schema examples/schema/echo.fbs --out examples/host-go/plugins
pluginart gen bindings --target plugin --lang go --schema examples/schema/echo.fbs --out examples/plugin-go/plugin
cd examples/plugin-go && go build -o plugin-go .
cd ../host-go && go run .

Go hosts use runtime.NewManagerFromConfig("pluginart.toml") and generated clients that wrap manager.Call.

Quickstart: Python Host

pluginart gen bindings --target host --lang python --schema examples/schema/echo.fbs --out examples/host-py/plugins/echo
pluginart gen plugin --lang python --name echo --schema examples/schema/echo.fbs --out examples/plugin-py
pip install pluginart flatbuffers
python examples/host-py/main.py

Python hosts use:

from pluginart import PluginManager
from plugins.echo.echo_client import echoClient

with PluginManager.from_config("pluginart.toml") as manager:
    client = echoClient(manager, "echo")
    response = client.Echo(builder, echo_request_offset)

Quickstart: TypeScript Host

pluginart gen bindings --target host --lang typescript --schema examples/schema/echo.fbs --out examples/host-ts/plugins/echo
pluginart gen plugin --lang typescript --name echo --schema examples/schema/echo.fbs --out examples/plugin-ts
cd examples/plugin-ts && npm install && npm run build
cd ../host-ts && npm install && npm run build && npm start

TypeScript hosts use:

import { PluginManager } from 'pluginart';

const manager = await PluginManager.fromConfig('pluginart.toml');
await manager.start();
const client = new EchoClient(manager, 'echo');
const response = await client.Echo(builder, echoRequestOffset);
await manager.shutdown();

Plugin Modes

type Host behavior Transport default
binary Execs path, injects PLUGIN_SOCKET or PLUGIN_ADDR, waits for READY Unix socket
docker Runs docker run, injects PLUGIN_ADDR, waits for READY in logs TCP
remote Dials address directly TCP

Config-driven lifecycle is available in Go, Python, and TypeScript runtimes.

The repository examples also include repeat plugins in Go, Python, and TypeScript that run through Docker mode. Build them from the repository root before running any host example:

docker build -f examples/plugin-repeat-go/Dockerfile -t pluginart-repeat-go:local .
docker build -f examples/plugin-repeat-py/Dockerfile -t pluginart-repeat-py:local .
docker build -f examples/plugin-repeat-ts/Dockerfile -t pluginart-repeat-ts:local .

Each host example calls the binary echo plugins and the Dockerized repeat plugins through the same pluginart.toml lifecycle.

Benchmarks

Pluginart has a dedicated benchmark suite in bench. It measures runtime overhead with raw payloads and no generated schema code, so the results focus on framing, calls, manager lookup, handshake, and plugin server dispatch.

The suite covers host manager calls, direct protocol client calls, and plugin server dispatch for Go, Python, and TypeScript. Each runtime is tested against its own benchmark plugin. CI runs every case for 10 seconds and uploads the benchmark output as an artifact.

Latest local 100x run on an Apple M5:

Go benchmark Payload ns/op MB/s B/op allocs/op
host manager 10 45702 0.22 131 5
host manager 1000 40364 24.77 1138 5
host manager 10000 42732 234.01 10355 5
protocol client 10 35368 0.28 126 5
protocol client 1000 35118 28.48 1134 5
protocol client 10000 36048 277.41 10350 5
plugin server 10 29444 0.34 126 5
plugin server 1000 34707 28.81 1139 5
plugin server 10000 38572 259.26 10357 5
Python benchmark Payload ns/op MB/s Peak heap/op Retained heap/op
protocol client 10 28662 0.33 10 B 4 B
protocol client 1000 30949 30.81 50 B 14 B
protocol client 10000 51771 184.21 410 B 104 B
plugin manager 10 45067 0.21 10 B 4 B
plugin manager 1000 35494 26.87 50 B 14 B
plugin manager 10000 30645 311.19 410 B 104 B
plugin server 10 20280 0.47 10 B 4 B
plugin server 1000 22591 42.21 50 B 14 B
plugin server 10000 25730 370.63 410 B 104 B
TypeScript benchmark Payload ns/op MB/s Peak heap/op Retained heap/op
protocol client 10 63272 0.15 7043 B 1261 B
protocol client 1000 56728 16.81 5610 B 337 B
protocol client 10000 66761 142.85 5597 B 105 B
plugin manager 10 45313 0.21 6028 B 354 B
plugin manager 1000 43971 21.69 5705 B 90 B
plugin manager 10000 48949 194.83 5717 B 3 B
plugin server 10 51640 0.18 4921 B 96 B
plugin server 1000 38360 24.86 4940 B 0 B
plugin server 10000 47253 201.82 5207 B 90 B

Run the suite locally:

go test -tags bench ./bench/go -run TestBench -bench Benchmark -benchmem -benchtime=10s -count=1
go test ./pkg/protocol -run '^$' -bench BenchmarkHandleConnServer -benchmem -benchtime=10s -count=1
.venv/bin/python bench/python/run_bench.py --duration 10s --json bench-results/python.json
node --expose-gc bench/typescript/dist/run-bench.js --duration 10s --json bench-results/typescript.json

Docs

Roadmap

Version Status Scope
v0.1 Shipped Go runtime foundation: FlatBuffers call envelope, framing, handshake, contract-hash verification, Unix/TCP transports, binary and remote plugin lifecycle, Go schema/client/plugin generation, and getting-started docs.
v0.2 Shipped Python and TypeScript runtimes, Python/TypeScript host and plugin generation, Docker plugin mode, config validation, full protocol docs, reusable plugin server helpers, and example hosts/plugins across Go, Python, and TypeScript.
v0.3 Planned Resilience: circuit breakers, per-call deadlines and cancellation, and batching.
v0.4 Planned Observability: W3C trace context propagation and OpenTelemetry integration.
v0.5 Planned Transport hardening: compression negotiation with LZ4/ZSTD and TLS support for remote mode, including mutual TLS options.
v0.6 Planned Performance: shared-memory fast path, runtime object pooling, and sender write coalescing.

The current release is v0.2.2. Field-level request/response builders, plugin registry/marketplace support, and languages beyond Go, Python, and TypeScript are not currently in scope.

License

MIT

About

Resilient language-agnostic plugin system

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors