# How to upload an image to S3 using Node.js

> Learn how to upload an image to AWS S3 from Node.js with the aws-sdk, creating an S3 client, sending the image blob, and reading its public Location URL.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2022-04-12 | Topics: [Node.js](https://flaviocopes.com/tags/node/) | Canonical: https://flaviocopes.com/node-aws-s3-upload-image/

In this post I want to share how to upload an image to AWS S3, the wonderful cloud file hosting solution provided by Amazon Web Services.

> I already wrote about this topic in the past in [how to upload files to S3 from Node.js](https://flaviocopes.com/node-upload-files-s3/)

First, install the `aws-sdk` library:

```
npm install aws-sdk
```

Import it in your code at the top of the file you're going to add this file upload to S3 functionality:

```js
import AWS from 'aws-sdk'
```

Next, use the SDK to create an instance of the S3 object. I assign it to a `s3` variable:

```js
const s3 = new AWS.S3({
  accessKeyId: process.env.AWS_S3_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_S3_SECRET_ACCESS_KEY,
})
```

Note that I use two [environment variables](https://flaviocopes.com/node-environment-variables/) here: `AWS_S3_ACCESS_KEY_ID` and `AWS_S3_SECRET_ACCESS_KEY`. 

Now comes some "administrative work". You need to create an IAM profile on AWS (the credentials) with programmatic access with the permissions for `AWSCloudFormationFullAccess` and `AmazonS3FullAccess` and an S3 bucket that this user has access to.

I won't cover this aspect here as you can find tons of articles and documentation about this. I'll just talk about the [JavaScript](https://flaviocopes.com/javascript/) code you need.

Now, you need an **image blob** to upload.

You can use a URL like this:

```js
const imageURL = 'https://url-to-image.jpg'
const res = await fetch(imageURL)
const blob = await res.buffer()
```

or you can get an image sent from a form image field upload in a [multipart form](https://flaviocopes.com/nextjs-upload-files/):

```js
const imagePath = req.files[0].path
const blob = fs.readFileSync(imagePath)
```

Finally, make a call to `s3.upload()` and call its `.promise()` method so you can use await to wait until it finishes to get the uploaded file object:

```js
const uploadedImage = await s3.upload({
  Bucket: process.env.AWS_S3_BUCKET_NAME,
  Key: req.files[0].originalFilename,
  Body: blob,
}).promise()
```

> `AWS_S3_BUCKET_NAME` is the name of the S3 bucket, another environment variable
 
Finally, you can get the URL of the uploaded image on S3 by referencing the `Location` property:

```js
uploadedImage.Location
```

You have to make sure you [set the S3 bucket as public](https://flaviocopes.com/aws-s3-public/) so you can access that image URL.
