npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fibercom/routeros-api

v2.0.0

Published

Robust MikroTik RouterOS API client for Node.js and TypeScript

Readme

@fibercom/routeros-api

A TypeScript and Node.js client for the MikroTik RouterOS API.

The library supports plain TCP and TLS connections, tagged concurrent commands, continuous data streams, connection retries, RouterOS traps, and convenience methods for common router operations.

Features

  • TypeScript declarations and strict type checking
  • RouterOS API over TCP or TLS
  • Tagged commands on a shared connection
  • Long-running streams with pause, resume, and close support
  • Safe incremental decoding across fragmented TCP packets
  • RouterOS !re, !done, !trap, !fatal, and !empty replies
  • DHCP lease, firewall, route, interface, user, log, and system helpers
  • Legacy RouterOS challenge-response login compatibility
  • Configurable retries, timeouts, keepalive, and debug output

Requirements

  • Node.js 14 or newer
  • MikroTik RouterOS API service enabled
  • Network and firewall access to the API port

RouterOS normally uses:

  • 8728 for the unencrypted API service
  • 8729 for API-SSL

Installation

npm install @fibercom/routeros-api

Basic usage

const { MikrotikAPI } = require("@fibercom/routeros-api");

async function main() {
  const api = new MikrotikAPI({
    host: "192.168.88.1",
    user: "api-user",
    password: "your-password",
    timeout: 10,
  });

  api.on("error", (error) => {
    console.error("Router error:", error.message);
  });

  api.on("timeout", (error) => {
    console.error("Router timeout:", error.message);
  });

  try {
    await api.connect();

    const identity = await api.getSystemIdentity();
    const resources = await api.getSystemResources();

    console.log({ identity, resources });
  } finally {
    if (api.connected) await api.close();
  }
}

main().catch(console.error);

TypeScript usage

import { MikrotikAPI, IRosOptions } from "@fibercom/routeros-api";

const options: IRosOptions = {
  host: "192.168.88.1",
  user: "api-user",
  password: "your-password",
  timeout: 10,
};

const api = new MikrotikAPI(options);

await api.connect();
const interfaces = await api.getInterfaces();
await api.close();

TLS connection

Use RouterOS API-SSL whenever the connection crosses an untrusted network.

const api = new MikrotikAPI({
  host: "router.example.com",
  user: "api-user",
  password: "your-password",
  tls: true,
});

When tls is enabled and port is omitted, the library uses port 8729. You can pass Node.js TLS options instead of true:

const fs = require("fs");

const api = new MikrotikAPI({
  host: "router.example.com",
  user: "api-user",
  password: "your-password",
  tls: {
    ca: fs.readFileSync("router-ca.pem"),
    servername: "router.example.com",
    rejectUnauthorized: true,
  },
});

Port 8728 is unencrypted. Usernames, passwords, commands, and responses can be observed by anyone able to inspect that network traffic.

Connection retries

await api.connectWithRetry(3, 1000);

Arguments:

  1. Maximum connection attempts
  2. Delay between attempts in milliseconds

A socket timeout produces:

Connection timeout. Possible firewall enabled, RouterOS API service disabled, or host unreachable.

Raw RouterOS commands

Use write() for any RouterOS API command that does not have a convenience method:

const addresses = await api.write([
  "/ip/address/print",
  "?interface=bridge",
]);

The method accepts either one array or multiple command arguments:

const identity = await api.write("/system/identity/print");

await api.write(
  "/system/identity/set",
  "=name=core-router"
);

RouterOS response values are returned as strings in plain JavaScript objects.

DHCP leases

Get every lease:

const leases = await api.getDhcpLeases();

Filter by an exact DHCP server name:

const leases = await api.getDhcpLeases("Dhcp-mgmt");

RouterOS query values are case-sensitive. Use the exact server name returned by:

const servers = await api.write("/ip/dhcp-server/print");

Add a static lease:

await api.addDhcpLease({
  address: "192.168.88.20",
  macAddress: "00:11:22:33:44:55",
  server: "Dhcp-mgmt",
  comment: "Office printer",
  disabled: false,
});

Update a lease:

await api.setDhcpLease("*1A", {
  address: "192.168.88.21",
  comment: "Updated printer address",
});

Block or unblock a lease using the Blocked firewall address list:

await api.blockDhcpLeaseById("*1A", "Blocked by billing");
await api.unblockDhcpLeaseById("*1A");

Some DHCP helpers update multiple RouterOS resources sequentially. If a command fails midway, earlier router changes are not automatically rolled back.

Live interface traffic

const stream = api.streamInterfaceStats(
  {
    interface: "sfp-sfpplus1",
    interval: 1,
  },
  (error, packet) => {
    if (error) {
      console.error(error.message);
      return;
    }

    console.log(
      packet["rx-bits-per-second"],
      packet["tx-bits-per-second"]
    );
  }
);

await new Promise((resolve) => setTimeout(resolve, 5000));
await stream.pause();

await new Promise((resolve) => setTimeout(resolve, 3000));
await stream.resume();

await new Promise((resolve) => setTimeout(resolve, 5000));
await stream.close();

A paused stream remains registered with the API. Resuming creates a fresh RouterOS command tag. Calling close() or stop() performs final cleanup.

Streams also emit events:

stream.on("data", (packet) => console.log(packet));
stream.on("paused", () => console.log("paused"));
stream.on("started", () => console.log("started"));
stream.on("done", () => console.log("done"));
stream.on("close", () => console.log("closed"));
stream.on("stopped", () => console.log("stopped"));
stream.on("trap", (trap) => console.error("trap", trap));
stream.on("error", (error) => console.error(error));

Convenience methods

System

  • getSystemInfo()
  • getSystemResources()
  • getSystemIdentity()
  • setSystemIdentity(name)
  • getSystemLogs(topics?)
  • streamSystemLogs(callback?)
  • reboot()
  • exportConfig(filename?)
  • importConfig(filename)

Interfaces and networking

  • getInterfaces()
  • getIPAddresses()
  • getInterfaceStats(interfaceName?)
  • streamInterfaceStats(options, callback?)
  • getBridges()
  • getRoutes()
  • addRoute(destination, gateway, distance?)

DHCP

  • getDhcpLeases(serverName?)
  • addDhcpLease(lease)
  • setDhcpLease(id, parameters)
  • setDhcpLeaseAndUpdateAddressLists(id, parameters)
  • removeDhcpLease(id)
  • getDhcpServersWithGateways()
  • getFreeIpsForDhcpServer(serverName, gatewayCidr)
  • blockDhcpLeaseById(id, comment?)
  • unblockDhcpLeaseById(id)

Firewall, wireless, and users

  • getFirewallRules(chain?)
  • addFirewallRule(...)
  • getWirelessInterfaces()
  • getWirelessRegistrations()
  • streamWirelessRegistrations(callback?)
  • getUsers()
  • addUser(name, password, group?)
  • runScript(scriptName)

Connection options

interface IRosOptions {
  host: string;
  user?: string;
  password?: string;
  port?: number;
  timeout?: number;
  tls?: boolean | TlsOptions;
  keepalive?: boolean;
  debug?: boolean;
}

timeout is measured in seconds.

Errors

RouterOS and connection failures use RosException:

const { RosException } = require("@fibercom/routeros-api");

try {
  await api.connect();
} catch (error) {
  if (error instanceof RosException) {
    console.error(error.errno, error.message);
  } else {
    throw error;
  }
}

RouterOS !trap replies reject command promises. Listen for the API's error and timeout events when maintaining a long-lived connection.

Live router smoke test

The repository includes a read-only test in index.js. It reads router system information, interfaces, DHCP leases, and exercises traffic streaming with this sequence:

start -> 5 seconds -> pause -> 3 seconds -> resume -> 5 seconds -> close

Copy .env.example to .env and configure it:

ROUTEROS_HOST=192.168.88.1
ROUTEROS_PORT=8728
ROUTEROS_USER=api-user
ROUTEROS_PASSWORD=change-me
ROUTEROS_TIMEOUT=10
ROUTEROS_TLS=false
ROUTEROS_DEBUG=false
ROUTEROS_TEST_INTERFACE=sfp-sfpplus1
ROUTEROS_DHCP_SERVER=Dhcp-mgmt

Then run:

npm run test:router

The .env file is ignored by Git. Do not commit router credentials.

Development

Install dependencies:

npm install

Build the library:

npm run build

Run strict compilation and the automated tests:

npm test

Watch TypeScript sources:

npm run watch

Compiled JavaScript and declarations are written to dist/.

Security

  • Prefer API-SSL on port 8729.
  • Restrict API access with RouterOS firewall rules and /ip service address restrictions.
  • Use a dedicated RouterOS user with only the permissions your application needs.
  • Never commit passwords, .env files, private keys, or router backups.
  • Test configuration-changing helpers on a non-production router first.

License

MIT