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 🙏

© 2025 – Pkg Stats / Ryan Hefner

micro-svc-registry

v0.1.2

Published

Zero-config local service registry for microservices (development only).

Downloads

322

Readme

micro-svc-registry

A zero-config service discovery layer for local microservice development. It lets your services find each other dynamically without hardcoding ports, without maintaining .env files, and without running Docker or Kubernetes.

This is most useful when you're running multiple Node.js/Express microservices locally and you want them to communicate without guessing which port each service is on.

Why this exists

Local microservice development usually means:

  • Random port conflicts (3001? 5173? 8080?)
  • Hardcoded URLs inside services
  • Registrations that break every time you restart a service
  • Gateways that fail with ECONNREFUSED during restarts
  • No lightweight service discovery unless you run Kubernetes or Docker

micro-svc-registry solves all this with a tiny local daemon that:

  • Runs automatically
  • Listens on 127.0.0.1:<random-port>
  • Tracks live services
  • Cleans up stale ones automatically
  • Lets services find each other by name

Features

  • Express-based daemon (clean routing, JSON body parsing, extensible)
  • Automatic daemon boot (client forks it if missing)
  • Register / heartbeat / resolve / list / unregister APIs
  • TTL-based cleanup
  • Zero configuration
  • No dependencies required in your services
  • Purely development-focused

Installation

npm install micro-svc-registry

Quick Start

1. Register your service

import registry from "micro-svc-registry";

const { instance } = await registry.register({
  name: "auth-service",
  port: 3001,
  pid: process.pid
});

console.log("Registered:", instance.id);

2. Send heartbeats

setInterval(() => {
  registry.heartbeat({
    name: "auth-service",
    id: instance.id
  });
}, 5000);

3. Resolve a service

const resp = await registry.resolve("auth-service");

if (resp.instance) {
  const { host, port } = resp.instance;
  console.log("Auth at:", `http://${host}:${port}`);
}

API Reference

register({ name, port, host?, pid?, id?, meta? })

Registers a service instance in the daemon.

heartbeat({ name, id })

Refreshes the lastSeen timestamp so the instance stays alive.

resolve(name)

Returns the most recently active instance for that service.

list()

Returns all services + all currently alive instances.

unregister({ name, id })

Stops tracking this instance.

startDaemonIfNeeded()

Starts the Express daemon if it doesn’t exist yet.

discoveryInfo()

Returns { host, port, pid } of the running daemon.


Express-Based Daemon Endpoints

Your daemon now exposes:

  • POST /register
  • POST /heartbeat
  • POST /unregister
  • GET /resolve/:name
  • GET /list
  • GET /health

The body is always JSON.

Example:

POST /register
{
  "name": "auth-service",
  "port": 3001,
  "pid": 12345
}

Response:

{
  "ok": true,
  "instance": {
    "id": "127.0.0.1:3001:839212",
    "host": "127.0.0.1",
    "port": 3001,
    "lastSeen": 1735820123912
  }
}

Example: Local Microservices

Auth Service (Express)

import express from "express";
import registry from "micro-svc-registry";

const app = express();
const PORT = 3001;

app.get("/authenticate", (req, res) => res.json({ ok: true }));

app.listen(PORT, async () => {
  const { instance } = await registry.register({
    name: "auth-service",
    port: PORT,
    pid: process.pid
  });

  setInterval(() => {
    registry.heartbeat({ name: "auth-service", id: instance.id });
  }, 5000);
});

Gateway

import express from "express";
import axios from "axios";
import registry from "micro-svc-registry";

const app = express();
const PORT = 3000;

app.get("/auth/authenticate", async (req, res) => {
  const resp = await registry.resolve("auth-service");

  if (!resp.instance) return res.status(503).json({ error: "auth down" });

  const { host, port } = resp.instance;
  const result = await axios.get(`http://${host}:${port}/authenticate`);
  res.json(result.data);
});

app.listen(PORT, () =>
  console.log("Gateway on 3000")
);

How It Works (Express Version)

1. Daemon Startup

  • Client forks an Express-based server from daemon.js
  • Daemon picks a random open port using Express
  • Writes discovery file → /tmp/svc-registry.json

2. Registration

  • Service sends POST /register
  • Daemon creates instance entry
  • Returns generated instance ID

3. Heartbeats

  • Services send POST /heartbeat
  • Daemon updates lastSeen

4. Auto Cleanup

Every 5s daemon removes instances where:

now - lastSeen > TTL (default 15000 ms)

5. Resolution

  • /resolve/:name
  • Returns the most recently active instance

Configuration

SVC_TTL=20000   # override TTL (ms)

Limitations

  • Only works on 127.0.0.1 (local machine)
  • In-memory only (daemon restart = registry reset)
  • No SSL/TLS
  • No auth
  • NOT for production use

License

MIT