---
title: "Set up Storage"
section: "build-a-backend/storage"
platforms: ["angular", "javascript", "nextjs", "react", "vue", "swift", "android", "flutter", "react-native"]
gen: 2
last-updated: "2026-04-22T14:02:04.000Z"
url: "https://docs.amplify.aws/react/build-a-backend/storage/set-up-storage/"
---

In this guide, you will learn how to set up storage in your Amplify app. You will set up your backend resources, and enable listing, uploading, and downloading files.

If you have not yet created an Amplify app, visit the [quickstart guide](/[platform]/start/quickstart/).

Amplify Storage seamlessly integrates file storage and management capabilities into frontend web and mobile apps, built on top of Amazon Simple Storage Service (Amazon S3). It provides intuitive APIs and UI components for core file operations, enabling developers to build scalable and secure file storage solutions without dealing with cloud service complexities.

## Building your storage backend

First, create a file `amplify/storage/resource.ts`. This file will be the location where you configure your storage backend. Instantiate storage using the `defineStorage` function and providing a `name` for your storage bucket. This `name` is a friendly name to identify your bucket in your backend configuration. Amplify will generate a unique identifier for your app using a UUID, the name attribute is just for use in your app.

```ts title="amplify/storage/resource.ts"
import { defineStorage } from '@aws-amplify/backend';

export const storage = defineStorage({
  name: 'amplifyTeamDrive'
});
```

Import your storage definition in your `amplify/backend.ts` file that contains your backend definition. Add storage to `defineBackend`.

```ts title="amplify/backend.ts"
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
// highlight-next-line
import { storage } from './storage/resource';

defineBackend({
  auth,
  // highlight-next-line
  storage
});
```

Now when you run `npx ampx sandbox` or deploy your app on Amplify, it will configure an Amazon S3 bucket where your files will be stored. Before files can be accessed in your application, you must configure storage access rules.

To deploy these changes, commit them to git and push the changes upstream. Amplify's CI/CD system will automatically pick up the changes and build and deploy the updates.

```bash title="Terminal" showLineNumbers={false}
git commit -am "add storage backend"
git push
```

### Define File Path Access

By default, no users or other project resources have access to any files in the storage bucket. Access must be explicitly granted within `defineStorage` using the `access` callback.

The access callback returns an object where each key in the object is a file path and each value in the object is an array of access rules that apply to that path.

The following example shows you how you can set up your file storage structure for a generic photo sharing app. Here,

1. Guests have access to see all profile pictures and only the users that uploaded the profile picture can replace or delete them. Users are identified by their Identity Pool ID in this case i.e. identityID.
2. There's also a general pool where all users can submit pictures.

[Learn more about customizing access to file path](/[platform]/build-a-backend/storage/authorization/).

```ts title="amplify/storage/resource.ts"
export const storage = defineStorage({
  name: 'amplifyTeamDrive',
  access: (allow) => ({
    'profile-pictures/{entity_id}/*': [
      allow.guest.to(['read']),
      allow.entity('identity').to(['read', 'write', 'delete'])
    ],
    'picture-submissions/*': [
      allow.authenticated.to(['read','write']),
      allow.guest.to(['read', 'write'])
    ],
  })
});
```

### Configure additional storage buckets

Amplify Storage gives you the flexibility to configure your backend to automatically provision and manage multiple storage resources. 

You can define additional storage buckets by using the same `defineStorage` function and providing a unique, descriptive `name` to identify the storage bucket. You can pass this `name` to the storage APIs to specify the bucket you want to perform the action to. Ensure that this `name` attribute is unique across the defined storage buckets in order to reliably identify the correct bucket and prevent conflicts.

It's important to note that if additional storage buckets are defined one of them must be marked as default with the `isDefault` flag.

```ts title="amplify/storage/resource.ts"
export const firstBucket = defineStorage({
  name: 'firstBucket',
  isDefault: true, // identify your default storage bucket (required)
});

export const secondBucket = defineStorage({
  name: 'secondBucket',
  access: (allow) => ({
    'private/{entity_id}/*': [
      allow.entity('identity').to(['read', 'write', 'delete'])
    ]
  })
})
```

Add additional storage resources to the backend definition.

```ts title="amplify/backend.ts"
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { firstBucket, secondBucket } from './storage/resource';

defineBackend({
  auth,
  firstBucket,
  // highlight-next-line
  secondBucket
});
```

<!-- Platform: react, angular, javascript, vue, nextjs, react-native -->
### Storage bucket client usage

Additional storage buckets can be referenced from application code by passing the `bucket` option to Amplify Storage APIs. You can provide a target bucket's name assigned in Amplify Backend.

```ts
import { downloadData } from 'aws-amplify/storage';

try {
  const result = downloadData({
    path: "album/2024/1.jpg",
    options: {
      // highlight-start
      // Specify a target bucket using name assigned in Amplify Backend
      bucket: "secondBucket"
      // highlight-end
    }
  }).result;
} catch (error) {
  console.log(`Error: ${error}`)
}
```
Alternatively, you can also pass in an object by specifying the bucket name and region from the console. See each Amplify Storage API page for additional usage examples.

```ts
import { downloadData } from 'aws-amplify/storage';

try {
  const result = downloadData({
    path: 'album/2024/1.jpg',
    options: {
      // highlight-start
      // Alternatively, provide bucket name from console and associated region
      bucket: {
        bucketName: 'second-bucket-name-from-console',
        region: 'us-east-2'
      }
      // highlight-end
    }
  }).result;
} catch (error) {
  console.log(`Error: ${error}`);
}

```
<!-- /Platform -->

<!-- Platform: android -->
### Storage bucket client usage

Additional storage buckets can be referenced from application code by passing the `bucket` option to Amplify Storage APIs. You can provide a target bucket's name assigned in Amplify Backend.

#### [Java]

```java
StorageBucket secondBucket = StorageBucket.fromOutputs("secondBucket");
StorageDownloadFileOptions options = StorageDownloadFileOptions.builder().bucket(secondBucket).build();
Amplify.Storage.downloadFile(
        StoragePath.fromString("public/example"),
        new File(getApplicationContext().getFilesDir() + "/download.txt"),
        options,
        result -> Log.i("MyAmplifyApp", "Successfully downloaded: " + result.getFile().getName()),
        error -> Log.e("MyAmplifyApp",  "Download Failure", error)
);
```

#### [Kotlin - Callbacks]

```kotlin
val secondBucket = StorageBucket.fromOutputs("secondBucket")
val options = StorageDownloadFileOptions.builder().bucket(secondBucket).build()
val file = File("${applicationContext.filesDir}/download.txt")
Amplify.Storage.downloadFile(StoragePath.fromString("public/example"), file, option,
    { Log.i("MyAmplifyApp", "Successfully downloaded: ${it.file.name}") },
    { Log.e("MyAmplifyApp",  "Download Failure", it) }
)
```

#### [Kotlin - Coroutines]

```kotlin
val secondBucket = StorageBucket.fromOutputs("secondBucket")
val options = StorageDownloadFileOptions.builder().bucket(secondBucket).build()
val file = File("${applicationContext.filesDir}/download.txt")
val download = Amplify.Storage.downloadFile(StoragePath.fromString("public/example"), file, options)
try {
    val fileName = download.result().file.name
    Log.i("MyAmplifyApp", "Successfully downloaded: $fileName")
} catch (error: StorageException) {
    Log.e("MyAmplifyApp", "Download Failure", error)
}
```

#### [RxJava]

```java      
StorageBucket secondBucket = StorageBucket.fromOutputs("secondBucket");
StorageDownloadFileOptions options = StorageDownloadFileOptions.builder().bucket(secondBucket).build();
RxProgressAwareSingleOperation<StorageDownloadFileResult> download =
        RxAmplify.Storage.downloadFile(
            StoragePath.fromString("public/example"),
            new File(getApplicationContext().getFilesDir() + "/download.txt"),
            options
        );

download
    .observeResult()
    .subscribe(
        result -> Log.i("MyAmplifyApp", "Successfully downloaded: " + result.getFile().getName()),
        error -> Log.e("MyAmplifyApp",  "Download Failure", error)
    );
```

Alternatively, you can also pass in an object by specifying the bucket name and region from the console. See each Amplify Storage API page for additional usage examples.

#### [Java]

```java
BucketInfo bucketInfo = new BucketInfo("second-bucket-name-from-console", "us-east-2");
StorageBucket secondBucket = StorageBucket.fromBucketInfo(bucketInfo);
StorageDownloadFileOptions options = StorageDownloadFileOptions.builder().bucket(secondBucket).build();
Amplify.Storage.downloadFile(
        StoragePath.fromString("public/example"),
        new File(getApplicationContext().getFilesDir() + "/download.txt"),
        options,
        result -> Log.i("MyAmplifyApp", "Successfully downloaded: " + result.getFile().getName()),
        error -> Log.e("MyAmplifyApp",  "Download Failure", error)
);
```

#### [Kotlin - Callbacks]

```kotlin
val bucketInfo = BucketInfo("second-bucket-name-from-console", "us-east-2")
val secondBucket = StorageBucket.fromBucketInfo(bucketInfo)
val options = StorageDownloadFileOptions.builder().bucket(secondBucket).build()
val file = File("${applicationContext.filesDir}/download.txt")
Amplify.Storage.downloadFile(StoragePath.fromString("public/example"), file, options,
    { Log.i("MyAmplifyApp", "Successfully downloaded: ${it.file.name}") },
    { Log.e("MyAmplifyApp",  "Download Failure", it) }
)
```

#### [Kotlin - Coroutines]

```kotlin
val bucketInfo = BucketInfo("second-bucket-name-from-console", "us-east-2")
val secondBucket = StorageBucket.fromBucketInfo(bucketInfo)
val options = StorageDownloadFileOptions.builder().bucket(secondBucket).build()
val file = File("${applicationContext.filesDir}/download.txt")
val download = Amplify.Storage.downloadFile(StoragePath.fromString("public/example"), file, options)
try {
    val fileName = download.result().file.name
    Log.i("MyAmplifyApp", "Successfully downloaded: $fileName")
} catch (error: StorageException) {
    Log.e("MyAmplifyApp", "Download Failure", error)
}
```

#### [RxJava]

```java
BucketInfo bucketInfo = new BucketInfo("second-bucket-name-from-console", "us-east-2");
StorageBucket secondBucket = StorageBucket.fromBucketInfo(bucketInfo);
StorageDownloadFileOptions options = StorageDownloadFileOptions.builder().bucket(secondBucket).build();
RxProgressAwareSingleOperation<StorageDownloadFileResult> download =
        RxAmplify.Storage.downloadFile(
            StoragePath.fromString("public/example"),
            new File(getApplicationContext().getFilesDir() + "/download.txt"),
            options,
        );

download
    .observeResult()
    .subscribe(
        result -> Log.i("MyAmplifyApp", "Successfully downloaded: " + result.getFile().getName()),
        error -> Log.e("MyAmplifyApp",  "Download Failure", error)
    );
```

<!-- /Platform -->

<!-- Platform: swift -->
### Storage bucket client usage

Additional storage buckets can be referenced from application code by passing the `bucket` option to Amplify Storage APIs. You can provide a target bucket's name assigned in Amplify Backend.

```swift
let downloadTask = Amplify.Storage.downloadData(
    path: .fromString("public/example/path"),
    options: .init(
        bucket: .fromOutputs(name: "secondBucket")
    )
)
```

Alternatively, you can also directly specify the bucket name and region from the console. See each Amplify Storage API page for additional usage examples.

```swift
let downloadTask = Amplify.Storage.downloadData(
    path: .fromString("public/example/path"),
    options: .init(
        bucket: .fromBucketInfo(.init(
            bucketName: "another-bucket-name",
            region: "another-bucket-region")
        )    
    )
)
```
<!-- /Platform -->

<!-- Platform: flutter -->
### Storage bucket client usage

Additional storage buckets can be referenced from application code by passing the `bucket` option to Amplify Storage APIs. You can provide a target bucket's name assigned in Amplify Backend.

```dart
import 'package:amplify_flutter/amplify_flutter.dart';

try {
  final result = await Amplify.Storage.downloadData(
    path: const StoragePath.fromString('album/2024/1.jpg'),
    options: StorageDownloadDataOptions(
      // highlight-start
      // Specify a target bucket using name assigned in Amplify Backend
      bucket: StorageBucket.fromOutputs('secondBucket'),
      // highlight-end
    ),
  ).result;
} on Exception catch (e) {
    print('Error: $e');
}
```
Alternatively, you can also pass in an object by specifying the bucket name and region from the console. See each Amplify Storage API page for additional usage examples.

```dart
import 'package:amplify_flutter/amplify_flutter.dart';

try {
  final result = await Amplify.Storage.downloadData(
    path: const StoragePath.fromString('album/2024/1.jpg'),
    options: const StorageDownloadDataOptions(
      // highlight-start
      // Alternatively, provide bucket name from console and associated region
      bucket: StorageBucket.fromBucketInfo(
        BucketInfo(
          bucketName: 'second-bucket-name-from-console',
          region: 'us-east-2',
        ),
      ),
      // highlight-end
    ),
  ).result;
} on Exception catch (e) {
  print('Error: $e');
}
```
<!-- /Platform -->

## Configure storage deletion behavior

By default, Amplify deletes the S3 bucket and all its objects when you remove the storage resource or delete your Amplify app. To preserve the bucket and its data, set `keepOnDelete` to `true`:

```ts title="amplify/storage/resource.ts"
export const storage = defineStorage({
  name: 'myProjectFiles',
  // Keep the bucket when the resource is removed
  keepOnDelete: true,
});
```

| Setting | Behavior |
| --- | --- |
| `keepOnDelete: false` (default) | The bucket and all objects are deleted on removal. |
| `keepOnDelete: true` | The bucket is preserved on removal. You must delete it manually when no longer needed. |

> **Warning:** Retained buckets continue to incur S3 storage costs. To avoid unexpected charges, delete retained buckets manually through the [AWS S3 console](https://console.aws.amazon.com/s3/) or the AWS CLI (replace `your-bucket-name`: `aws s3 rb s3://your-bucket-name --force`) when they are no longer needed.

> **Info:** When using `npx ampx sandbox`, the bucket is always deleted regardless of the `keepOnDelete` setting. This prevents resource accumulation during development. The `keepOnDelete` setting only takes effect in deployed environments (connected Git branches).

## Connect your app code to the storage backend

The Amplify Storage library provides client APIs that connect to the backend resources you defined.

<!-- Platform: react, angular, javascript, vue, nextjs, react-native -->
### Configure Amplify in project

Import and load the configuration file in your app. It's recommended you add the Amplify configuration step to your app's root entry point. For example `index.js` in React or `main.ts` in Angular.

```javascript
import { Amplify } from 'aws-amplify';
import outputs from '../amplify_outputs.json';

Amplify.configure(outputs);
```
<Callout warning="true">

Make sure you call `Amplify.configure` as early as possible in your application’s life-cycle. A missing configuration or `NoCredentials` error is thrown if `Amplify.configure` has not been called before other Amplify JavaScript APIs.

</Callout>
<!-- /Platform -->

<!-- Platform: swift -->
### Prerequisites

An application with Amplify libraries integrated and a minimum target of any of the following:
- **iOS 13.0**, using **Xcode 14.1** or later.
- **macOS 10.15**, using **Xcode 14.1** or later.
- **tvOS 13.0**, using **Xcode 14.3** or later.
- **watchOS 9.0**, using **Xcode 14.3** or later.
- **visionOS 1.0**, using **Xcode 15 beta 2** or later. (Preview support - see below for more details.)

For a full example, please follow the [project setup walkthrough](/[platform]/start/quickstart/).

<Callout>

visionOS support is currently in **preview** and can be used by using the latest [Amplify Release](https://github.com/aws-amplify/amplify-swift/releases). 
As new Xcode and visionOS versions are released, the support will be updated with any necessary fixes on a best effort basis.

</Callout>

### Install Amplify library via Swift Package Manager

1. To install Amplify Libraries in your application, open your project in Xcode and select **File > Add Packages...**.

2. Enter the **Amplify Library for Swift** GitHub repo URL (`https://github.com/aws-amplify/amplify-swift`) into the search bar and click **Add Package**.

  <Callout>

  **Note:** **Up to Next Major Version** should be selected from the **Dependency Rule** dropdown.

  </Callout>

3. Lastly, choose **AWSS3StoragePlugin**, **AWSCognitoAuthPlugin**, and **Amplify**. Then click **Add Package**.

### Configure Amplify in project

Initialize the Amplify Storage category by calling `Amplify.add(plugin:)`. To complete initialization call `Amplify.configure()`.

#### [SwiftUI]

Add the following imports to the top of your `App` scene and configure Amplify in the `init`:
```swift
import Amplify
import AWSCognitoAuthPlugin
import AWSS3StoragePlugin

@main
struct MyAmplifyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }

    init() {
        do {
            try Amplify.add(plugin: AWSCognitoAuthPlugin())
            try Amplify.add(plugin: AWSS3StoragePlugin())
            try Amplify.configure(with: .amplifyOutputs)
            print("Amplify configured with Auth and Storage plugins")
        } catch {
            print("Failed to initialize Amplify with \(error)")
        }
    }
}
```

#### [UIKit]

Add the following imports to the top of your `AppDelegate.swift` file:

```swift
import Amplify
import AWSCognitoAuthPlugin
import AWSS3StoragePlugin
```

Add the following code to the `application:didFinishLaunchingWithOptions` method:

```swift
func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    do {
        try Amplify.add(plugin: AWSCognitoAuthPlugin())
        try Amplify.add(plugin: AWSS3StoragePlugin())
        try Amplify.configure(with: .amplifyOutputs)
        print("Amplify configured with Auth and Storage plugins")
    } catch {
        print("Failed to initialize Amplify with \(error)")
    }

    return true
}
```

Upon building and running this application you should see the following in your console window:

```console
Amplify configured with Auth and Storage plugins
```
<!-- /Platform -->

<!-- Platform: android -->
### Prerequisites

* An Android application targeting Android API level 24 (Android 7.0) or above
    * For a full example of creating Android project, please follow the [quickstart guide](/[platform]/start/quickstart/)

### Install the Amplify library

Expand **Gradle Scripts**, open **build.gradle (Module: app)**. You will already have configured Amplify by following the steps in the [quickstart guide](/[platform]/start/quickstart/).

Add these libraries into the `dependencies` block:
```kotlin title="app/build.gradle.kts"
android {
    compileOptions {
        // Support for modern Java features
        isCoreLibraryDesugaringEnabled = true
    }
}

dependencies {
    // Amplify API dependencies
    // highlight-start
    implementation("com.amplifyframework:aws-storage-s3:ANDROID_VERSION")
    implementation("com.amplifyframework:aws-auth-cognito:ANDROID_VERSION")    
    // highlight-end
    // ... other dependencies
    coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:ANDROID_DESUGAR_VERSION")
}
```

`aws-auth-cognito` is used to provide authentication for Amazon S3.

Click **Sync Now**.

### Configure Amplify in your project

Initialize Amplify Storage by calling `Amplify.addPlugin()`. To complete initialization, call `Amplify.configure()`.

Add the following code to your `onCreate()` method in your application class:

> **Warning:** Before calling the `Amplify.configure` function, make sure to either download the `amplify_outputs.json` file from the console, or generate it with the following command: 
> 
> ```bash title="Terminal" showLineNumbers={false}
npx ampx generate outputs --app-id <app-id> --branch main --out-dir app/src/main/res/raw
```
> 
> Next, be sure the file you generated or downloaded is in the appropriate resource directory for your application (for example, `app/src/main/res/raw`) in your Android project. Otherwise, you will not be able to compile your application.

#### [Java]

```java
import android.util.Log;
import com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin;
import com.amplifyframework.core.Amplify;
import com.amplifyframework.core.configuration.AmplifyOutputs;
import com.amplifyframework.storage.s3.AWSS3StoragePlugin;
```

```java
Amplify.addPlugin(new AWSCognitoAuthPlugin());
Amplify.addPlugin(new AWSS3StoragePlugin());
```

Your class will look like this:

```java
public class MyAmplifyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        try {
            // Add these lines to add the AWSCognitoAuthPlugin and AWSS3StoragePlugin plugins
            Amplify.addPlugin(new AWSCognitoAuthPlugin());
            Amplify.addPlugin(new AWSS3StoragePlugin());
            Amplify.configure(AmplifyOutputs.fromResource(R.raw.amplify_outputs), getApplicationContext());

            Log.i("MyAmplifyApp", "Initialized Amplify");
        } catch (AmplifyException error) {
            Log.e("MyAmplifyApp", "Could not initialize Amplify", error);
        }
    }
}
```

#### [Kotlin]

```kotlin
import android.util.Log
import com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin
import com.amplifyframework.core.Amplify
import com.amplifyframework.core.configuration.AmplifyOutputs
import com.amplifyframework.storage.s3.AWSS3StoragePlugin
```

```kotlin
Amplify.addPlugin(AWSCognitoAuthPlugin())
Amplify.addPlugin(AWSS3StoragePlugin())
```

Your class will look like this:

```kotlin
class MyAmplifyApp : Application() {
    override fun onCreate() {
        super.onCreate()

        try {
            // Add these lines to add the AWSCognitoAuthPlugin and AWSS3StoragePlugin plugins
            Amplify.addPlugin(AWSCognitoAuthPlugin())
            Amplify.addPlugin(AWSS3StoragePlugin())
            Amplify.configure(AmplifyOutputs(R.raw.amplify_outputs), applicationContext)
            Log.i("MyAmplifyApp", "Initialized Amplify")
        } catch (error: AmplifyException) {
            Log.e("MyAmplifyApp", "Could not initialize Amplify", error)
        }
    }
}
```

#### [RxJava]

```java
import android.util.Log;
import com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin;
import com.amplifyframework.core.configuration.AmplifyOutputs;
import com.amplifyframework.rx.RxAmplify;
import com.amplifyframework.storage.s3.AWSS3StoragePlugin;
```

```java
RxAmplify.addPlugin(new AWSCognitoAuthPlugin());
RxAmplify.addPlugin(new AWSS3StoragePlugin());
```

Your class will look like this:

```java
public class MyAmplifyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        try {
            // Add these lines to add the AWSCognitoAuthPlugin and AWSS3StoragePlugin plugins
            RxAmplify.addPlugin(new AWSCognitoAuthPlugin());
            RxAmplify.addPlugin(new AWSS3StoragePlugin());
            RxAmplify.configure(AmplifyOutputs.fromResource(R.raw.amplify_outputs), getApplicationContext());

            Log.i("MyAmplifyApp", "Initialized Amplify");
        } catch (AmplifyException error) {
            Log.e("MyAmplifyApp", "Could not initialize Amplify", error);
        }
    }
}
```

Note that because the storage category requires auth, you will need to either configure [guest access](/[platform]/build-a-backend/auth/concepts/guest-access/) or [sign in a user](/[platform]/frontend/auth/sign-in) before using features in the storage category.
<!-- /Platform -->

<!-- Platform: flutter -->
### Prerequisites

Amplify Flutter requires a minimum target platform for iOS (13.0), Android (API level 24), and macOS (10.15). Refer to [Flutter's supported deployment platforms](https://docs.flutter.dev/reference/supported-platforms) when targeting Web, Windows, or Linux.

### Install Amplify library

Add the following dependency to your **app**'s `pubspec.yaml` along with others you added above in **Prerequisites**:

```yaml
dependencies:
  flutter:
    sdk: flutter

  amplify_auth_cognito: ^2.0.0
  amplify_flutter: ^2.0.0
  amplify_storage_s3: ^2.0.0
```

### Configure Amplify in project

To initialize the Amplify Auth and Storage categories, call `Amplify.addPlugin()` for each plugin or pass all the plugins in `Amplify.addPlugins()`. To complete initialization, call `Amplify.configure()`.

Your code should look like this:

```dart
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_storage_s3/amplify_storage_s3.dart';
import 'package:flutter/material.dart';

import 'amplify_outputs.dart';

Future<void> _configureAmplify() async {
  try {
    final auth = AmplifyAuthCognito();
    final storage = AmplifyStorageS3();
    await Amplify.addPlugins([auth, storage]);

    // call Amplify.configure to use the initialized categories in your app
    await Amplify.configure(amplifyConfig);
  } on Exception catch (e) {
    safePrint('An error occurred configuring Amplify: $e');
  }
}

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await _configureAmplify();
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  // ...
}
```
<!-- /Platform -->

### Upload your first file

Next, let's a photo to the `picture-submissions/` path.

<!-- Platform: react, react-native -->
```jsx
import React from 'react';
import { uploadData } from 'aws-amplify/storage';

function App() {
  const [file, setFile] = React.useState();

  const handleChange = (event) => {
    setFile(event.target.files?.[0]);
  };

  const handleClick = () => {
    if (!file) {
      return;
    }
    uploadData({
      path: `picture-submissions/${file.name}`,
      data: file,
    });
  };

  return (
    <div>
      <input type="file" onChange={handleChange} />
      <button onClick={handleClick}>Upload</button>
    </div>
  );
}
```
<!-- /Platform -->

<!-- Platform: javascript, angular, vue, nextjs -->
```javascript
import { uploadData } from "aws-amplify/storage";

const file = document.getElementById("file");
const upload = document.getElementById("upload");

upload.addEventListener("click", () => {
  const fileReader = new FileReader();
  fileReader.readAsArrayBuffer(file.files[0]);

  fileReader.onload = async (event) => {
    console.log("Complete File read successfully!", event.target.result);
    try {
      await uploadData({
        data: event.target.result,
        path: `picture-submissions/${file.files[0].name}`
      });
    } catch (e) {
      console.log("error", e);
    }
  };
});
```
<!-- /Platform -->

<!-- Platform: swift -->
```swift
import Amplify
import SwiftUI
import PhotosUI

struct ContentView: View {
    @State private var selectedPhoto: PhotosPickerItem?
    @State private var image: Image?

    var body: some View {
        NavigationStack {
            VStack {
                image?
                    .resizable()
                    .scaledToFit()
            }
            .padding()
            PhotosPicker(
                selection: $selectedPhoto
            ) {
                Text("Select a photo to upload")
            }
            .task(id: selectedPhoto) {
                if let imageData = try? await selectedPhoto?.loadTransferable(type: Data.self) {
                    if let uiImage = UIImage(data: imageData) {
                        image = Image(uiImage: uiImage)
                    }
                    let uploadTask = Amplify.Storage.uploadData(
                        path: .fromString("picture-submissions/myPhoto.png"),
                        data: imageData
                    )
                }
            }
        }
    }
}
```
<!-- /Platform -->

<!-- Platform: android -->

#### [Java]

```java
private void uploadFile() {
    File exampleFile = new File(getApplicationContext().getFilesDir(), "myPhoto.png");

    try {
        BufferedWriter writer = new BufferedWriter(new FileWriter(exampleFile));
        writer.append("Example file contents");
        writer.close();
    } catch (Exception exception) {
        Log.e("MyAmplifyApp", "Upload failed", exception);
    }

    Amplify.Storage.uploadFile(
            StoragePath.fromString("picture-submissions/myPhoto.png"),
            exampleFile,
            result -> Log.i("MyAmplifyApp", "Successfully uploaded: " + result.getPath()),
            storageFailure -> Log.e("MyAmplifyApp", "Upload failed", storageFailure)
    );
}
```

#### [Kotlin - Callbacks]

```kotlin
private fun uploadFile() {
    val exampleFile = File(applicationContext.filesDir, "myPhoto.png")
    exampleFile.writeText("Example file contents")

    Amplify.Storage.uploadFile(StoragePath.fromString("picture-submissions/myPhoto.png"), exampleFile,
        { Log.i("MyAmplifyApp", "Successfully uploaded: ${it.path}") },
        { Log.e("MyAmplifyApp", "Upload failed", it) }
    )
}
```

#### [Kotlin - Coroutines]

```kotlin
private suspend fun uploadFile() {
    val exampleFile = File(applicationContext.filesDir, "myPhoto.png")
    exampleFile.writeText("Example file contents")

    val upload = Amplify.Storage.uploadFile(StoragePath.fromString("picture-submissions/myPhoto.png"), exampleFile)
    try {
        val result = upload.result()
        Log.i("MyAmplifyApp", "Successfully uploaded: ${result.path}")
    } catch (error: StorageException) {
        Log.e("MyAmplifyApp", "Upload failed", error)
    }
}
```

#### [RxJava]

```java
private void uploadFile() {
    File exampleFile = new File(getApplicationContext().getFilesDir(), "myPhoto.png");

    try {
        BufferedWriter writer = new BufferedWriter(new FileWriter(exampleFile));
        writer.append("Example file contents");
        writer.close();
    } catch (Exception exception) {
        Log.e("MyAmplifyApp", "Upload failed", exception);
    }

    RxProgressAwareSingleOperation<StorageUploadFileResult> rxUploadOperation =
            RxAmplify.Storage.uploadFile(StoragePath.fromString("picture-submissions/myPhoto.png"), exampleFile);

    rxUploadOperation
            .observeResult()
            .subscribe(
                result -> Log.i("MyAmplifyApp", "Successfully uploaded: " + result.getPath()),
                error -> Log.e("MyAmplifyApp", "Upload failed", error)
            );
}
```

<!-- /Platform -->

<!-- Platform: flutter -->
<Callout>

**Note**: To use `AWSFilePlatform`, add [aws_common](https://pub.dev/packages/aws_common) package to your Flutter project
by running: `flutter pub add aws_common`

</Callout>

#### [All Platforms]

```dart
import 'package:amplify_flutter/amplify_flutter.dart';

Future<void> uploadFile() async {
  try {
    final result = await Amplify.Storage.uploadFile(
      localFile: AWSFile.fromPath('/path/to/local/myPhoto.png'),
      path: const StoragePath.fromString('picture-submissions/myPhoto.png'),
    ).result;
    safePrint('Uploaded file: ${result.uploadedItem.path}');
  } on StorageException catch (e) {
    safePrint(e.message);
  }
}
```

<Block name= "Mobile & Desktop">

```dart
import 'dart:io' show File;

import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:aws_common/vm.dart';

Future<void> uploadFile(File file) async {
  try {
    final result = await Amplify.Storage.uploadFile(
      localFile: AWSFilePlatform.fromFile(file),
      path: const StoragePath.fromString('picture-submissions/myPhoto.png'),
    ).result;
    safePrint('Uploaded file: ${result.uploadedItem.path}');
  } on StorageException catch (e) {
    safePrint(e.message);
  }
}
```

#### [Web]

```dart
import 'dart:html' show File;

import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:aws_common/web.dart';

Future<void> uploadFile(File file) async {
  final awsFile = AWSFilePlatform.fromFile(file);
  try {
    final result = await Amplify.Storage.uploadFile(
      localFile: awsFile,
      path: const StoragePath.fromString('picture-submissions/myPhoto.png'),
    ).result;
    safePrint('Uploaded file: ${result.uploadedItem.path}');
  } on StorageException catch (e) {
    safePrint(e.message);
  }
}
```

<!-- /Platform -->

## Manage files in Amplify console

After successfully publishing your storage backend and connecting your project with client APIs, you can manage files and folders in [the Amplify console](https://console.aws.amazon.com/amplify). You can perform on-demand actions like upload, download, copy, and more under the Storage tab in the console. Refer to [Manage files in Amplify Console](/[platform]/build-a-backend/storage/manage-with-amplify-console/) guide for additional information.

## Conclusion

Congratulations! You finished the Set up Amplify Storage guide. In this guide, you set up and connected to backend resources, customized your file paths and access definitions, and connected your application to the backend to implement features like file uploads and downloads.

### Next steps

Now that you have completed setting up storage in your Amplify app, you can proceed to add file management features to your app. You can use the following guides to implement upload and download functionality, or you can access more capabilities from the side navigation.

- [Upload Files](/[platform]/frontend/storage/upload-files/)
- [Download Files](/[platform]/frontend/storage/download-files/)
