Skip to content
Files SDK
Esc
navigateopen⌘Jpreview
On this page

NestJS

First-class NestJS integration - a dynamic FilesModule that mounts the gateway, plus InjectFiles() for sharing the Files instance through DI.

files-sdk/nestjs wraps the gateway in an idiomatic NestJS module. FilesModule.forRoot() (or forRootAsync()) configures createFilesRouter, mounts it at a configurable path via Nest’s middleware layer, and exposes the Files instance through dependency injection — inject it anywhere with @InjectFiles(). Both the Express and Fastify platform adapters are supported.

import { Module } from "@nestjs/common";
import { createFiles } from "files-sdk";
import { FilesModule } from "files-sdk/nestjs";
import { s3 } from "files-sdk/s3";

@Module({
  imports: [
    FilesModule.forRoot({
      files: createFiles({ adapter: s3({ bucket: "uploads" }) }),
      path: "/api/files", // the default
      allowedOrigins: ["https://app.example.com"],
      operations: ["upload", "download", "list", "delete", "url"],
      secret: process.env.FILES_API_SECRET,
    }),
  ],
})
export class AppModule {}
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

// Express adapter: disable the global body parser (see below).
const app = await NestFactory.create(AppModule, { bodyParser: false });
await app.listen(3000);

Async configuration

forRootAsync() follows the standard Nest pattern — imports, inject, and a useFactory that returns the same options:

import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { createFiles } from "files-sdk";
import { FilesModule } from "files-sdk/nestjs";
import { s3 } from "files-sdk/s3";

@Module({
  imports: [
    ConfigModule.forRoot(),
    FilesModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        files: createFiles({
          adapter: s3({ bucket: config.getOrThrow("S3_BUCKET") }),
        }),
        secret: config.getOrThrow("FILES_API_SECRET"),
        allowedOrigins: [config.getOrThrow("APP_ORIGIN")],
        operations: ["upload", "download", "list", "delete", "url"],
      }),
    }),
  ],
})
export class AppModule {}

Injecting the Files instance

The module registers globally by default (global: false to opt out), so any provider can inject the shared instance without importing FilesModule:

import { Injectable } from "@nestjs/common";
import type { Files } from "files-sdk";
import { InjectFiles } from "files-sdk/nestjs";

@Injectable()
export class UploadsService {
  constructor(@InjectFiles() private readonly files: Files) {}

  async uploadAvatar(userId: string, file: Blob) {
    return await this.files.upload(`avatars/${userId}.png`, file, {
      contentType: file.type,
    });
  }
}

The configured gateway router is also available under the FILES_API token for manual wiring or tests.

Options beyond path and global are the gateway options (minus the per-request files factory form — mount files-sdk/express manually for multi-tenant routing), and the endpoint speaks the same protocol as every other binding: point useFiles or createFilesClient at your mount path and lock it down with authorize.

Was this page helpful?