{"id":17111,"library":"koa-static","title":"Koa Static File Server","description":"Koa-static is a middleware for the Koa web framework designed to efficiently serve static files such as HTML, CSS, JavaScript, images, and other assets. It acts as a wrapper around `koa-send`, providing a streamlined interface for common static file serving patterns. The current stable version is 5.0.0. This package is mature and stable, with infrequent releases (v5.0.0 published 8 years ago), indicating a solid and well-understood functionality rather than rapid ongoing development. Key features include comprehensive caching controls via `maxage`, support for serving hidden files, configurable default index filenames (e.g., `index.html`), and automatic Gzip/Brotli compression where supported by the client. It also offers a `defer` option to allow other middleware to handle requests first and the ability to set custom response headers. Its primary differentiator is its deep integration and idiomatic usage within the Koa ecosystem, offering a lightweight and unopinionated approach compared to more feature-rich alternatives like `koa-static-cache` which offer in-memory caching or complex routing extensions.","status":"maintenance","version":"5.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/koajs/static","tags":["javascript","koa","middleware","file","static","sendfile"],"install":[{"cmd":"npm install koa-static","lang":"bash","label":"npm"},{"cmd":"yarn add koa-static","lang":"bash","label":"yarn"},{"cmd":"pnpm add koa-static","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency, as it's a Koa middleware. Requires Koa 2.x or later for async/await middleware signature.","package":"koa","optional":false},{"reason":"Runtime dependency; `koa-static` is a wrapper around `koa-send` for core file serving logic.","package":"koa-send","optional":false}],"imports":[{"note":"Koa-static exports a default function, not a named export. Ensure 'type': 'module' in package.json for ESM.","wrong":"import { serve } from 'koa-static';","symbol":"serve","correct":"import serve from 'koa-static';"},{"note":"Standard CommonJS import. This is often used in older Koa applications or environments not configured for ESM.","symbol":"serve (CommonJS)","correct":"const serve = require('koa-static');"},{"note":"TypeScript users can import the `Options` interface directly for type safety. No direct type definitions are shipped with `koa-static` itself, but `@types/koa-static` provides them, which typically exports `Options` from the main module.","wrong":"import Koa from 'koa';\nimport serve from 'koa-static';\nconst options: koaStatic.Options = { maxage: 3600000 };","symbol":"Options Interface (TypeScript)","correct":"import Koa from 'koa';\nimport serve, { Options } from 'koa-static';\nconst options: Options = { maxage: 3600000 };"}],"quickstart":{"code":"import Koa from 'koa';\nimport serve from 'koa-static';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst app = new Koa();\nconst publicPath = path.join(__dirname, 'public');\n\n// Create a 'public' directory in your project root and add some files (e.g., index.html)\n// Example public/index.html:\n// <h1>Hello from Koa Static!</h1>\n\napp.use(serve(publicPath, {\n  // Optional: Enable gzip compression if client supports it and .gz file exists\n  gzip: true,\n  // Optional: Cache assets in browser for 7 days\n  maxage: 1000 * 60 * 60 * 24 * 7,\n  // Optional: Serve 'index.html' when root path is requested\n  index: 'index.html'\n}));\n\n// Fallback for non-static routes\napp.use(async (ctx) => {\n  if (!ctx.response.status || ctx.response.status === 404) {\n    ctx.body = 'Hello Koa! No static file found or served.';\n  }\n});\n\nconst PORT = process.env.PORT ?? 3000;\napp.listen(PORT, () => {\n  console.log(`Koa static server running on http://localhost:${PORT}`);\n  console.log(`Serving files from: ${publicPath}`);\n});","lang":"typescript","description":"Demonstrates how to set up a basic Koa application to serve static files from a 'public' directory with caching and compression enabled. It includes both ESM setup and a simple fallback route."},"warnings":[{"fix":"Ensure your Koa application and all middleware are compatible with Koa 2.x's async/await signature. For `koa-static`, upgrade to v5.0.0 or later. Update middleware functions from `function*` to `async/await` syntax.","message":"Upgrading from Koa 1.x (generator-based middleware) to Koa 2.x (async/await middleware) requires updating `koa-static` to a compatible version (v5.x). The middleware signature changed from `function* (next)` to `async (ctx, next) => { ... }`. Direct usage of `koa-static` in a Koa 1.x application will lead to errors.","severity":"breaking","affected_versions":"<5.0.0"},{"fix":"Use `koa-mount` to mount `koa-static` to a specific path:\n`import mount from 'koa-mount';\napp.use(mount('/assets', serve(publicPath)));`","message":"To serve static files from a specific URL subpath (e.g., `/assets`), `koa-static` must be combined with `koa-mount`. Directly passing a path like `app.use(serve('/assets', publicPath))` will not mount it correctly.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If static files should always be served first, ensure `defer` is `false` (the default) or remove the option. If you want other middleware to take precedence, set `defer: true`.","message":"The `defer` option, when set to `true`, ensures that `koa-static` only attempts to serve files *after* all downstream middleware have had a chance to respond. If a downstream middleware handles the request, `koa-static` will be skipped. This can be unexpected if you intend static files to be served first.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use `import.meta.url` along with `path` and `fileURLToPath` to construct `__dirname` and `__filename` equivalents:\n`import { fileURLToPath } from 'url';\nimport path from 'path';\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);`","message":"When using `koa-static` in an ESM project (with `\"type\": \"module\"` in `package.json`), ensure your path resolution for the root directory is correct. Node.js's native `__dirname` and `__filename` are not available in ESM modules.","severity":"gotcha","affected_versions":">=5.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Verify that the file exists in the directory provided to `koa-static`. Ensure the `publicPath` is resolved correctly (e.g., `path.join(__dirname, 'public')`). If serving from a subpath, use `koa-mount`.","cause":"The requested static file (e.g., `app.js`) does not exist in the configured static directory, or the path to the static directory is incorrect, or `koa-static` is not mounted correctly.","error":"GET http://localhost:3000/app.js net::ERR_ABORTED 404 (Not Found)"},{"fix":"Always pass the absolute path to your static files directory as the first argument to `koa-static`:\n`app.use(serve(path.join(__dirname, 'public')));`","cause":"The `root` directory parameter (the path to the folder containing your static files) was not provided to `koa-static`.","error":"Error: \"root\" is required in koa-send"},{"fix":"Ensure all files intended to be served statically are located within the `root` directory specified in `koa-static`. Adjust your application's file structure or URL routing accordingly.","cause":"Attempting to access a file via a URL that resolves to a path outside the configured `root` directory for security reasons.","error":"Cannot serve files outside the 'root' directory."}],"ecosystem":"npm","meta_description":null}