Build a Music Sharing App with Amazon S3 and AWS Amplify
Tags: beginners, aws, javascript
Published: 2020-10-13 16:21:42

---
title: Build a Music Sharing App with Amazon S3 and AWS Amplify
published: true
tags: beginners, aws, javascript
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/dy8chhu3rjk31xx8d1pd.png 
canonical_url: https://welearncode.com/get-started-s3/
---
> **June 27, 2024:** This blog post uses Amplify Gen 1, if you're starting a new Amplify app I recommend trying out [Gen 2](https://dev.to/aws/introducing-a-new-fullstack-typescript-dx-for-aws-1ap9)!


Amazon S3 was the first AWS service I ever used, which I would guess is a pretty common occurrence -- it's pretty simple and allows you to store files such as images or videos on your site.

S3 stands for **S** imple **S** torage **S** ervice. It's used for **Object** storage. This means you can store flat files -- videos, images, and text files that don't change often.

In S3, Data is organized in **buckets** , which are like folders. Objects inside those buckets have keys, file names, and values, bytes with data.

We're going to go ahead and build a music sharing app where users can upload `.mp3` files and then other users can listen to them!

**Please note that I work as a Developer Advocate on the AWS Amplify team, if you have any feedback or questions about it, please reach out to me or ask on our discord - discord.gg/amplify!**

{% youtube iabegXf05DE %}

## Security

Before we start, it's important to discuss security on an app like this. Amazon S3 [has a free tier](https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc) for the first year of your account; however, if you allow anyone to upload to your S3 bucket, a bad actor could upload a bunch of files to your account leading to fees on your end.

Therefore, it's best practice to follow the [least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege) principle and limit uploads to only those who need access.

For this quick demo, my app will allow anyone to upload and download files so that we don't need to cover authentication. **In a production application, think carefully about who needs to be able to upload files and only give them access.**

## Setup

We'll first initialize [AWS Amplify](https://aws.amazon.com/amplify/), which is a suite of tools that aid front-end and mobile development on AWS.

First, [install and configure the Amplify CLI](https://docs.amplify.aws/cli/start/install).

Then, create a project or move into one you've already created. I'm going to be starting out with a HTML/CSS/Vanilla JavaScript project with Parcel for bundling. You can follow the "Setup" instructions [on this tutorial](https://welearncode.com/first-fullstack-app/) or [download this code](https://github.com/aspittel/giphlify/tree/starter) and run `npm install` to get my setup if you want!

Then, we can run `$ amplify init` to initialize an AWS Amplify project. You will then be prompted to answer some questions -- you may need to tweak the answers a little bit for your setup if you're using a different text editor, but here are the settings I chose! Many of these are the defaults.

```yml
? Enter a name for the project: tunelify
? Enter a name for the environment: dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building: javascript
? What javascript framework are you using: none
? Source Directory Path: src
? Distribution Directory Path: dist
? Build Command: npm run-script build
? Start Command: npm run-script start
? Do you want to use an AWS profile: Yes
? Please choose the profile you want to use: aspittel
```

Then, we will use AWS Amplify to add authentication to our app, we won't actually use it for this project but under the hood it will be used for our S3 permissions.

`$ amplify add auth`

```yml
Do you want to use the default authentication and security configuration: Default configuration
How do you want users to be able to sign in: Username
Do you want to configure advanced settings: No, I am done.
```

Only one more configuration step, I promise! This time, we'll add S3 storage. **For this demo, anyone can create and read data. In production you would most likely want to limit who can upload files!**

`$ amplify add storage`

```yml
? Please select from one of the below mentioned services: Content (Images, audio, video, etc.)
? Please provide a friendly name for your resource that will be used to label this category in the project: tunelify
? Please provide bucket name: tunes
? Who should have access: Auth and guest users
? What kind of access do you want for Authenticated users: create/update, read
? What kind of access do you want for Guest users: create/update, read
? Do you want to add a Lambda Trigger for your S3 Bucket: No
```

Now, run `$ amplify push` to deploy your changes!

## The Code

Now that we've done all the configuration for our app, we only need a little bit of our own code to create an image upload form and to display our tunes.

Let's install the AWS Amplify library:

`$ npm i aws-amplify`

Now, we'll configure Amplify on our frontend. In your `script.js` add:

```js
import Amplify, { Storage } from 'aws-amplify'
import awsconfig from './aws-exports'

Amplify.configure(awsconfig)
```

In your HTML, add the following form:

```html
<form id="upload-form">
  <input type="file" name="filename" id="file-upload" accept=".mp3">
  <input type="submit" value="Upload">
</form>
```

This will allow the user to upload a file, only allowing those with a `.mp3` extension.

Then, in your JavaScript add:

```js
// select the upload form we created, and listen for a submit event on it
document.getElementById('upload-form').addEventListener('submit', e => {
  // don't refresh the page on submit
  e.preventDefault()
  // get the file from the file upload element, this will be an array.
  // we only want the first element
  const file = document.getElementById('file-upload').files[0]
  // put our file in storage, use the file's name as its S3 Key
  Storage.put(file.name, file)
    .then(item => {
      console.log(item)
    })
    .catch(err => console.error(err))
})
```

🎉 Just like that we've uploaded our file to S3!

Now, let's list all the files that are in our bucket:

```js
Storage.list('')
  .then(result => {
    result.forEach(item => console.log(item))
  })
  .catch(err => console.error(err))
```

You could change the argument to `.list()` in order to only get files with a certain prefix.

Let's make it so that we can play our audio files on the page! Change the `console.log(item)` in the two above snippets of code to `createAudioPlayer(item)` and add the following code to add an audio element to the page:

```js
const createAudioPlayer = track => {
  // Get the track from S3
  Storage.get(track.key).then(result => {
    // create an audio element and add a source element to it
    const audio = document.createElement('audio')
    const source = document.createElement('source')
    audio.appendChild(source)
    // add controls to the audio element
    audio.setAttribute('controls', '')
    // add the track source and type
    source.setAttribute('src', result)
    source.setAttribute('type', 'audio/mpeg')
    // add the item to the page
    document.querySelector('.tracks').appendChild(audio)
  })
}
```

I also ended up adding some styling to my app to make the end product look like this:

![Rainbows and purple everywhere](https://welearncode.com/get-started-s3/tunelify-screenshot.png)

The completed code is [on my GitHub](https://github.com/aspittel/s3-demo) if you'd like to take a look! I also have a tutorial [here](https://blog.alispit.tel/create-rainbow-text-with-css-three-different-methods/) on re-creating the rainbow text 🌈.

## Conclusion

I hope this was a fun demo on how to get up and running with Amazon S3 using AWS Amplify. If you'd like to learn more, [here is a tutorial on creating a CRUD app with AWS Amplify](https://welearncode.com/first-fullstack-app/), [here is an extended demo on Amplify, S3, and Svelte](https://dev.to/swyx/amplibox-a-self-hosted-file-storage-app-with-aws-amplify-1f6g), and [here is a post on using an existing S3 bucket in AWS Amplify](https://dev.to/onlybakam/aws-amplify-how-to-interact-with-an-existing-s3-bucket-3mb1).