# Platformatic's Watt runs any Node.js app on worker threads, from three different CLIs

> Platformatic is a pnpm monorepo whose README now documents Watt, an application server that runs any Node.js app inside a worker thread and keeps logging, metrics, tracing and health checks outside that thread. The package names, the npm badge and the globally linked binaries do not all point at the same command.

**platformatic/platformatic** — Platformatic Open Source monorepo!

- Repository: https://github.com/platformatic/platformatic
- Stars: 2,131 · Forks: 210
- Language: JavaScript
- License: Apache-2.0
- Published: 2026-10-13 · Updated: 2026-10-13 · Language: en
- Canonical page: https://hysenlabs.com/projects/platformatic-platformatic

## Watt targets the plain single-process container you already run

This repository is a JavaScript monorepo whose README now documents Watt, and Watt exists to replace a setup the README calls the default one: a single Node.js process per container, scaled by whatever orchestrator you already run. Three complaints drive the design.

A single thread cannot consume the CPU allocated to it, so its event loop blocks during heavy traffic and latency spikes. That same thread owns the telemetry, so a crash destroys the data needed to explain the crash. And container orchestrators do not measure the metrics that matter for scaling Node.js, so new pods arrive late and teams either over-provision or risk downtime.

That default is the real alternative, and the difference is where responsibility sits. In a plain process the application thread is at once your server, your scheduler and your monitoring agent. Watt moves the server into worker threads and keeps logging, metrics, tracing, memory and CPU profiling, and health checks outside them, in a process that is not serving traffic.

For a team who wants the opposite trade, that matters. If each service must keep its own failure domain, its own autoscaling policy and its own quota inside the orchestrator, then consolidating a BFF and a microfrontend into one process gives those up, and the README does not weigh the cost.

## Worker threads move telemetry outside the crashing process

Any Node.js application, written in any framework, runs inside a worker thread, and that is the whole runtime model. Threads are auto-healed and rescaled in seconds, which is how the README says low latency is held at p95 and above without restarting a container. Because the main thread is not the request-serving thread, the observability path stays up when the application does not.

Framework coverage is broad by design. Astro, Next.js, Nitro, Nuxt, React Router, Remix, TanStack Start, Vite, NestJS and plain Node.js are all named, and the migration path points at Express, Fastify and Next.js applications that already exist.

TypeScript support is described as first class, with auto-generated types and an SDK, and production concerns are listed as built in: Docker deployment, environment configuration and scaling.

The other lever is process count. Services an orchestrator would normally schedule apart, BFFs and microfrontends among them, can sit in the same process, so the network hop between them disappears instead of being tuned. HTTP services, API gateways, frontend frameworks and data services are all named as composable pieces.

## The two-minute start lands on port 3042 with generated APIs

The shortest documented path installs one global binary, scaffolds a project and starts it. Three commands, copied from the quick start:

```bash
npm install -g wattpm
npx wattpm create my-first-app
cd my-first-app && npm start
```

The application then listens at `http://localhost:3042` with auto-generated REST and GraphQL APIs. That last part is more than a runtime would give you: the scaffolding step emits an API surface, not a bare Node.js server, and the topics attached to the repository name fastify, graphql, openapi and rest accordingly.

Two details are worth carrying into your own setup. The binary you install is `wattpm`, while the container entrypoint runs a different command, and nothing in the flow is pinned, because no version appears anywhere in the install line. A global install therefore follows whatever tag is newest, not a build you picked.

For a first real exercise rather than a smoke test, the README routes beginners to a separate tutorial that builds a complete Todo API in about 30 minutes.

## The README headlines Watt, the repository is platformatic

A close look at the top of this repository shows a naming mismatch worth stating plainly. The repository description reads 'Platformatic Open Source monorepo!', the npm badge tracks the platformatic package, and the root package.json is named platformatic, yet the README headline is 'Watt - The Node.js Application Server' and its quick start installs another binary entirely.

The mismatch has a consequence beyond branding. That same package.json carries `"private": true` at version 3.71.0, so the workspace root is never published, and only the packages under packages/ reach the registry. A reader who installs platformatic expecting the thing the README headlines has to reconcile the difference themselves.

The last push was on 2026-10-06, and the most recent tag is a 3.71.1 alpha dated 2026-09-30, sitting ahead of the 3.71.0 tag from 2026-09-29. The archive also carries DOCS_RESTRUCTURE_PLAN.md and CLAUDE.md at the root, which is a sign that the documentation layout is in motion while the README copy settles on a new product name.

## Three CLIs are linked globally, the image links two

Packaging is where the naming becomes concrete. One workspace script links three packages onto the PATH in a single line:

```json
"global-links": "cd packages/cli && pnpm add -g . && cd ../wattpm && pnpm add -g . && cd ../create-wattpm && pnpm add -g ."
```

The container image performs only two of those three installs. It links packages/cli as platformatic and packages/wattpm as wattpm, and never links packages/create-wattpm. An image that can serve an application but cannot scaffold one is a coherent choice for a deployment, yet it is a real difference from what a local install gives you.

The workspace underneath is pnpm, pinned by `"packageManager": "pnpm@12.9.1"`, with pnpm-workspace.yaml at the root and pnpm-lock.yaml committed. Every recursive script passes --workspace-concurrency=1, and pre-commit runs lint:updated-only, which calls node ./scripts/lint-updated-packages.js and checks only the packages you touched. renovate.json handles dependency bumps, and a script regenerates THIRD_PARTY_LICENSES.md rather than leaving it hand-maintained.

## The image builds on node:22-slim and ships no application

The Dockerfile is a two-stage build. The base stage runs node:22-slim, sets PLT_HOME, PNPM_HOME and APP_HOME under /home, installs python3, libc-dev, make and g++ for native modules, installs pnpm@12 globally, copies the lock files and runs pnpm fetch --prod before an offline hoisted install. The second stage drops the build toolchain, keeps dumb-init, copies the linked packages forward and switches to the node user.

Those choices have consequences for your own builds. The image pins pnpm@12 while the workspace declares pnpm@12.9.1, so a container can resolve a different patch of pnpm than the lockfile was written against. Build tooling never reaches the runtime layer, which is the part most worth copying into an existing Dockerfile.

The closing lines tell you what the image expects to receive:

```dockerfile
WORKDIR $APP_HOME
USER node
ENTRYPOINT ["dumb-init"]
CMD ["platformatic"]
```

WORKDIR points at $APP_HOME, and no application is ever copied into it. dumb-init as the entrypoint is what makes signal handling and zombie reaping behave when an orchestrator stops the container.

## Five database containers back the demo folder

docker-compose.yml at the root starts five database containers, two of which look like this:

```yaml
  postgresql:
    ports:
      - '127.0.0.1:5432:5432'
    image: 'pgvector/pgvector:pg17-trixie'
  valkey:
    ports:
      - '127.0.0.1:6379:6379'
    image: 'valkey/valkey:8'
```

Every port is published on the host loopback address rather than on all interfaces, which suits a suite running on the machine and keeps those databases off the network.

The repository has a demo folder with two entries, demo/auth/ and demo/basic/, and the README mentions neither. Nothing states which store the demo expects, so this compose file is the only written record of the supported matrix, and it records it as images and ports rather than prose. The spread is itself informative: two MySQL generations, a MariaDB, a Postgres carrying the pgvector image and a Valkey cache, which is a workspace testing engine-specific behaviour rather than assuming one store.

## The 93% figure resolves to a blog post, not a benchmark

The performance claim is the least verifiable thing here. Up to 93% faster appears in the README, but the number is a hyperlink to a post on blog.platformatic.dev rather than a result stored in the tree. No top-level entry is a benchmark suite, and no script in package.json runs one, so the headline cannot be checked against this repository.

The configuration story has the same shape. The README argues that orchestrators do not measure the metrics that matter for scaling Node.js, yet the root file list holds no Kubernetes manifest, no Helm chart and no metrics exporter configuration. It also documents no key for worker thread count, for the rescale interval, or for which telemetry endpoints Watt exposes. Those settings live in the separate documentation at docs.platformatic.dev, so adopting this means reading configuration the repository does not contain.

What is verifiable is the shape of the thing: a worker-thread runtime, a supervisor outside it, three linked binaries where the image keeps two, and a compose file that names the databases it cares about. The README also does not document an upgrade or rollback path for a deployment already in traffic.

## Conclusion

Adopt Watt when a Node.js app already runs in containers and the event loop is the bottleneck, since that is exactly the case the worker-thread design answers. Do not adopt it on the strength of the headline number: the 93% figure resolves to a blog post rather than to a benchmark in this tree, and the README has no worker count or telemetry setting. Before committing, read the configuration reference in the platformatic documentation, run demo/auth/ against your own data stores, and confirm that the application missing from the Docker image is something your deployment already supplies.

## FAQ

### What is the difference between platformatic and Watt?

Watt is the application server this repository's README documents, while platformatic remains the repository name and the name of the npm package the badge tracks. The root package.json is marked private, so only the individual packages under packages/ are published to the registry.

### How do I start a Watt app locally, and which port does it use?

Install wattpm globally, run npx wattpm create my-first-app, then npm start inside the created directory. The generated application listens at http://localhost:3042 with auto-generated REST and GraphQL APIs.

### Does the Docker image include my application?

No. The Dockerfile sets WORKDIR to $APP_HOME and installs the platformatic and wattpm commands, but nothing is copied into that directory, so the application has to be supplied by your own deployment.

### What does docker-compose.yml at the root of the repository start?

Five database containers: pgvector/pgvector:pg17-trixie on port 5432, mariadb:11.8 on 3307, mysql:5.7 on 3306, mysql:8 on 3308 and valkey/valkey:8 on 6379. Each one is published on the 127.0.0.1 loopback address of the host.

### Which databases does the project run in CI?

The repository root records the database set in docker-compose.yml rather than in a CI configuration, and it does not document which of them a continuous integration run exercises.

## Sources

- [Issues](https://github.com/platformatic/platformatic/issues)
- [License: Apache-2.0](https://github.com/platformatic/platformatic/blob/main/LICENSE)
- [platformatic/platformatic on GitHub](https://github.com/platformatic/platformatic)
- [README](https://github.com/platformatic/platformatic/blob/main/README.md)
- [Releases](https://github.com/platformatic/platformatic/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/platformatic-platformatic
