{"id":17829,"library":"nestjs-form-data","title":"NestJS FormData Handling","description":"nestjs-form-data provides an object-oriented approach to managing `multipart/form-data` requests in NestJS, specifically designed for file uploads and form field serialization. Unlike the built-in Multer integration, it allows files to be treated as first-class properties within Data Transfer Objects (DTOs), enabling declarative validation with `class-validator` and `class-transformer`. The current stable version is `11.0.1`, with active development indicated by recent major releases addressing features, fixes, and security concerns. Key differentiators include automatic cleanup of temporary files, pluggable storage options (memory, file system, or custom), reliable MIME type detection using magic numbers, and full support for nested objects in form data. It is compatible with NestJS versions 7 through 11 and supports both Express and Fastify platforms.","status":"active","version":"11.0.1","language":"javascript","source_language":"en","source_url":"https://github.com/dmitriy-nz/nestjs-form-data","tags":["javascript","form data","nestjs multipart","nestjs form data","nestjs form data interceptor","nestjs file upload","nestjs validate file","nestjs store file","file middleware","typescript"],"install":[{"cmd":"npm install nestjs-form-data","lang":"bash","label":"npm"},{"cmd":"yarn add nestjs-form-data","lang":"bash","label":"yarn"},{"cmd":"pnpm add nestjs-form-data","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for NestJS core functionalities like decorators, pipes, and modules.","package":"@nestjs/common","optional":false},{"reason":"Essential for bootstrapping NestJS applications and core runtime.","package":"@nestjs/core","optional":false},{"reason":"Used for transforming plain objects to DTO instances, crucial for hydrating file objects.","package":"class-transformer","optional":false},{"reason":"Enables declarative validation of DTO properties, including custom file validators.","package":"class-validator","optional":false},{"reason":"Required by NestJS and `class-transformer` for decorator-based metadata reflection.","package":"reflect-metadata","optional":false},{"reason":"A peer dependency of NestJS itself, used for reactive programming patterns.","package":"rxjs","optional":false}],"imports":[{"note":"Main module to be imported into your NestJS application (e.g., AppModule) to enable form data processing. Use `NestjsFormDataModule.config()` for global options.","wrong":"const { NestjsFormDataModule } = require('nestjs-form-data')","symbol":"NestjsFormDataModule","correct":"import { NestjsFormDataModule } from 'nestjs-form-data'"},{"note":"Decorator applied to controller methods (`@Post()`, `@Patch()`, etc.) to activate form data parsing for that specific route. It's a named import.","wrong":"import FormDataRequest from 'nestjs-form-data'","symbol":"FormDataRequest","correct":"import { FormDataRequest } from 'nestjs-form-data'"},{"note":"Represents an uploaded file stored in memory. It's a concrete implementation of `StoredFile` and is commonly used in DTOs for smaller files.","symbol":"MemoryStoredFile","correct":"import { MemoryStoredFile } from 'nestjs-form-data'"},{"note":"These are custom validation decorators provided by `nestjs-form-data` specifically for file properties within DTOs. `class-validator` itself needs to be installed as a peer dependency.","wrong":"import { IsFile } from 'class-validator'","symbol":"IsFile, MaxFileSize, HasMimeType","correct":"import { IsFile, MaxFileSize, HasMimeType } from 'nestjs-form-data'"}],"quickstart":{"code":"import { NestFactory } from '@nestjs/core';\nimport { ValidationPipe, Module, Controller, Post, Body } from '@nestjs/common';\nimport { NestjsFormDataModule, FormDataRequest, MemoryStoredFile, IsFile, MaxFileSize, HasMimeType } from 'nestjs-form-data';\n\n// 1. Define your DTO for file upload and form fields\nclass UploadAvatarDto {\n  @IsFile()\n  @MaxFileSize(1e6, { message: 'Avatar file size must not exceed 1MB' })\n  @HasMimeType(['image/jpeg', 'image/png'], { message: 'Avatar must be a JPEG or PNG image' })\n  avatar: MemoryStoredFile;\n\n  @Body('userId')\n  userId: string;\n}\n\n// 2. Create your controller\n@Controller('users')\nexport class UsersController {\n  @Post('avatar')\n  @FormDataRequest() // Apply the decorator to enable form data parsing\n  uploadAvatar(@Body() dto: UploadAvatarDto) {\n    // dto.avatar is now a MemoryStoredFile instance\n    console.log(`User ${dto.userId} uploaded avatar:`);\n    console.log(`Original Name: ${dto.avatar.originalName}`);\n    console.log(`Size: ${dto.avatar.size} bytes`);\n    console.log(`MIME Type: ${dto.avatar.mimeType}`);\n    console.log(`Buffer length: ${dto.avatar.buffer.length}`);\n\n    // In a real application, you would save dto.avatar.buffer to storage (e.g., S3, local disk)\n    return { message: `Avatar for user ${dto.userId} uploaded successfully!` };\n  }\n}\n\n// 3. Register the module and global validation pipe\n@Module({\n  imports: [\n    NestjsFormDataModule.config({\n      is// Enable file system storage by default, or keep MemoryStoredFile as default\n      // storage: FileSystemStoredFile, \n    }),\n  ],\n  controllers: [UsersController],\n})\nexport class AppModule {}\n\n// 4. Bootstrap your NestJS application\nasync function bootstrap() {\n  const app = await NestFactory.create(AppModule);\n\n  app.useGlobalPipes(\n    new ValidationPipe({\n      transform: true, // Crucial for DTO transformation and file object hydration\n      whitelist: true, // Recommended for security\n      forbidNonWhitelisted: true, // Recommended for security\n    }),\n  );\n\n  await app.listen(3000);\n  console.log('Application is running on: http://localhost:3000');\n}\nbootstrap();","lang":"typescript","description":"This quickstart demonstrates how to set up `nestjs-form-data` to handle a single file upload along with a text field. It defines a DTO with file-specific validation decorators, applies the `@FormDataRequest()` decorator to a controller method, and configures a global `ValidationPipe` for DTO transformation."},"warnings":[{"fix":"Update your `NestjsFormDataModule.config()` to use `cleanupAfterSuccessHandle: boolean` and `cleanupAfterFailedHandle: boolean` instead of `autoDeleteFile`.","message":"The configuration option `autoDeleteFile` was deprecated in favor of more granular control. It has been replaced by two separate fields: `cleanupAfterSuccessHandle` and `cleanupAfterFailedHandle`.","severity":"breaking","affected_versions":">=1.9.7"},{"fix":"Upgrade to `v11.0.0` or later to mitigate the prototype pollution vulnerability. This change might subtly affect applications that previously relied on inherited properties on the parsed form data object (though this is highly unlikely and discouraged).","message":"A prototype pollution vulnerability via multipart field names (`__proto__[key]`) was fixed. The internal form-data result object is now created with `Object.create(null)` to prevent inherited properties from being modified.","severity":"breaking","affected_versions":"<11.0.0"},{"fix":"Review your usage of `@HasMimeType` decorators with the `strictSource` option after upgrading to `v11.0.0+` to ensure desired validation behavior. Adjust the `strictSource` setting if necessary.","message":"The `HasMimeType` validator's `strictSource` parameter was silently ignored in versions prior to `v11.0.0`. It now correctly enforces the source for MIME type detection, which might alter validation behavior for existing configurations.","severity":"gotcha","affected_versions":"<11.0.0"},{"fix":"Upgrade to `v11.0.1`. If you need to revert to a fire-and-forget cleanup for faster responses, configure `awaitCleanup: false` in `NestjsFormDataModule.config()`.","message":"A race condition where file cleanup (using `deleteFiles()`) was not consistently awaited before sending the response was fixed. Cleanup is now properly awaited by default. A new `awaitCleanup` configuration option (default `true`) was added to allow for fire-and-forget cleanup for faster response times.","severity":"breaking","affected_versions":"<11.0.1"},{"fix":"Ensure your `main.ts` includes `app.useGlobalPipes(new ValidationPipe({ transform: true }))`.","message":"A global `ValidationPipe` with `transform: true` is crucial for `nestjs-form-data` to correctly transform incoming request bodies into DTO instances and hydrate `StoredFile` objects, especially for file arrays. Without it, file properties might be `undefined` or plain objects.","severity":"gotcha","affected_versions":"*"},{"fix":"Upgrade your Node.js environment to version 20 or newer.","message":"This package explicitly requires Node.js version 20 or higher. Using older versions may lead to unexpected behavior or installation issues.","severity":"gotcha","affected_versions":"<20.0.0 (Node.js)"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Verify that `@FormDataRequest()` is applied to your controller method and that `app.useGlobalPipes(new ValidationPipe({ transform: true }))` is configured in `main.ts`.","cause":"The DTO property for the file (e.g., `dto.avatar`) is `undefined` or not a `StoredFile` instance, often due to missing `@FormDataRequest()` decorator or incorrect `ValidationPipe` configuration.","error":"TypeError: Cannot read properties of undefined (reading 'originalName')"},{"fix":"Ensure your client-side code (e.g., HTML form, Axios, Fetch API) correctly sets `Content-Type: multipart/form-data` and sends the data in the appropriate format. For HTML forms, `enctype=\"multipart/form-data\"` is needed.","cause":"The client making the request is not sending the `Content-Type` header as `multipart/form-data`, which is necessary for file uploads.","error":"HttpException: Request must have a Content-Type of multipart/form-data"},{"fix":"Check the `mimeTypes` array passed to `@HasMimeType()` in your DTO to ensure it includes the expected MIME types for the files being uploaded. Also, review the `strictSource` option if on `v11.0.0+`.","cause":"The MIME type of the uploaded file does not match any of the allowed types specified in the `@HasMimeType()` decorator on your DTO property.","error":"BadRequestException: Invalid mime type"},{"fix":"Increase the `maxSize` value (in bytes) provided to the `@MaxFileSize()` decorator in your DTO or adjust the `maxFileSize` global configuration in `NestjsFormDataModule.config()`.","cause":"The size of the uploaded file is larger than the maximum allowed size configured in the `@MaxFileSize()` decorator.","error":"BadRequestException: File size exceeds the allowed limit"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}