This content originally appeared on Bits and Pieces - Medium and was authored by Ryan Adhitama
A tutorial on how to upload files to a local folder and online storage

Uploading is one of the basic skills of backend developers. In this tutorial, I wanna explain uploading files into local folders and online storage such as Cloudinary.
Cloudinary is a SaaS technology company headquartered in Santa Clara, California, with offices in Israel, England, Poland, and Singapore. The company provides cloud-based image and video management services. It enables users to upload, store, manage, manipulate, and deliver images and videos for websites and apps.
Requirement
Before we go so far, let’s prepare some software and account we need.
Software
- NodeJS (https://nodejs.org/en)
- Visual Studio Code (https://code.visualstudio.com/download)
- Postman (https://www.postman.com)
Account
- Cloudinary (https://cloudinary.com)
Setup Project
Install NestJS CLI globally:
$ npm install -g @nestjs/cli
Create a new project and test it:
$ nest new nest-upload
$ cd nest-upload
$ npm run start:dev
The output will be like this:

Route: (/local) (POST & Form Data)
- First of all, we need to install the main package for upload named multer
$ npm i @types/multer
- Create folder public/img at the root folder

- Add a function local to handle uploaded files saved in public/img folder
import {
Controller,
Post,
UploadedFile,
UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
@Controller()
export class AppController {
@Post('local')
@UseInterceptors(
FileInterceptor('file', {
storage: diskStorage({
destination: 'public/img',
filename: (req, file, cb) => {
cb(null, file.originalname);
},
}),
}),
)
async local(@UploadedFile() file: Express.Multer.File) {
return {
statusCode: 200,
data: file.path,
};
}
}
- Then, test the endpoint via Postman

Let’s access the file http://localhost:3000/public/img/download.png

The server detects the file as a route, so we need to install the package to serve a static file.
$ npm i @nestjs/serve-static
Import ServeStaticModule at AppModule (src/app.module.ts)
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..'),
})
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Let’s access the file again, and the server will return a static file.

Route: (/online) (POST & Form Data)
- Install Cloudinary and buffer-to-stream package
$ npm i cloudinary buffer-to-stream
- Create Cloudinary module and service
$ nest g mo cloudinary
$ nest g s cloudinary
- Add uploadImage function at CloudinaryService (src/cloudinary/cloudinary.service.ts). Update aaa, bbb, and ccc with your Cloudinary's credential
import { Injectable } from '@nestjs/common';
import { UploadApiErrorResponse, UploadApiResponse, v2 } from 'cloudinary';
import toStream = require('buffer-to-stream');
@Injectable()
export class CloudinaryService {
async uploadImage(
fileName: Express.Multer.File,
): Promise<UploadApiResponse | UploadApiErrorResponse> {
return new Promise((resolve, reject) => {
v2.config({
cloud_name: 'aaa',
api_key: 'bbb',
api_secret: 'ccc',
});
const upload = v2.uploader.upload_stream((error, result) => {
if (error) return reject(error);
resolve(result);
});
toStream(fileName.buffer).pipe(upload);
});
}
}
- Export CloudinaryService at CloudinaryModule (src/cloudinary/cloudinary.module.ts)
import { Module } from '@nestjs/common';
import { CloudinaryService } from './cloudinary.service';
@Module({
providers: [CloudinaryService],
exports: [CloudinaryService],
})
export class CloudinaryModule {}
- Import CloudinaryModule at AppModule (src/app.module.ts)
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CloudinaryModule } from './cloudinary/cloudinary.module';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..'),
}),
CloudinaryModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
- Add a function online to handle uploading files into Cloudinary
import {
Controller,
Post,
UploadedFile,
UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { CloudinaryService } from './cloudinary/cloudinary.service';
@Controller()
export class AppController {
constructor(private cloudinary: CloudinaryService) {}
@Post('local')
@UseInterceptors(
FileInterceptor('file', {
storage: diskStorage({
destination: 'public/img',
filename: (req, file, cb) => {
cb(null, file.originalname);
},
}),
}),
)
async local(@UploadedFile() file: Express.Multer.File) {
return {
statusCode: 200,
data: file.path,
};
}
@Post('online')
@UseInterceptors(FileInterceptor('file'))
async online(@UploadedFile() file: Express.Multer.File) {
return await this.cloudinary
.uploadImage(file)
.then((data) => {
return {
statusCode: 200,
data: data.secure_url,
};
})
.catch((err) => {
return {
statusCode: 400,
message: err.message,
};
});
}
}
💡 Pro Tip: You can now encapsulate the file upload logic into a package and push it to Bit as an independently tested and versioned component. This would let you reuse this component across multiple projects.
Learn more here:
Extracting and Reusing Pre-existing Components using bit add
- Test via Postman

Conclusion
Today we have learned how to create Upload File with NestJS. Stay on top of several other news, let’s connect via LinkedIn!
https://www.linkedin.com/in/ryanadhitama/
Build Apps with reusable components, just like Lego

Bit’s open-source tool help 250,000+ devs to build apps with components.
Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.
Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:
→ Micro-Frontends
→ Design System
→ Code-Sharing and reuse
→ Monorepo
Learn more:
- Creating a Developer Website with Bit components
- How We Build Micro Frontends
- How we Build a Component Design System
- How to reuse React components across your projects
- 5 Ways to Build a React Monorepo
- How to Create a Composable React App with Bit
- How to Reuse and Share React Components in 2023: A Step-by-Step Guide
- 5 Tools for Building React Component Libraries in 2023
Upload File with NestJS was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Ryan Adhitama

Ryan Adhitama | Sciencx (2023-05-29T13:13:51+00:00) Upload File with NestJS. Retrieved from https://www.scien.cx/2023/05/29/upload-file-with-nestjs/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.