Page updated Nov 14, 2023

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 in v5 interacted with the Amplify JavaScript library.

import { CognitoUser } from '@aws-amplify/auth'; import { Auth } from 'aws-amplify'; const handleSignIn = async ({ username, password }: { username: string; password: string; }) => { const user: CognitoUser = Auth.signIn(username, password); };
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.

import { signIn } from 'aws-amplify/auth'; const handleSignIn = async ({ username, password }: { username: string; password: string; }) => { const { isSignUpComplete, userId, nextStep } = signIn({ username, password }); };
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};

Steps to Upgrade

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:

2. Update your Amplify project dependencies

Make sure to delete your package-lock.json and node_modules folder before running npm install

Upgrade to the latest Amplify library using the following command.

npm install aws-amplify
1npm install aws-amplify

The aws-amplify package in v6 includes the categories below:

  • Auth
  • API
  • Storage
  • Analytics
  • DataStore
  • In-App Messaging

If you would like to use Geo, Predictions, PubSub, or Interactions you will need to install those packages separately. (see category-specific migration instructions)

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.

amplify upgrade amplify push
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

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

V6

import amplifyconfig from './amplifyconfiguration.json'; Amplify.configure(amplifyconfig);
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.

Running Amplify on the server with NextJS

To enable the use of the Amplify JavaScript library on the server, you need to set the ssr configuration to true in the Amplify.configure function.

Amplify.configure(amplifyConfig, { ssr: true });
1Amplify.configure(amplifyConfig, {
2 ssr: true
3});

4. Upgrade category usage

DataStore is no longer supported in an SSR context: if you are using DataStore within your SSR project, you will need to migrate to the API category.

Auth

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:

import { Auth } from 'aws-amplify'; async function signIn() { try { const user = await Auth.signIn(username, password); } catch (error) { console.log('error signing in', error); } } async function signOut() { try { await Auth.signOut(); } catch (error) { console.log('error signing out: ', error); } }
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}

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

Find all API changes in the Auth migration guide

Analytics

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

import { Analytics } from 'aws-amplify'; Analytics.record({ name: 'albumVisit', attributes: {}, metrics: { minutesListened: 30 } }); Analytics.autoTrack('session', { // REQUIRED, turn on/off the auto tracking enable: true, // OPTIONAL, the attributes of the event, you can either pass an object or a function // which allows you to define dynamic attributes attributes: { attr: 'attr' }, // OPTIONAL, the service provider, by default is the Amazon Pinpoint provider: 'AWSPinpoint' });
1import { Analytics } from 'aws-amplify';
2
3Analytics.record({
4 name: 'albumVisit',
5 attributes: {},
6 metrics: { minutesListened: 30 }
7});
8
9Analytics.autoTrack('session', {
10 // REQUIRED, turn on/off the auto tracking
11 enable: true,
12 // OPTIONAL, the attributes of the event, you can either pass an object or a function
13 // which allows you to define dynamic attributes
14 attributes: {
15 attr: 'attr'
16 },
17 // OPTIONAL, the service provider, by default is the Amazon Pinpoint
18 provider: 'AWSPinpoint'
19});

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

Find all API changes in the Analytics migration guide

API (GraphQL)

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:

import { API, graphqlOperation } from 'aws-amplify'; import { createTodo, updateTodo, deleteTodo } from './graphql/mutations'; const todo = { name: 'My first todo', description: 'Hello world!' }; /* create a todo */ await API.graphql(graphqlOperation(createTodo, { input: todo })); /* update a todo */ await API.graphql( graphqlOperation(updateTodo, { input: { id: todoId, name: 'Updated todo info' } }) ); /* delete a todo */ await API.graphql(graphqlOperation(deleteTodo, { input: { id: todoId } }));
1import { API, graphqlOperation } from 'aws-amplify';
2import { createTodo, updateTodo, deleteTodo } from './graphql/mutations';
3
4const todo = { name: 'My first todo', description: 'Hello world!' };
5
6/* create a todo */
7await API.graphql(graphqlOperation(createTodo, { input: todo }));
8
9/* update a todo */
10await API.graphql(
11 graphqlOperation(updateTodo, {
12 input: { id: todoId, name: 'Updated todo info' }
13 })
14);
15
16/* delete a todo */
17await API.graphql(graphqlOperation(deleteTodo, { input: { id: todoId } }));

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:

import { Amplify, API } from 'aws-amplify'; /* fetch data */ function getData() { const apiName = 'MyApiName'; const path = '/path'; const myInit = { headers: {} // OPTIONAL }; return API.get(apiName, path, myInit); } (async function () { const response = await getData(); })(); /* update data */ async function postData() { const apiName = 'MyApiName'; const path = '/path'; const myInit = { body: {}, // replace this with attributes you need headers: {} // OPTIONAL }; return await API.post(apiName, path, myInit); } postData(); /* delete data */ async function deleteData() { const apiName = 'MyApiName'; const path = '/path'; const myInit = { headers: {} // OPTIONAL }; return await API.del(apiName, path, myInit); } deleteData();
1import { Amplify, API } from 'aws-amplify';
2
3/* fetch data */
4function getData() {
5 const apiName = 'MyApiName';
6 const path = '/path';
7 const myInit = {
8 headers: {} // OPTIONAL
9 };
10
11 return API.get(apiName, path, myInit);
12}
13
14(async function () {
15 const response = await getData();
16})();
17
18/* update data */
19async function postData() {
20 const apiName = 'MyApiName';
21 const path = '/path';
22 const myInit = {
23 body: {}, // replace this with attributes you need
24 headers: {} // OPTIONAL
25 };
26
27 return await API.post(apiName, path, myInit);
28}
29
30postData();
31
32/* delete data */
33async function deleteData() {
34 const apiName = 'MyApiName';
35 const path = '/path';
36 const myInit = {
37 headers: {} // OPTIONAL
38 };
39 return await API.del(apiName, path, myInit);
40}
41
42deleteData();

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

In App Messaging

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:

import { Notifications } from 'aws-amplify'; const { InAppMessaging } = Notifications; InAppMessaging.syncMessages(); const sendEvent = (eventName: string) => { InAppMessaging.dispatchEvent({ name: eventName }); }
1import { Notifications } from 'aws-amplify';
2
3const { InAppMessaging } = Notifications;
4InAppMessaging.syncMessages();
5
6const sendEvent = (eventName: string) => {
7 InAppMessaging.dispatchEvent({ name: eventName });
8}

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

Find all API changes in the In App Messaging migration guide

Interactions

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

npm install @aws-amplify/interactions
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. Use the switcher below to see the differences between v5 and v6:

import { Amplify } from 'aws-amplify'; import { AWSLexV2Provider } from '@aws-amplify/interactions'; import awsconfig from './aws-exports'; Amplify.configure(awsconfig); Amplify.addPluggable(new AWSLexV2Provider()); const interactionsConfig = { Interactions: { bots: { my_v2_bot: { name: "<V2BotName>", aliasId: "<V2BotAliasId>", botId: "<V2BotBotId>", localeId: "<V2BotLocaleId>", region: "<V2BotRegion>", providerName: "AWSLexV2Provider", }, } } } Amplify.configure(interactionsConfig);
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);

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:

import { Amplify, PubSub } from 'aws-amplify'; import { AWSIoTProvider } from '@aws-amplify/pubsub'; // Apply plugin with configuration Amplify.addPluggable( new AWSIoTProvider({ aws_pubsub_region: '<YOUR-IOT-REGION>', aws_pubsub_endpoint: 'wss://xxxxxxxxxxxxx.iot.<YOUR-IOT-REGION>.amazonaws.com/mqtt' }) ); // Step 1 - Create IAM policies for AWS IoT (see v5 docs) // Step 2 - Attach your policy to your Amazon Cognito Identity ID Auth.currentCredentials().then((info) => { const cognitoIdentityId = info.identityId; }); aws iot attach-policy --policy-name 'myIoTPolicy' --target '<YOUR_COGNITO_IDENTITY_ID>' // Step 3 - Allow Amazon Cognito Authenticated Role to access IoT Services
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

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

Storage

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:

import { Storage } from 'aws-amplify'; // Upload a file with access level `public` const result = await Storage.put("test.txt", "Hello", { level: 'public', }); // Generate a file download url with check if the file exists in the S3 bucket const url = await Storage.get('filename.txt', { validateObjectExistence: true });
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});

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 the functional API’s directly from the aws-amplify/utils path as shown below. Use the switcher below to see the differences between v5 and v6:

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

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

Server-side Rendering

The Amplify JS v5 withSSRContext utility is no longer available with Amplify JS v6. You will need to use the runWithAmplifyServerContext function exported from @aws-amplify/adapter-nextjs to make Amplify API calls on the server side of your Next.js app. Use the switcher below to see the differences between v5 and v6:

import { Amplify, withSSRContext } from 'aws-amplify'; import { listTodos } from './graphql/queries'; import awsExports from './aws-exports'; Amplify.configure({ ...awsExports, ssr: true }); const getServerSideProps = async ({ req }) => { const SSR = withSSRContext({ req }); const { data } = await SSR.API.graphql({ query: listTodos }); return { props: { todos: data.listTodos.items } }; };
1import { Amplify, withSSRContext } from 'aws-amplify';
2import { listTodos } from './graphql/queries';
3import awsExports from './aws-exports';
4
5Amplify.configure({ ...awsExports, ssr: true });
6
7const getServerSideProps = async ({ req }) => {
8 const SSR = withSSRContext({ req });
9 const { data } = await SSR.API.graphql({ query: listTodos });
10
11 return {
12 props: {
13 todos: data.listTodos.items
14 }
15 };
16};

Please review the Server-Side Rendering with Amplify JavaScript v6, as we've changed the developer experience to allow working with cookies and middleware in NextJS.