Create virtual network topologies using Linux network namespaces directly from Node.js.
VirtualNet makes it easy to spin up isolated nodes connected through a virtual bridge, simulate network conditions (latency, packet loss, bandwidth limits), and run processes inside each node.
This is useful for distributed systems testing.
npm install virtual-net
⚠️ Requires Linux withiproute2andtc. Most commands require sudo/root privileges because network namespaces are used.
The module creates a simple topology:
graph TD
subgraph HUB["node1 (hub namespace)"]
br0["Linux Bridge: br0<br/>IP: 10.0.0.1"]
end
subgraph N2["node2 namespace"]
v2["veth2<br/>10.0.0.2"]
end
subgraph N3["node3 namespace"]
v3["veth3<br/>10.0.0.3"]
end
subgraph N4["node4 namespace"]
v4["veth4<br/>10.0.0.4"]
end
br0 ---|"veth1-2"| v2
br0 ---|"veth1-3"| v3
br0 ---|"veth1-4"| v4
node1acts as the hub containing a bridge (br0)- All other nodes connect via veth pairs
- Each node gets an IP in the same subnet
Example IP layout:
node1 -> 10.0.0.1
node2 -> 10.0.0.2
node3 -> 10.0.0.3
node4 -> 10.0.0.4
const { VirtualNet } = require("virtual-net");
async function main() {
const net = new VirtualNet({ peers: 4 });
await net.start();
const node2 = net.node(2);
const node3 = net.node(3);
node2.exec("ping -c 3 10.0.0.3");
// add latency
net.latency(2, { delay: "100ms" });
node2.exec("ping 10.0.0.3");
// cleanup
net.stop();
}
main();new VirtualNet(options)Options:
| Option | Default | Description |
|---|---|---|
peers |
5 |
Number of nodes in the network |
prefix |
10.0.0 |
IP subnet prefix |
Example:
const net = new VirtualNet({
peers: 3,
prefix: "10.1.0"
});Creates the virtual network:
- deletes old namespaces
- creates nodes
- creates bridge
- connects nodes with veth pairs
- assigns IP addresses
await net.start();Removes all created network namespaces.
net.stop();Returns a Node instance representing a network namespace.
const node2 = net.node(2);Returns the IP address of a node.
net.ip(3);
// 10.0.0.3Apply network shaping using tc netem.
Options:
| Option | Example |
|---|---|
delay |
"100ms" |
loss |
"5%" |
rate |
"1mbit" |
Example:
net.latency(2, {
delay: "200ms",
loss: "2%",
rate: "5mbit"
});Remove traffic shaping from a node.
net.clearLatency(2);Node represents a single network namespace.
Spawn a process inside the node.
node.spawn("ping", ["10.0.0.3"]);Equivalent to:
sudo ip netns exec nodeX <cmd>
Execute a shell command.
node.exec("ping -c 3 10.0.0.3");Run a Node.js script inside the node.
node.fork("server.js");Open an interactive shell inside the node.
node.repl();This runs:
sudo ip netns exec nodeX bash
const { VirtualNet } = require("virtualnet");
async function run() {
const net = new VirtualNet({ peers: 3 });
await net.start();
net.node(2).fork("./server.js");
net.node(3).fork("./client.js", [net.ip(2)]);
}
run();- Linux
iproute2tcsudoaccess
Install dependencies:
sudo apt install iproute2If something crashes:
sudo ip netns list
sudo ip netns delete node1Or just call:
net.stop();MIT
