# Uploading Files to Cloudflare R2 with AWS SDK for JavaScript v3

Cloudflare R2 offers a compelling storage solution that's fully compatible with the S3 API, making it an excellent choice for developers looking for cost-effective object storage. One of the significant advantages of using Cloudflare R2 is its promise of zero egress fees, which can drastically reduce costs for applications that serve a large amount of data.

In this post, we'll explore how to upload files to Cloudflare R2 using the AWS SDK for JavaScript v3, the latest iteration of the SDK that offers a modular, more efficient way to interact with AWS services.

## Why Use AWS SDK v3?

The AWS SDK for JavaScript v3 is a rewrite of v2 with some key improvements:
- **Modular Architecture**: You can now install only the packages you need, reducing the size of your project.
- **First-class TypeScript support**: Making it easier to use in TypeScript projects.
- **Improved API for Promises**: Simplifies the code, especially when using async/await.

## Prerequisites
Before we start, make sure you have:
- Node.js installed on your development machine.
- An R2 bucket created in your Cloudflare account.
- Your R2 Access and Secret Keys.

## Step 1: Setting Up Your Project

First, initialize a new Node.js project and install the necessary AWS SDK v3 packages:

```bash
mkdir r2-upload-example
cd r2-upload-example
npm init -y
npm install @aws-sdk/client-s3 @aws-sdk/lib-storage
```

## Step 2: Configuring the S3 Client

Create a new file `s3Client.js` to configure and export the S3 client tailored for R2:

```javascript
const { S3Client } = require('@aws-sdk/client-s3');

const REGION = "auto"; // R2 does not require a region, but AWS SDK expects one
const s3Client = new S3Client({
  region: REGION,
  endpoint: "https://<your-r2-endpoint>",
  credentials: {
    accessKeyId: "<your-access-key-id>",
    secretAccessKey: "<your-secret-access-key>",
  },
  forcePathStyle: true, // Important for R2 compatibility
});

module.exports = { s3Client };
```

Replace `<your-r2-endpoint>`, `<your-access-key-id>`, and `<your-secret-access-key>` with your actual Cloudflare R2 endpoint and credentials.

## Step 3: Uploading Files to R2

Now, let's write the code to upload files. Create `uploadFile.js`:

```javascript
const { s3Client } = require('./s3Client');
const { Upload } = require('@aws-sdk/lib-storage');
const fs = require('fs');

async function uploadFile(filePath, bucketName, key) {
  const fileStream = fs.createReadStream(filePath);

  try {
    const uploader = new Upload({
      client: s3Client,
      params: {
        Bucket: bucketName,
        Key: key,
        Body: fileStream,
      },
    });

    uploader.on('httpUploadProgress', (progress) => {
      console.log(`Upload progress: ${progress.loaded} of ${progress.total} bytes`);
    });

    await uploader.done();
    console.log(`File uploaded: ${key}`);
  } catch (err) {
    console.error("Error uploading file:", err);
  }
}

module.exports = { uploadFile };
```

## Step 4: Putting It All Together

Finally, create `index.js` to use the `uploadFile` function:

```javascript
const { uploadFile } = require('./uploadFile');

const bucketName = '<your-bucket-name>';
const filePath = 'path/to/your/file.txt';
const key = 'your/file/key.txt';

uploadFile(filePath, bucketName, key)
  .then(() => console.log("File uploaded successfully"))
  .catch((err) => console.error("Failed to upload file:", err));
```

Make sure to replace `<your-bucket-name>`, `path/to/your/file.txt`, and `your/file/key.txt` with your bucket name, local file path, and desired key (file name in R2) respectively.

## Conclusion

You've now learned how to configure the AWS SDK for JavaScript v3 to upload files to Cloudflare R2, leveraging the modular nature of the SDK for more efficient code. Cloudflare's R2 storage, with its compatibility with the S3 API and the advantage of no egress fees, offers an attractive solution for storing and serving content.

Happy coding!

