The Problem

Building a reliable, message‑driven microservice in Node often requires wiring a service‑bus, defining messages, handlers and workflows, and handling boiler‑plate for transports and persistence. Without a ready scaffold, teams spend time on repetitive setup rather than business logic.

What This Does

The bus‑starter repo supplies a minimal, runnable example of a @node‑ts/bus application. Core code lives under src/:

  • src/bus.ts creates and disposes the bus (initializeBus, disposeBus, exported bus).
  • Message definitions are in src/messages/ (e.g., siren-test-started.ts, email-maintenance-team.ts).
  • Handlers live in src/handlers/ and invoke the bus (start-siren-test-handler.ts, email-maintenance-team-handler.ts).
  • A simple workflow coordinating a siren‑test scenario is in src/workflows/siren-test-workflow.ts.

The project is TypeScript‑first, built with npm, and includes a CircleCI pipeline (.circleci/config.yml). Tests (test/) exercise the bus and handlers.

How It Is Wired

Execution starts at src/index.ts → function runDemo (line 7). runDemo:

  1. Calls initializeBus from src/bus.ts (creates the bus instance).
  2. Publishes a StartSirenTest message via bus.publish.
  3. Calls generateUuid from src/messages/uuid.ts to tag the demo run.

From there the internal call graph proceeds:

  • startSirenTestHandler (in src/handlers/start-siren-test-handler.ts) receives the start message and publishes SirenTestStarted.
  • The workflow (src/workflows/siren-test-workflow.ts) subscribes to SirenTestStarted and, on failure, publishes SirenTestFailed.
  • emailMaintenanceTeamHandler (in src/handlers/email-maintenance-team-handler.ts) reacts to SirenTestFailed and calls sendEmail from src/services/email-service.ts.
  • sendEmail uses the shared bus to emit a MaintenanceTeamEmailed event.

The bus (src/bus.ts) is the single point of outward effect; all message traffic flows through it. The call graph shows bus invoked from seven distinct places, giving it the widest blast radius.

A circular import exists among seven modules, most notably src/bus.ts, src/services/email-service.ts, and src/handlers/email-maintenance-team-handler.ts. This creates a dependency cycle that can hinder tree‑shaking, increase build times, and make future refactoring riskier. Breaking the cycle—e.g., extracting shared types into a src/common/ module or using lazy imports—will improve modularity.

How To Use It

# Clone the starter (use the exact URL as requested)
git clone https://github.com/moses-y/bus-starter my-bus-app
cd my-bus-app
git remote set-url origin <your‑repo‑url>

# Install dependencies
npm i

# Start a local RabbitMQ instance (required transport)
docker run -d -p 8080:15672 -p 5672:5672 rabbitmq:3-management

# Run the demo in watch mode
npm run dev

The demo prints log output as the siren‑test workflow fires. Replace the message, handler, and workflow files under src/messages/, src/handlers/, and src/workflows/ with domain‑specific logic. No additional configuration files are required beyond the RabbitMQ container.

Real‑World Use

A building‑management service could adopt this scaffold to coordinate fire‑alarm tests across multiple sites. Each site publishes a StartSirenTest event; the workflow aggregates results, and on failure automatically notifies the maintenance crew via email or SMS, all without tightly coupling the test runner to the notification service.

Code Health & Issues

  • High – Missing LICENSE – No license file at repository root; default is “all rights reserved”, preventing legal reuse. Fix: add an MIT or Apache‑2.0 license.
  • Medium – No Dependabot – One manifest (package.json) but no automated dependency‑update bot. Fix: add .github/dependabot.yml.
  • High – Import Cycle – Seven modules (e.g., src/bus.ts, src/services/email-service.ts, src/handlers/email-maintenance-team-handler.ts) form a circular import. Fix: extract shared types or invert dependencies to break the cycle.

Tests are present (test/), CI runs on CircleCI, and a lockfile (package-lock.json) ensures reproducible installs. No Dockerfile or committed secrets were detected.

The Bottom Line

bus-starter delivers a functional, well‑structured example of a @node‑ts/bus application, complete with a demo workflow and CI. It is suitable for teams that need a quick, TypeScript‑based entry point into message‑driven microservices, but they should address the license, dependency‑bot, and import‑cycle issues before adopting it in production.