express-static-gzip

Express middleware that serves pre-gzipped or brotli-compressed static files instead of compressing on every request.

Library
npm
v3.0.2
150stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
55/100Fair
Development Activity56
Maintenance28
Community56
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
57/100Fair
Architecture78
Code Quality62
Innovation48
Learning Curve40

express-static-gzip is a thin wrapper around Express’s serve-static middleware that serves files you’ve already compressed at build time — gzip by default, with optional brotli and custom encodings — instead of compressing them on every request. It inspects the Accept-Encoding header, matches it against the compressed files it finds alongside your originals, and rewrites the request to point at the right pre-compressed asset before handing off to serve-static.

Built for static production hosting (SPA bundles, prerendered sites, CDN origins) where compression can happen once in the build pipeline rather than per-request, it supports configurable encoding preference ordering, custom compression types beyond gzip/brotli, and passes through the full serve-static options set for cache headers, dotfile handling, and index-file behavior.

What You Get

  • Automatic serving of pre-gzipped or pre-brotli files based on the client’s Accept-Encoding header
  • Support for custom compression algorithms via encodingName/fileExtension pairs
  • orderPreference option to force a server-side encoding priority regardless of client preference
  • Full pass-through of serve-static options (cacheControl, maxAge, dotfiles, index, etc.)
  • TypeScript type definitions included out of the box

Common Use Cases

  • Serving a built SPA (React/Vue/Angular) bundle where gzip/brotli assets are generated at build time
  • Hosting a static site or documentation build behind a CDN origin without per-request compression CPU cost
  • Replacing express.static in a production Express app to cut response size without a runtime compression middleware
  • Adding brotli support to an existing static-file server without changing build tooling

Under The Hood

Architecture The module exports a single factory function, expressStaticGzipMiddleware(root, options), that follows a classic Express middleware factory pattern: on setup it sanitizes options (util/options.js), builds a list of registered Compression objects (gzip always, brotli optionally, custom ones from options), and eagerly walks the root directory tree once (parseRootDirForCompressedFiles → findCompressedFilesInDirectory) to build an in-memory files map keyed by original file path listing which compressed variants exist — trading a one-time synchronous filesystem walk at startup for zero per-request disk I/O. Each incoming request first passes through changeUrlFromDirectoryToIndexFile (directory-to-index-file rewriting), looks itself up in the files map, and if a match exists, findEncoding (util/encoding-selection.js) picks the best compression by intersecting the client’s Accept-Encoding header (parsed and sorted by q-value) with the file’s available compressions and any server orderPreference; convertToCompressedRequest then rewrites req.url and sets Content-Encoding/Content-Type headers before delegating to the wrapped serve-static middleware, restoring the original URL in its callback. The design is a thin decorator around serve-static — it never serves files itself, only rewrites the request/response and reuses serve-static for delivery.

Tech Stack Plain JavaScript with no build step, targeting Node/Express, with serve-static as a direct dependency for actual file delivery, mime-types for content-type/charset lookup, and parseurl for pathname parsing independent of query strings. TypeScript consumers get hand-written ambient type definitions in index.d.ts rather than generated types. Dev/test tooling is mocha with chai assertions and nyc for coverage; CI runs the suite via GitHub Actions across multiple Node LTS versions on every push and pull request to master. No bundler, linter, or formatter configuration is present.

Code Quality The test suite splits cleanly into focused unit specs over the two util modules and a genuine end-to-end spec that mounts the middleware in a real Express app and issues real HTTP requests against fixture directories, asserting on status codes and response headers rather than relying on mocks. Error handling is deliberate but minimal: the request handler catches only the one operation that can meaningfully throw (decoding a malformed URL) and returns a 400, while a quality-value parsing helper swallows a regex-match failure with an empty catch block, falling back to a safe default. There is no static typing, linting, or type-checking step in CI, but naming is consistent and descriptive throughout, and the suite runs across multiple Node versions on every push.

What Makes It Unique The library’s core idea is inverting where compression happens: instead of compressing responses per request like a typical runtime compression middleware, it assumes compression already happened during the build and does a near-zero-cost header/URL rewrite to serve the prebuilt artifact — a meaningful performance win for static and CDN-origin workloads. Beyond that, it stays a deliberately small, single-purpose wrapper around serve-static with a couple of ergonomic extras (server-side encoding preference, pluggable custom compression types) rather than a novel algorithm; the encoding negotiation itself follows the standard Accept-Encoding quality-value approach used across the ecosystem.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search