Skip to content

Static Assets

useStaticAssets(root, options?) serves files from a directory using Bun.file. It handles content-type detection, Range requests, and blocks path traversal — no extra plugin required.

import { NestFactory } from '@nestjs/core';
import { ElysiaAdapter, type NestElysiaApplication } from 'nestjs-platform-elysia';
const app = await NestFactory.create<NestElysiaApplication>(AppModule, new ElysiaAdapter());
app.useStaticAssets('./public', { prefix: '/assets' });
await app.listen(3000);

With the above, GET /assets/logo.png serves ./public/logo.png. Requests outside the prefix fall through to your Nest routes.

OptionDefaultDescription
prefix/URL prefix the assets are mounted under.
index'index.html'File served for the prefix root (/assets/). Set to false to disable.
app.useStaticAssets('./public', { prefix: '/static', index: 'home.html' });
app.useStaticAssets('./downloads', { prefix: '/files', index: false });

Responses advertise Accept-Ranges: bytes, and a Range request gets a 206 Partial Content with the requested slice — so video/audio seeking and resumable downloads work:

GET /assets/video.mp4
Range: bytes=0-1048575
206 Partial Content
Content-Range: bytes 0-1048575/52428800
Content-Length: 1048576

An unsatisfiable range returns 416 Range Not Satisfiable; a malformed Range header is ignored and the full file is sent.

Paths are resolved and checked against the asset root, so encoded traversal attempts (..%2f..%2fetc%2fpasswd) are rejected with 403. Files outside root are never reachable.