Latest in Servers and APIs

Home → Servers and APIs

Building servers and APIs in Node.js — HTTP handling, routing, request lifecycles, and the patterns that keep backends maintainable.

47-day TLS certificates: what changes from 2026 to 2029, and how to check your Node.js apps

Public TLS certificates now last at most 200 days, will last 100 days from March 2027 and 47 days from 2029, and big services like Sentry are moving from DigiCert to Let's Encrypt and Google Trust Services. Here's the schedule from the CA/Browser Forum rules, what breaks (manual renewals, certificate pinning, mTLS with public certificates, old Node.js trust stores), and four tested Node.js scripts: an expiry and chain checker, an ACME Renewal Information (ARI) lookup, an mTLS test, and the NODE_EXTRA_CA_CERTS and --use-system-ca trust options.

Run your Node.js app on Apple's container (a Docker Desktop alternative)

Apple shipped container 1.0 — an open-source, native CLI that runs Linux containers on macOS by giving each one its own lightweight micro-VM. It speaks OCI images and has a Docker-like CLI. Here's a real Node.js app built and run on it, the networking model, x86 images via Rosetta, and the gotchas — all verified on container 1.0.0 on an Apple-silicon Mac.

Node.js Docker images: full vs slim vs alpine vs distroless

Which base image should a Node.js app use? The choice swings your image from ~1.8 GB down to ~210 MB and changes how you debug and secure it. Here are the real sizes for the same app on node:26, node:26-slim, node:26-alpine, and distroless — all measured with Docker — plus the tradeoffs that actually matter.

Ship a Node.js app as a single executable binary

Node.js can bundle your script and the runtime into one executable file — a Single Executable Application — so users run your CLI without installing Node at all. Here's the full build, an embedded asset, and proof the binary runs on a machine with no Node installed. Verified on real Docker images.

The built-in Node.js test runner: a complete guide

You no longer need Jest, Mocha, or Vitest to test a Node.js project. node:test ships a complete runner — suites, hooks, mocking, filtering, watch mode, and coverage — that you run with node --test. No dependencies, no config. Every command and its output here is from a real node:26-slim Docker image.

node:sqlite: a built-in SQL database with zero dependencies

Need a database for a script, CLI, or small service? Node.js ships node:sqlite — a synchronous SQLite driver built right in. No better-sqlite3, no node-gyp, no native compile, no npm install. Here's the full API — prepared statements, transactions, and user-defined functions — verified on a real node:26-slim image.

Running TypeScript natively in Node.js: 22 vs 24 vs 26

Node.js runs .ts files directly — no ts-node, no tsx, no build step. But the details differ between Node 22, 24, and 26: what's flagged, what's stable, and one feature that was removed in Node 26. Every example here was run on real node:22-slim, node:24-slim, and node:26-slim Docker images.

Node.js features that replace popular npm packages

Node.js has quietly absorbed the jobs that used to need dependencies: a test runner, a file watcher, a .env loader, native TypeScript, fetch, terminal colors, deep clone, even SQLite. Here's what you can drop on Node.js 26 — every example verified on a real node:26 Docker image.

The HTTP QUERY method: GET semantics with a request body

The new HTTP QUERY method (RFC 10008, 2026) gives you the safe, idempotent, cacheable semantics of GET with the request body of POST — ideal for large or structured read operations. Here's its status, browser and server support, and a form + fetch + Node example you can actually test.

Total memory used by all Docker containers: a correct docker stats summary (and why summing MEM % is wrong)

docker stats shows memory per container but no total. The usual one-liner sums the MEM % column, and that's wrong as soon as any container has a memory limit. In a test it reported 13.53 GiB used, 174% of the machine, when the containers were really using about 1 GB. Here's a correct shell version, a Node.js version that groups by Compose project, and what the number actually measures.

Load-balance Node.js containers with nginx and Docker Compose, and scale without reloading nginx

Run several Node.js containers behind nginx with Docker Compose, spread requests evenly with least_conn, and add or remove replicas without touching nginx, using the resolve option that open-source nginx gained in 1.27.3. Measured: 73 → 279 req/s going from 1 to 4 replicas, and zero failed requests while scaling down, once one easy-to-miss timeout is set. Also: why the classic Docker-DNS nginx config silently ignores its own upstream block.

Block IP addresses in Node.js and Express: net.BlockList, ::ffff: addresses and X-Forwarded-For spoofing

Block single IPs, ranges and CIDR subnets in a Node.js or Express server with the built-in net.BlockList, without any package. The common snippet, x-forwarded-for || remoteAddress, fails twice: it never matches because Node reports ::ffff: addresses, and any client can bypass it with one header. Here's a version that works directly and behind nginx, tested on Node 24 and 26 with Express 5.

About Code with Node.js

This is a personal blog and reference point of a Node.js developer.

I write and explain how different Node and JavaScript aspects work, as well as research popular and cool packages, and of course fail time to time.