Image upload with Node.js and Typescript

Ward Price
3 min readMar 1, 2021

In Ruby on Rails we can use the ActiveStorage gem to upload files to your database. Although it takes a little getting used to, it allows you to rather simply upload an image and (in my case) save it in an AWS S3 bucket, then saves the S3 url as in a table as a blob with another table that references it’s placement in the blog table.

So how do we do this in Node.js?

That has what I’ve been researching currently and there seem to be two popular approaches.

Approach 1: aws-sdk, multer and multer-s3

Approach one is to use install the above packages which will upload directly to your configured s3 bucket for you.

aws-sdk is the sdk written by amazon themselves and does have typescript support if you install the types for node. To install enter the following into your terminal at your project directory

$ npm i aws-sdk
$ npm i -D @types/node

multer is “…a middleware for handling multipart/form-data which is primarily used for uploading files.” This will add the file to the request object created so that it can be parsed for our upload.

multer-s3 is a little extra sauce that helps optimize our file data for use with S3

To fit this all together create a seperate file to be imported in your routes.

import aws from 'aws-sdk';
import multer, { FileFilterCallback } from 'multer';
import multerS3 from 'multer-s3';
const s3 = new aws.S3();aws.config.update({
secretAccessKey: process.env.S3_ACCESS_SECRET,
accessKeyId: process.env.S3_ACCESS_KEY,
region: 'us-east-1' // or whatever region your s3 bucket is in
});
const fileFilter = (req: Express.Request, file: Express.Multer.File, cb: FileFilterCallback) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(new Error());
}
};
const upload = multer({
fileFilter,
storage: multerS3({
acl: 'public-read',
s3,
bucket: {your bucket name here as a string},
metadata: (req, file, cb) => {
cb(null, { fieldName: 'TESTING_METADATA' });
},
key: (req, file, cb) => {
cb(null, Date.now().toString());
},
}),
});
export default upload;

Approach 2: Cloudinary

Cloudinary takes control of a lot of the annoying bits of uploading images, even offers services that will auto resize, crop or color your uploaded images too.

$ npm i multer cloudinary multer-storage-cloudinary

multer is “…a middleware for handling multipart/form-data which is primarily used for uploading files.” This will add the file to the request object created so that it can be parsed for our upload.

cloudinary is the official package built by cloudinary to interact with their servers

multer-storage-cloudinary is the an engine to utilize their cloud engine.

const cloudinary = require('cloudinary').v2;
import { CloudinaryStorage } from 'multer-storage-cloudinary';
import multer from 'multer';
require('dotenv').config();cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.CLOUD_KEY,
api_secret: process.env.CLOUD_SECRET,
});
const cloudStorage = new CloudinaryStorage({
cloudinary,
params: {
allowed_formats: ['jpg', 'png'],
unique_filename: true,
folder: {your folder name as a string},
},
});

And thats it, Happy coding!

--

--