Page updated Jan 16, 2024

Migrate from Amplify JavaScript v5 to v6

This migration guide will help you upgrade your Amplify JavaScript project from v5 to v6. In order to provide you with a cleaner experience, better typings, improved support for NextJS, and improved tree-shaking leading to a much smaller bundle-size, we made the following changes for v6:

  1. We have transitioned to an approach where you only import the features you need from each of our categories.
  2. Most API’s now use named params instead of positional params, allowing for cleaner and more consistent typing.
  3. We have enabled typescript strict mode on all categories and have added typing to help make it easier to connect your backend resources if you have chosen not to use the Amplify CLI.

Below is an example of how you would have previously interacted with the Amplify JavaScript library in v5.

1import { CognitoUser } from '@aws-amplify/auth';
2import { Auth } from 'aws-amplify';
3
4const handleSignIn = async ({
5 username,
6 password
7}: {
8 username: string;
9 password: string;
10}) => {
11 const user: CognitoUser = Auth.signIn(username, password);
12};

The following is an example of how you would accomplish the same functionality with v6, using our new imports and API surface.

1import { signIn } from 'aws-amplify/auth';
2
3const handleSignIn = async ({
4 username,
5 password
6}: {
7 username: string;
8 password: string;
9}) => {
10 const { isSignUpComplete, userId, nextStep } = signIn({ username, password });
11};

Changes to React Native

As part of the updates to Amplify JavaScript v6, we also re-evaluated our strategy for how we can best support React Native going forward. This has been an ongoing effort ever since we introduced our updated Push Notification experience in v5 and is something we will continue to evolve along with the ever-changing React Native ecosystem.

@aws-amplify/react-native

We have introduced a new package - @aws-amplify/react-native - to encompass the core requirements for using Amplify JavaScript v6 in a React Native environment. This package is a new requirement which allows us to:

  • Remove the dependency on the amazon-cognito-identity-js package by moving core native Amplify functionality previously vended by this package into @aws-amplify/react-native.
  • Automatically install JavaScript-only (i.e. non-native module dependencies) polyfills required by Amplify as transitive dependencies, no longer requiring extra steps from you.
  • Automatically import all required polyfills, no longer requiring you to take extra steps to include import statements at the top of your application entry point.

Native modules required by Amplify such as @react-native-async-storage/async-storage or react-native-get-random-values still need to be installed separately as they need to be linked with React Native

Instructions for React Native version 0.72 and below

@aws-amplify/react-native requires a minimum iOS deployment target of 13.0 if you are using react-native version less than or equal to 0.72. Open the Podfile located in the ios directory and update the target value:

1- platform :ios, min_ios_version_supported
2 + platform :ios, 13.0

Dropping support for Expo Go

With the goal of providing more idiomatic native functionality to your React Native application, Expo Go will no longer be supported in v6.

Per the Expo docs:

The Expo Go app is a great tool to get started. It exists to help developers quickly get projects off the ground, experiment with ideas (such as on Snack), and share their work with minimal friction. Expo Go makes this possible by including a feature-rich native runtime made up of every module in the Expo SDK, so all you need to do to use a module is install the package and reload your app.

The tradeoff is that Expo Go does not allow you to add custom native code. You can only use native modules built into the Expo SDK. Many great libraries are available outside of the Expo SDK, and you may even want to build your native library. You can leverage these libraries with development builds or using prebuild to generate native projects, or both. You can also continue using EAS Build to release your app as no changes are required.

A key part of Amplify's React Native strategy going forward is to reduce our reliance on third-party native modules. While third-party native modules are a mainstay of the React Native ecosystem, we believe the flexibility of building more native modules tailored to the specific needs of our customers will allow us to most quickly deliver value to them in the long run. As a result of now requiring native modules not available through the Expo SDK, Expo Go is not supported in v6 but you should still be able to use Expo.

Step 1: Upgrade your dev environment

In order to use Amplify JavaScript v6, you will need to make sure you are using the following versions in your development environment:

Step 2: Upgrade your Amplify project dependencies

Make sure to delete your package-lock.json and node_modules folder before running npm install
The aws-amplify-react-native package is not compatible with v6.

To upgrade React Native projects that do not utilize aws-amplify-react-native, remove amazon-cognito-identity-js from the project package.json and install @aws-amplify/react-native.

Then upgrade/install the necessary dependencies using the following command:

1npm install aws-amplify@6 @aws-amplify/react-native @react-native-community/netinfo @react-native-async-storage/async-storage react-native-get-random-values

Note that v6 supports react-native v0.70+, so if you prefer manually upgrading dependencies double-check the version of react-native in your package.json file.

If you are using signInWithRedirect (previously Auth.federatedSignIn) you will need to install the @aws-amplify/rtn-web-browser native module.

If you are using Push Notifications, you will need to upgrade the @aws-amplify/rtn-push-notification native module to v1.2+ (if you were using push notifications in v5, this dependency should already be added). Find all Push Notifications API changes in its migration guide

Step 3: Upgrade Amplify CLI version and configuration file

If you created your project with Amplify CLI version < 12.5.1, upgrade your CLI version and regenerate your configuration file using the scripts below.

1amplify upgrade
2amplify push

This will generate a new configuration file called amplifyconfiguration.json

Wherever you called Amplify.configure({ aws-exports }); previously (usually in the root of your project) update your code as shown below

V5

1import awsconfig from './aws-exports';
2
3Amplify.configure(awsconfig);

V6

1import amplifyconfig from './amplifyconfiguration.json';
2
3Amplify.configure(amplifyconfig);

Amplify.configure() will now accept either the config JSON file or a strongly typed configuration object. Therefore, if you need to add additional configuration, you will call configure twice: once with the contents of amplifyconfiguration.json, and then again using Amplify.getConfig() plus any additions. Keep in mind that any call to configuration will fully override previous configurations, so pay special attention to nested configurations.

If you have previously configured Amplify by passing the configuration object literal when calling the Amplify.configure() function, you can now configure Amplify manually with type safety. Please refer to the documentation of each category that you are using for migration.

Remove polyfill imports

For React Native applications, polyfill imports should no longer need to be added to your application's entry point file as they are imported by the @aws-amplify/react-native package.

1// Example index.js
2- import 'react-native-get-random-values';
3- import 'react-native-url-polyfill/auto';

Step 4: Update category usage

Auth

Find a comprehensive summary of changes to the Auth category in the Auth migration guide

As of v6 of Amplify, you will now import the functional API’s directly from the aws-amplify/auth path as shown below. Use the switcher below to see the differences between v5 and v6:

1import { Auth } from 'aws-amplify';
2
3async function signIn() {
4 try {
5 const user = await Auth.signIn(username, password);
6 } catch (error) {
7 console.log('error signing in', error);
8 }
9}
10
11async function signOut() {
12 try {
13 await Auth.signOut();
14 } catch (error) {
15 console.log('error signing out: ', error);
16 }
17}
1import { signIn, signOut } from 'aws-amplify/auth';
2
3async function signIn({ username, password }) {
4 try {
5 const { isSignedIn, nextStep } = await signIn({ username, password });
6 } catch (error) {
7 console.log('error signing in', error);
8 }
9}
10
11async function handleSignOut() {
12 try {
13 await signOut();
14 } catch (error) {
15 console.log('error signing out: ', error);
16 }
17}

For a deeper look at v6 Auth functionality, check out our Authentication category documentation.

Analytics

Find a comprehensive summary of changes to the Analytics category in the Analytics migration guide

As of v6 of Amplify, you will now import the functional API’s directly from the aws-amplify/analytics path as shown below. Note that in v6, the provider is determined by import path. The functions exported from aws-amplify/analytics use AWS Pinpoint. Use the switcher below to see the differences between v5 and v6:

1import { Analytics } from 'aws-amplify';
2
3Analytics.record({
4 name: 'albumVisit',
5 attributes: { genre: '', artist: '' },
6 metrics: { minutesListened: 30 }
7});
8
9Analytics.autoTrack('session', {
10 enable: true,
11 attributes: {
12 customizableField: 'attr'
13 },
14 provider: 'AWSPinpoint'
15});
1import { record, configureAutoTrack } from 'aws-amplify/analytics';
2
3record({
4 name: 'albumVisit',
5 attributes: { genre: '', artist: '' },
6 metrics: { minutesListened: 30 }
7});
8
9configureAutoTrack({
10 enable: true,
11 type: 'session',
12 options: {
13 attributes: {
14 customizableField: 'attr'
15 }
16 }
17});

For a deeper look at V6 Analytics functionality, check out our Analytics category documentation.

API (GraphQL)

As of v6 of Amplify, you will now import a function called generateClient from the aws-amplify/api path and use the client returned from that method to perform graphql operations as shown below. Use the switcher below to see the differences between v5 and v6:

1import { API, graphqlOperation } from 'aws-amplify';
2import { createTodo, updateTodo, deleteTodo } from './graphql/mutations';
3
4const todo = {
5 name: 'My first todo',
6 description: 'Hello world!'
7};
8
9/* create a todo */
10const newTodo = await API.graphql(
11 graphqlOperation(createTodo, {
12 input: todo
13 })
14);
15
16/* update a todo */
17const updatedTodo = await API.graphql(
18 graphqlOperation(updateTodo, {
19 input: {
20 id: newTodo.id,
21 name: 'Updated todo info'
22 }
23 })
24);
25
26/* delete a todo */
27await API.graphql(
28 graphqlOperation(deleteTodo, {
29 input: { id: newTodo.id }
30 })
31);
1import { generateClient } from 'aws-amplify/api';
2import { createTodo, updateTodo, deleteTodo } from './graphql/mutations';
3
4const client = generateClient();
5
6const todo = {
7 name: 'My first todo',
8 description: 'Hello world!'
9};
10
11/* create a todo */
12const newTodo = await client.graphql({
13 query: createTodo,
14 variables: { input: todo }
15});
16
17/* update a todo */
18const updatedTodo = await client.graphql({
19 query: updateTodo,
20 variables: { input: {
21 id: newTodo.id,
22 name: 'Updated todo info'
23 }}
24});
25
26/* delete a todo */
27const deletedTodo = await client.graphql({
28 query: deleteTodo,
29 variables: {
30 input: { id: newTodo.id }
31 }
32});

For a deeper look at how the GraphQL API functionality in V6, check out our API (GraphQL) category documentation.

API (Rest)

As of v6 of Amplify, you will now import the functional API’s directly from the aws-amplify/api path as shown below. Use the switcher below to see the differences between v5 and v6:

1import { Amplify, API } from 'aws-amplify';
2
3/* fetch data */
4async function getData() {
5 const apiName = 'MyApiName';
6 const path = '/path';
7 const options = {
8 headers: {} // OPTIONAL
9 };
10
11 return await API.get(apiName, path, options);
12}
13
14/* update data */
15async function postData() {
16 const apiName = 'MyApiName';
17 const path = '/path';
18 const options = {
19 body: {
20 name: 'My first todo',
21 message: 'Hello world!'
22 },
23 headers: {} // OPTIONAL
24 };
25
26 return await API.post(apiName, path, options);
27}
28
29postData();
30
31/* delete data */
32async function deleteData() {
33 const apiName = 'MyApiName';
34 const path = '/path';
35 const options = {
36 headers: {} // OPTIONAL
37 };
38 return await API.del(apiName, path, options);
39}
40
41deleteData();
1import { get, put, del } from 'aws-amplify/api';
2
3/* fetch data */
4async function getTodo() {
5 const apiName = 'MyApiName';
6 const path = '/path';
7 const options = {
8 body: {
9 name: 'My first todo',
10 message: 'Hello world!'
11 },
12 headers: {} // OPTIONAL
13 };
14
15 const restOperation = get({
16 apiName,
17 path,
18 options
19 });
20 return await restOperation.response;
21}
22
23/* update data */
24async function updateTodo() {
25 const apiName = 'MyApiName';
26 const path = '/path';
27 const options = {
28 body: {
29 name: 'My first todo',
30 message: 'Hello world!'
31 },
32 headers: {} // OPTIONAL
33 };
34
35 const restOperation = put({
36 apiName,
37 path,
38 options
39 });
40 return await restOperation.response;
41}
42
43/* delete data */
44async function deleteTodo() {
45 const apiName = 'MyApiName';
46 const path = '/path';
47 const options = {
48 headers: {} // OPTIONAL
49 };
50
51 const restOperation = del({
52 apiName,
53 path,
54 options
55 });
56 return await restOperation.response;
57}

For a deeper look at how the REST API functionality in V6, check out our API (REST) category documentation.

In-App Messaging

Find a comprehensive summary of changes to In-App Messaging in the In-App Messaging migration guide

As of v6 of Amplify, you will now import the functional API’s directly from the aws-amplify/in-app-messaging path as shown below. Use the switcher below to see the differences between v5 and v6:

1import { Notifications } from 'aws-amplify';
2
3const { InAppMessaging } = Notifications;
4InAppMessaging.syncMessages();
5
6const sendEvent = (eventName: string) => {
7 InAppMessaging.dispatchEvent({ name: eventName });
8}
1import {
2 dispatchEvent,
3 initializeInAppMessaging,
4 syncMessages
5} from 'aws-amplify/in-app-messaging';
6
7initializeInAppMessaging();
8syncMessages();
9
10const sendEvent = (eventName: string) => {
11 dispatchEvent({ name: eventName });
12}

For a deeper look at In App Messaging functionality in v6, check out our In App Messaging category documentation.

Interactions

To use Interactions in v6, you will first need to install the category as a separate dependency using the below command:

1npm install @aws-amplify/interactions

Make sure that the @aws-amplify/interactions package has the same version number as the aws-amplify package in your package.json file.

In v6, the AWSLexV2Provider provider will be included by default and you are no longer required to call Amplify.addPluggable. It is also recommended to integrate your App with AWS LexV2, as the default module exports are associated with AWS LexV2 APIs. Interactions operates in the same way as before, however, the configuration structure has changed somewhat. Use the switcher below to see the differences between v5 and v6:

1import { Amplify } from 'aws-amplify';
2import { AWSLexV2Provider } from '@aws-amplify/interactions';
3import awsconfig from './aws-exports';
4
5Amplify.configure(awsconfig);
6
7Amplify.addPluggable(new AWSLexV2Provider());
8const interactionsConfig = {
9 Interactions: {
10 bots: {
11 my_v2_bot: {
12 name: '<V2BotName>',
13 aliasId: '<V2BotAliasId>',
14 botId: '<V2BotBotId>',
15 localeId: '<V2BotLocaleId>',
16 region: '<V2BotRegion>',
17 providerName: 'AWSLexV2Provider',
18 },
19 }
20 }
21}
22
23Amplify.configure(interactionsConfig);
1import { Amplify } from 'aws-amplify';
2import amplifyconfig from './amplifyconfiguration.json';
3
4Amplify.configure(amplifyconfig);
5
6const interactionsConfig = {
7 LexV2: {
8 '<V2BotName>': {
9 aliasId: '<V2BotAliasId>',
10 botId: '<V2BotBotId>',
11 localeId: '<V2BotLocaleId>',
12 region: '<V2BotRegion>'
13 }
14 }
15}
16
17Amplify.configure({
18 ...Amplify.getConfig(),
19 Interactions: interactionsConfig
20});

For a deeper look at Interactions functionality in v6, check out our Interactions category documentation.

PubSub

As of v6 of Amplify, you will now import the functional API’s directly from the aws-amplify/pubsub path as shown below. Use the switcher below to see the differences between v5 and v6:

1import { Amplify, PubSub } from 'aws-amplify';
2import { AWSIoTProvider } from '@aws-amplify/pubsub';
3
4// Apply plugin with configuration
5Amplify.addPluggable(
6 new AWSIoTProvider({
7 aws_pubsub_region: '<YOUR-IOT-REGION>',
8 aws_pubsub_endpoint:
9 'wss://xxxxxxxxxxxxx.iot.<YOUR-IOT-REGION>.amazonaws.com/mqtt'
10 })
11);
12
13// Step 1 - Create IAM policies for AWS IoT (see v5 docs)
14
15// Step 2 - Attach your policy to your Amazon Cognito Identity ID
16
17Auth.currentCredentials().then((info) => {
18 const cognitoIdentityId = info.identityId;
19});
20
21aws iot attach-policy --policy-name 'myIoTPolicy' --target '<YOUR_COGNITO_IDENTITY_ID>'
22
23// Step 3 - Allow Amazon Cognito Authenticated Role to access IoT Services
1import { Amplify } from 'aws-amplify';
2import { PubSub } from '@aws-amplify/pubsub';
3
4// Apply plugin with configuration
5const pubsub = new PubSub({
6 region: '<YOUR-IOT-REGION>',
7 endpoint:
8 'wss://xxxxxxxxxxxxx.iot.<YOUR-IOT-REGION>.amazonaws.com/mqtt'
9});
10
11// Step 1 - Create IAM policies for AWS IoT (see v5 docs)
12
13// Step 2 - Attach your policy to your Amazon Cognito Identity ID
14
15import { fetchAuthSession } from 'aws-amplify/auth';
16fetchAuthSession().then((info) => {
17 const cognitoIdentityId = info.identityId;
18});
19
20aws iot attach-policy --policy-name 'myIoTPolicy' --target '<YOUR_COGNITO_IDENTITY_ID>'
21
22// Step 3 - Allow Amazon Cognito Authenticated Role to access IoT Services

For a deeper look at PubSub functionality in V6, check out our PubSub category documentation.

Storage

Find a comprehensive summary of changes to Storage in the Storage migration guide

As of v6 of Amplify, you will now import the functional API’s directly from the aws-amplify/storage path as shown below. Use the switcher below to see the differences between v5 and v6:

1import { Storage } from 'aws-amplify';
2
3// Upload a file with access level `public`
4const result = await Storage.put('test.txt', 'Hello', {
5 level: 'public',
6});
7
8// Generate a file download url with check if the file exists in the S3 bucket
9const url = await Storage.get('filename.txt', {
10 validateObjectExistence: true
11});
1import { getUrl, uploadData } from 'aws-amplify/storage';
2
3// Upload a file with access level `guest` as the equivalent of `public` in v5
4const result = await uploadData({
5 key: 'test.txt',
6 data: 'Hello',
7 options: {
8 accessLevel: 'guest'
9 }
10}).result;
11
12// Generate a file download url with check if the file exists in the S3 bucket
13const url = await getUrl({
14 key: 'filename.txt',
15 options: {
16 validateObjectExistence: true
17 },
18});

For a deeper look at how the Storage functionality in V6, check out our Storage category documentation.

Utilities

As of v6 of Amplify, you will now import utility classes and instances from the aws-amplify/utils path as shown below. Use the switcher below to see the differences between v5 and v6:

In V6 we’ve audited our hub events and removed some events and categories to reduce redundancies and the overall chattiness of the hub. The Storage, In-App Messaging, and Push Notifications categories no longer emit Hub events. You can track the status of calls to those categories via API responses.

Expand the sections below to see the events that have been changed or removed. There have been no changes to API, DataStore, and PubSub events.

Auth Hub Events
V5V6
EventDataEventData
configurednullUse the new 'configure' event from the 'core' channelResourcesConfig
signInCognitoUsersignedInAuthUser
signIn_failureerror
signUpISignUpResult
signUp_failureerror
confirmSignUp'SUCCESS'
completeNewPassword_failureerror
autoSignInCognitoUser
autoSignIn_failureerror
forgotPasswordCognitoUser
forgotPassword_failureerror
forgotPasswordSubmitCognitoUser
forgotPasswordSubmit_failureerror
verifyCognitoUser
tokenRefreshtokenRefresh
tokenRefresh_failureerrortokenRefresh_failureerror
cognitoHostedUICognitoUsersignInWithRedirect
cognitoHostedUI_failureerrorsignInWithRedirect_failureerror
customOAuthStatestatecustomOAuthStatestate
customState_failureerror
parsingCallbackUrlurl
userDeletedresult
updateUserAttributesattributes
updateUserAttributes_failureerror
signOutCognitoUsersignedOut

Analytics Hub Events
V5V6
EventDataEventData
configurednullUse the new 'configure' event from the 'core' channelResourcesConfig
pinpointProvider_configurednullUse the new 'configure' event from the 'core' channelResourcesConfig
recordevent datarecordevent data

Core Hub Events
V5V6
EventDataEventData
credentials_configurednullconfigureResourcesConfig
1import {
2 ServiceWorker,
3 Cache,
4 Hub,
5 I18n,
6 Logger
7} from 'aws-amplify';
8
9// Service Worker
10const serviceWorker = new ServiceWorker();
11
12// Cache
13Cache.setItem(key, value, [options]);
14
15// Hub (Listening for messages)
16class MyClass {
17 constructor() {
18 Hub.listen('auth', (data) => {
19 const { payload } = data;
20 this.onAuthEvent(payload);
21 console.log('A new auth event has happened: ', data.payload.data.username + ' has ' + data.payload.event);
22 })
23 }
24
25 onAuthEvent(payload) {
26 // ... your implementation
27 }
28}
29
30// Internationalization
31I18n.setLanguage('fr');
32
33// Logger
34const logger = new Logger('foo');
35
36logger.info('info bar');
37logger.debug('debug bar');
38logger.warn('warn bar');
39logger.error('error bar');
1import {
2 ServiceWorker,
3 Cache,
4 Hub,
5 I18n,
6 ConsoleLogger
7} from 'aws-amplify/utils';
8
9// Service Worker
10const serviceWorker = new ServiceWorker();
11
12// Cache
13Cache.setItem(key, value, [options]);
14
15// Hub (Listening for messages)
16class MyClass {
17 constructor() {
18 Hub.listen('auth', (data) => {
19 const { payload } = data;
20 this.onAuthEvent(payload);
21 console.log('A new auth event has happened: ', data.payload.data.username + ' has ' + data.payload.event);
22 })
23 }
24
25 onAuthEvent(payload) {
26 // ... your implementation
27 }
28}
29
30// Internationalization
31I18n.setLanguage('fr');
32
33// Console Logger
34const logger = new ConsoleLogger('foo');
35
36logger.info('info bar');
37logger.debug('debug bar');
38logger.warn('warn bar');
39logger.error('error bar');

For a deeper look at v6 Utilities, check out our Utilities documentation.