Skip to content

StreamableFile

reference
3 min readUpdated

Kind: Class

Source: packages/common/file-stream/streamable-file.ts

Part of: Common

StreamableFile wraps a Readable stream or in-memory buffer so it can be returned as a streamed HTTP response. It centralizes response metadata such as content type, disposition, and length, while allowing custom stream error handling and logging.

Methods

MethodSignatureReturns
getStreamgetStream()Readable
getHeadersgetHeaders()void
setErrorHandlersetErrorHandler(handler: (err: Error, response: StreamableHandlerResponse) => void)void
setErrorLoggersetErrorLogger(handler: (err: Error) => void)void

Properties

PropertyType
loggerany
handleError( err: Error, response: StreamableHandlerResponse, ) => void
logError(err: Error) => void

Where it refuses work

  • StreamableFile stops the work with an early return when res.destroyed.

Diagram

mermaid
graph LR
  A[File Buffer or Readable Stream] --> B[StreamableFile]
  B --> C[getStream()]
  B --> D[getHeaders()]
  B --> E[setErrorHandler()]
  B --> F[setErrorLogger()]
  C --> G[HTTP Response Stream]
  D --> G
  E --> H[Custom Error Response]
  F --> I[Application Logger]

Usage

ts
import { Controller, Get, StreamableFile } from '@nestjs/common';
import { createReadStream } from 'node:fs';
import { join } from 'node:path';

@Controller('reports')
export class ReportsController {
  @Get('download')
  download(): StreamableFile {
    const filePath = join(process.cwd(), 'files', 'monthly-report.pdf');
    const stream = createReadStream(filePath);

    return new StreamableFile(stream, {
      type: 'application/pdf',
      disposition: 'attachment; filename="monthly-report.pdf"',
    })
      .setErrorLogger((error) => {
        console.error('Unable to stream report:', error);
      })
      .setErrorHandler((error, response) => {
        response.statusCode = 500;
        response.end('The report could not be downloaded.');
      });
  }
}

AI Coding Instructions

  • Pass a Readable stream for large files to avoid loading the entire file into memory; use a buffer only for small generated content.
  • Set type and disposition options when returning downloadable files so clients receive the correct MIME type and filename.
  • Return the StreamableFile instance directly from supported controller routes rather than manually piping its stream unless custom response handling is required.
  • Configure setErrorLogger() and setErrorHandler() when stream failures need application-specific logging or HTTP error responses.
  • Ensure file streams are created from validated paths and that stream errors are handled, especially for files that may be missing or inaccessible.

How it works

StreamableFile is an exported class that packages either byte data or a readable/pipe-capable object with optional HTTP file-response metadata. It is re-exported from the common package. packages/common/file-stream/streamable-file.ts:13 packages/common/index.ts:9-12

StreamableFileOptions contains type, disposition, and length, corresponding to Content-Type, Content-Disposition, and Content-Length response headers. disposition may be a string or string array. packages/common/file-stream/interfaces/streamable-options.interface.ts:8-21 getHeaders() returns these three values, defaulting type to application/octet-stream and the other two to undefined. packages/common/file-stream/streamable-file.ts:57-68

When an Express response body is a StreamableFile, the adapter sets those headers only if the response does not already contain them, then pipes getStream() into the response. String-array header values are joined with commas before Express sets them. packages/platform-express/adapters/express-adapter.ts:110-118 packages/platform-express/adapters/express-adapter.ts:501-522 The Fastify adapter similarly assigns absent headers and sends the stored stream. packages/platform-fastify/adapters/fastify-adapter.ts:449-482

The class exposes replaceable stream-error callbacks:

Used by

4 references from 4 files. Each is a place in this repository where the symbol is actually used — go read one rather than trusting an example.

Imported by (4)

  • AppControllerintegration/send-files/src/app.controller.ts:6
  • AppServiceintegration/send-files/src/app.service.ts:9
  • ExpressAdapterpackages/platform-express/adapters/express-adapter.ts:51
  • FastifyAdapterpackages/platform-fastify/adapters/fastify-adapter.ts:124

Was this page helpful?

Download as PDF
StreamableFile — NestJS head-to-head