Node.js

Lesson 01

Runtime boundaries and entry points

Keep process startup separate from reusable application wiring.

Good Code

src/server.ts
import { createApp } from "./app";
import { readConfig } from "./config";

const config = readConfig(process.env);
const app = createApp({ logger: console });

const server = app.listen(config.port, () => {
  console.info("Server listening on port " + config.port);
});

export { server };

Bad Code

src/app.ts
import http from "node:http";
import { handleRequest } from "./handler";

const server = http.createServer(handleRequest);

server.listen(process.env.PORT || 3000);

export default server;

Review Notes

What to review

Good Code

The good version keeps startup in one entry point and lets the app wiring be imported without immediately listening on a port.

Bad Code

The bad version starts the server as a side effect of importing app.ts, which makes tests, scripts, and workers unexpectedly open sockets.

Takeaways

  • A Node module should be importable without starting the process or opening sockets.