sirv

An optimized, lightweight Node.js middleware for serving static files at high speed.

Library
npm
v3.0.2
1,175stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
46/100Fair
Development Activity0
Maintenance32
Community52
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
86/100Excellent
Architecture85
Code Quality88
Innovation82
Learning Curve90

sirv is a fast, minimal middleware for serving static assets in Node.js. It returns a standard Express-style (req, res, next) handler that plugs directly into Polka, Express, and other Express-like frameworks, as well as the native http, https, and http2 modules.

Its headline advantage over serve-static is that, outside of dev mode, it does all of its filesystem work upfront and then answers every subsequent request from an in-memory cache — avoiding the expensive per-request fs existence checks that dominate other static servers. It ships with first-class support for precompiled gzip/brotli assets, ETags, SPA fallbacks, and fine-grained cache-control, in a dependency footprint of just three tiny packages.

What You Get

  • A drop-in (req, res, next) middleware compatible with Polka, Express, and the native http/https/http2 modules
  • In-memory caching of the directory tree in production for high-throughput serving without per-request fs checks
  • Built-in support for precompiled gzip and brotli assets, ETags, and configurable Cache-Control (maxAge, immutable)
  • Single-page-application fallback routing with customizable ignore patterns

Common Use Cases

  • Serving a built frontend (SPA or static site) from a Node.js backend
  • Adding a fast static-asset layer to a Polka or Express API server
  • Delivering precompiled gzip/brotli bundles with long-lived immutable cache headers

Under The Hood

Architecture — sirv’s entire runtime lives in a single ~180-line index.mjs in packages/sirv. The default export resolves the target directory and, unless dev is set, eagerly walks it via totalist to build a FILES map keyed by URL path, precomputing headers (Content-Type, Length, Last-Modified, optional ETag and Cache-Control) per file. It then returns a closure over either viaCache (production, map lookup) or viaLocal (dev, live fs.statSync). Per request it parses the pathname with @polka/url, assembles a prioritized extension/encoding candidate list (brotli, then gzip, then raw, plus extension and index fallbacks via toAssume), resolves the first match, and streams it with fs.createReadStream().pipe(res), handling ETag 304s and HTTP range requests along the way.

Tech Stack — Pure JavaScript targeting Node >=18, shipped as dual ESM/CJS builds generated from the .mjs source. Runtime dependencies are just three tiny lukeed-ecosystem packages: @polka/url (URL parsing), mrmime (MIME lookup), and totalist (fast recursive directory walk). TypeScript types are hand-authored (index.d.ts/index.d.mts). The repo is a Bun-managed monorepo (bun.lockb, builder.js) housing both sirv and sirv-cli.

Code Quality — The code is terse and performance-minded — manual char-code checks, cached loop bounds, bitwise tricks — but well-contained in small pure helpers (isMatch, toAssume, viaCache, viaLocal, toHeaders, send). Path traversal is guarded via normalize + abs.startsWith(dir). Tests are substantial: tests/sirv.mjs is ~33KB of uvu-based assertions covering encodings, ranges, SPA fallback, dotfiles, and headers, with a companion sirv-cli.mjs suite and a tests/public fixture tree.

API Design — The public surface is a single function sirv(dir?, opts?) returning standard Express-style middleware, so it drops into Polka/Express/native http with zero boilerplate. Options are flat, well-named booleans/values (dev, etag, maxAge, immutable, single, gzip, brotli, extensions, ignores, onNoMatch, setHeaders) and the README documents each with defaults and worked lookup-order examples, making behavior predictable and easy to reason about.

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