Reactive network manager for Linux, written in TypeScript. Manages network namespaces, bridges, veth pairs, WireGuard interfaces, routes, addresses, VLANs, and DHCP — all driven by a declarative YAML or JSON configuration.
This is very experimental, expect many bugs, it is clearly not yet ready for production use.
- Network namespaces — create, delete, and move interfaces between namespaces
- Bridges — with 802.1Q VLAN filtering, STP control, and per-port VLAN membership
- veth pairs — virtual Ethernet links within or across namespaces
- WireGuard — interface creation and full configuration (peers, keys, endpoints, keepalive)
- Hardware matching — declare expected physical interfaces by PCI bus/device ID
- DHCP client — automatic IPv4 lease acquisition with renewal and rebinding
- Wake-on-LAN — send WoL magic packets via the
compartinet wolcommand - systemd integration —
sd_notifyreadiness, SIGHUP config reload, periodic state drift detection - YAML/JSON configuration — single file or a directory, validated against a JSON Schema
CompartiNET uses a desired-state vs current-state reconciliation pattern:
-
Desired state is built from your declarative configuration (YAML/JSON). Feature handlers (netns, bridge, veth, WireGuard, DHCP, etc.) expand the config into a
NetworkModel— a structured representation of namespaces, interfaces, addresses, and routes. -
Current state is collected from the kernel by polling
iproute2JSON output,wg showconf,bridge vlan show,iw dev... -
Reconciliation diffs the two models and produces a sequence of
ip,bridgeandwgcommands to converge the current state toward the desired state. -
Commands are executed, and the cycle repeats every 30 seconds to catch drift.
# Install globally from npm
npm install -g compartinet
# Check current state (network model)
compartinet state
# Install the systemd service
sudo compartinet install
# Create a configuration based on the current state
compartinet state-config | sudo tee /etc/compartinet/config.d/network.yaml
# Start the service
sudo systemctl enable --now compartinet# /etc/compartinet/config.d/network.yaml :
# yaml-language-server: $schema=./dist/config-schema.json
- type: SetInterfaceUp
netns: ""
iface: lo
up: true
- type: MatchHardware
netns: ""
iface: eth0
hardwareBus: pci
hardwareDevice: 0000:00:1f.6
- type: SetInterfaceUp
netns: ""
iface: eth0
up: true
- type: DhcpClient
netns: ""
iface: eth0
macAddress: 01:02:03:04:05:06See sampleConfig.yaml for a complete annotated reference of all available features.
npm install -g compartinetThe package bundles all dependencies. Requires Node.js.
git clone https://github.com/davdiv/compartinet.git
cd compartinet
npm ci
npm run build:node
# The built executables are in dist/flowchart TD
config["Config (YAML/JSON)"]
features["Feature handlers"]
desired["Desired NetworkModel"]
collect["collectState()"]
current["Current NetworkModel"]
reconciler["Reconciler"]
actions["Actions"]
commands["ip / bridge / wg commands"]
kernel["Kernel state"]
config --> features --> desired
desired --> reconciler
collect --> current --> reconciler
reconciler --> actions --> commands --> kernel
- src/common/ — platform-agnostic model, feature system, reconciler, DHCP protocol parsing
- src/node/ — Linux state collection, command execution, CLI tools, systemd integration
- tests/unit/ — pure-logic tests (reconciler, model generation, DHCP protocol)
- tests/integration/ — end-to-end tests running real
ip,wg, andbridgecommands
Prerequisites: Node.js, Docker (for integration tests)
npm ci
# Full check (type-check, build, both unit and integration tests, lint and format check)
npm run ci
# Individual commands:
npm run type-check # TypeScript type checking
npm run build:node # Build the dist/ output
npm run test:unit # Run unit tests
npm run test:integration # Run integration tests (in Docker container)
npm run lint # ESLint
npm run format:check # Check formatting
npm run format:fix # Fix formattingIntegration tests run inside a privileged Docker container (--cap-add=NET_ADMIN --cap-add=SYS_ADMIN) built from tests/container/Dockerfile. You can also open an interactive shell in the test container:
npm run sandboxMIT — Copyright 2026 DivDE