or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-koa-send

Static file serving middleware for Koa.js applications with compression, caching, and security features.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/koa-send@5.0.x

To install, run

npx @tessl/cli install tessl/npm-koa-send@5.0.0

index.mddocs/

koa-send

koa-send is a static file serving middleware for Koa.js applications that provides secure, efficient delivery of static assets to web clients. It offers comprehensive file serving capabilities including automatic compression support (gzip and brotli), configurable browser caching, path normalization and security protections against directory traversal attacks, and flexible content type detection.

Package Information

  • Package Name: koa-send
  • Package Type: npm
  • Language: JavaScript (Node.js)
  • Installation: npm install koa-send

Core Imports

const send = require('koa-send');

For ES modules:

import send from 'koa-send';

Basic Usage

const send = require('koa-send');
const Koa = require('koa');
const app = new Koa();

// Basic file serving
app.use(async (ctx) => {
  if (ctx.path === '/') {
    ctx.body = 'Try GET /package.json';
    return;
  }
  await send(ctx, ctx.path);
});

// Serve from a root directory
app.use(async (ctx) => {
  await send(ctx, ctx.path, { root: __dirname + '/public' });
});

app.listen(3000);

Capabilities

Static File Serving

Serves static files with comprehensive security and performance features.

/**
 * Send static file with given options to Koa context
 * @param {Context} ctx - Koa context object (required)
 * @param {string} path - File path to serve (required)
 * @param {SendOptions} opts - Options object (optional)
 * @returns {Promise<string>} - Resolved file path that was served
 * @throws {Error} 400 if path decode fails
 * @throws {Error} 404 if file not found
 * @throws {Error} 500 for other file system errors
 * @throws {TypeError} if setHeaders is not a function
 */
async function send(ctx, path, opts = {});

Usage Examples:

// Basic usage
await send(ctx, 'path/to/file.txt');

// With root directory
await send(ctx, ctx.path, { root: '/public' });

// With compression and caching
await send(ctx, ctx.path, {
  root: __dirname + '/static',
  maxage: 86400000, // 24 hours
  gzip: true,
  brotli: true,
  immutable: true
});

// With custom headers
await send(ctx, ctx.path, {
  root: '/assets',
  setHeaders: (res, path, stats) => {
    res.setHeader('X-Served-By', 'koa-send');
  }
});

Options

SendOptions Interface

/**
 * Configuration options for the send function
 */
interface SendOptions {
  /** Root directory to restrict file access (defaults to '') */
  root?: string;
  /** Browser cache max-age in milliseconds (defaults to 0) */
  maxage?: number;
  /** Alias for maxage (defaults to 0) */
  maxAge?: number;
  /** Mark resource as immutable for caching (defaults to false) */
  immutable?: boolean;
  /** Allow transfer of hidden files (defaults to false) */
  hidden?: boolean;
  /** Name of index file for directories (defaults to undefined) */
  index?: string;
  /** Format path for directory handling (defaults to true) */
  format?: boolean;
  /** File extensions to try when no extension provided (defaults to false) */
  extensions?: Array<string> | false;
  /** Enable brotli compression support (defaults to true) */
  brotli?: boolean;
  /** Enable gzip compression support (defaults to true) */
  gzip?: boolean;
  /** Custom headers function (defaults to undefined) */
  setHeaders?: (res: ServerResponse, path: string, stats: Stats) => void;
}

Option Details

Root Directory (root)

Specifies the root directory from which to serve files. The path is resolved and normalized for security.

// Serve files from public directory
await send(ctx, ctx.path, { root: __dirname + '/public' });

// Serve specific file without user input
await send(ctx, 'path/to/my.js');

Caching Options (maxage, immutable)

Control browser caching behavior:

// Cache for 24 hours
await send(ctx, ctx.path, { 
  maxage: 86400000,
  immutable: true // Resource never changes
});

Compression (gzip, brotli)

Automatic compression based on client support:

// Enable both compression methods (default)
await send(ctx, ctx.path, { 
  gzip: true,
  brotli: true 
});

// Disable compression
await send(ctx, ctx.path, { 
  gzip: false,
  brotli: false 
});

Extension Matching (extensions)

Try multiple extensions for extensionless requests:

// Try .html, .js extensions
await send(ctx, ctx.path, { 
  extensions: ['html', 'js'] 
});

// Also works with dots
await send(ctx, ctx.path, { 
  extensions: ['.html', '.js'] 
});

Index Files (index)

Serve index files for directory requests:

// Serve index.html for directory requests
await send(ctx, ctx.path, { 
  index: 'index.html',
  format: true // Handle trailing slashes
});

Custom Headers (setHeaders)

Set custom response headers:

await send(ctx, ctx.path, {
  setHeaders: (res, path, stats) => {
    // Only modify Cache-Control or Last-Modified here
    // Other headers should be set before calling send()
    if (path.endsWith('.js')) {
      res.setHeader('Cache-Control', 'max-age=31536000, immutable');
    }
  }
});

Security Features

Path Traversal Protection

koa-send automatically protects against directory traversal attacks:

  • Paths are normalized and resolved safely
  • Parent directory references (..) are handled securely
  • The resolve-path library provides additional security

Hidden File Protection

By default, hidden files (starting with .) are not served:

// Allow hidden files (use with caution)
await send(ctx, ctx.path, { hidden: true });

Error Handling

The send function throws specific HTTP errors:

  • 400: Failed to decode the requested path
  • 404: File not found, name too long, or not a directory
  • 500: Other file system errors
  • TypeError: Invalid setHeaders option (not a function)
app.use(async (ctx, next) => {
  try {
    await send(ctx, ctx.path, { root: '/public' });
  } catch (err) {
    if (err.status === 404) {
      ctx.body = 'File not found';
    } else {
      throw err;
    }
  }
});

Performance Features

Automatic Compression

Files are automatically compressed when:

  • Client supports gzip or brotli encoding
  • Corresponding compressed file exists (.gz or .br)
  • Compression options are enabled (default)

Efficient Streaming

Files are streamed directly to the client using Node.js streams:

  • No memory buffering of large files
  • Efficient for serving large static assets
  • Proper Content-Length headers

Smart Caching

Configurable browser caching with:

  • max-age directive for cache duration
  • immutable directive for permanent caching
  • Automatic Last-Modified headers
  • Conditional request support

Types

/**
 * Node.js ServerResponse object
 */
interface ServerResponse {
  setHeader(name: string, value: string): void;
  removeHeader(name: string): void;
}

/**
 * Node.js fs.Stats object
 */
interface Stats {
  size: number;
  mtime: Date;
  isDirectory(): boolean;
}

/**
 * Koa Context object (subset of properties used by send)
 */
interface Context {
  path: string;
  res: ServerResponse;
  response: {
    get(field: string): string;
  };
  body?: any;
  type?: string;
  set(field: string, val: string): void;
  throw(status: number, message?: string): void;
  acceptsEncodings(...encodings: string[]): string | false;
}