Page updated Mar 26, 2024

Connect to existing AWS resources with Amplify CLI

The AWS Amplify CLI (Command Line Interface) CLI provides a simple workflow for provisioning cloud resources like authentication, databases, and storage for apps through the command line.

In this guide, you will learn how to connect a new React web app to backend resources you've already created using the Amplify CLI.

Connecting a mobile app? We also offer a version of this guide for integrating existing backends with Flutter using the Amplify CLI. Check out the Flutter guide.

Connect web app to existing AWS resources

This guide will walk you through connecting a new React web app to the AWS resources created with Amplify for an existing React app. If you don't already have an existing app, you can follow this React tutorial to create a to-do app that uses Amplify Auth, API, and Hosting resources.

Before you begin, you will need:

  • An existing React app
  • An AWS account: If you don't already have an account, follow the Setting Up Your AWS Environment tutorial for a quick overview.
  • The Amplify CLI installed and configured.
  • A text editor. For this guide, we will use VS Code, but you can use your preferred IDE.

Find the AWS backend details

Before connecting the backend resources to our new app, we first need to locate the details of the AWS environment provisioned for the existing app.

Step 1: In your existing app, open the file <Your-App>/amplify/team-provider-info.json .

The team-provider-info.json file within the file directory of the Amplify app.

Step 2: In the team-provider-info.json file, note the following:

  1. The environment you want to use
  2. The AmplifyAppId for the required environment
The environment and AmplifyAppId in team-provider-info.json file.

Create the React app

Now that we have gathered the necessary backend details, we can start building out the new React app.

Step 1: Create a React app by running the following command in your terminal.

npx create-react-app react-amplify-connect

Step 2: Open the newly created React app using VS Code by running the following commands in your terminal.

1cd react-amplify-connect
2code . -r

Open the created app using VS Code.

Step 3: Navigate to the app's root folder and import the Amplify backend for the app by running the following command in your terminal.

amplify pull --appId <The_App_ID> --envName <The_App_Env>

Step 4: Select the AWS Authentication method. In this example, we are using an AWS profile. Ensure that the selected profile has the necessary permissions to access and modify AWS resources. See Configure the Amplify CLI for more information on setting up your AWS profile.

Accept the default values for the prompts and make sure to answer Yes to the “modifying this backend” question. Amplify CLI will initialize the backend and connect the project to the cloud.

1? Select the authentication method you want to use: AWS profile
2
3For more information on AWS Profiles, see:
4https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html
5
6? Please choose the profile you want to use AwsWest1
7Amplify AppID found: dfn3u8j1nvzjc. Amplify App name is: reactamplified
8Backend environment dev found in Amplify Console app: reactamplified
9? Choose your default editor: Visual Studio Code
10Choose the type of app that you're building · javascript
11Please tell us about your project
12? What javascript framework are you using react
13? Source Directory Path: src
14? Distribution Directory Path: build
15? Build Command: npm run-script build
16? Start Command: npm run-script start
17? Do you plan on modifying this backend? Yes
18Fetching updates to backend environment: dev from the cloud.
19⚠️ WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules
20
21Fetching updates to backend environment: dev from the cloud. GraphQL schema compiled successfully.
22
23Edit your schema at /Users/malakamm/development/react-amplify-connect/amplify/backend/api/reactamplified/schema.graphql or place .graphql files in a directory at /Users/malakamm/development/react-amplify-connect/amplify/backend/api/reactamplified/schema
24Successfully pulled backend environment dev from the cloud.
25Browserslist: caniuse-lite is outdated. Please run:
26 npx update-browserslist-db@latest
27 Why you should do it regularly: https://github.com/browserslist/update-db#readme
28
29
30Successfully pulled backend environment dev from the cloud.
31Run 'amplify pull' to sync future upstream changes.

The Amplify CLI will add a new folder named amplify to the app's root folder, which contains the Amplify project and backend details.

The amplify folder within the file directory of the Amplify app.

Step 5: Use the following command to generate the GraphQL statements.

amplify codegen add

Step 6: Accept the default values of the prompts.

1? Choose the code generation language target javascript
2? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/**/*.js
3? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes
4? Enter maximum statement depth [increase from default if your schema is deeply nested] 2
5Generated GraphQL operations successfully and saved at src/graphql

The CLI will add a new folder named graphql to the app's root folder, which contains the GraphQL statements.

The graphql folder within the file directory of the Amplify app.

Step 7: Install the aws-amplify and @aws-amplify/ui-react packages by running the following commands.

npm install aws-amplify @aws-amplify/ui-react

Step 8: Update the App.js file with the following code to create a login flow using Amplify UI and a form with a button to create to-dos, as well as a way to fetch and render the list of to-dos.

src/App.js
1import React, { useEffect, useState } from 'react'
2import { Amplify, API, graphqlOperation } from 'aws-amplify'
3import { createTodo } from './graphql/mutations'
4import { listTodos } from './graphql/queries'
5import { withAuthenticator, Button, Heading } from '@aws-amplify/ui-react';
6import '@aws-amplify/ui-react/styles.css';
7
8import awsExports from "./aws-exports";
9Amplify.configure(awsExports);
10
11const initialState = { name: '', description: '' }
12
13const App = ({ signOut, user }) => {
14 const [formState, setFormState] = useState(initialState)
15 const [todos, setTodos] = useState([])
16
17 useEffect(() => {
18 fetchTodos()
19 }, [])
20
21 function setInput(key, value) {
22 setFormState({ ...formState, [key]: value })
23 }
24
25 async function fetchTodos() {
26 try {
27 const todoData = await API.graphql(graphqlOperation(listTodos))
28 const todos = todoData.data.listTodos.items
29 setTodos(todos)
30 } catch (err) { console.log('error fetching todos') }
31 }
32
33 async function addTodo() {
34 try {
35 if (!formState.name || !formState.description) return
36 const todo = { ...formState }
37 setTodos([...todos, todo])
38 setFormState(initialState)
39 await API.graphql(graphqlOperation(createTodo, {input: todo}))
40 } catch (err) {
41 console.log('error creating todo:', err)
42 }
43 }
44
45 return (
46 <div style={styles.container}>
47 <Heading level={1}>Hello {user.username}</Heading>
48 <Button onClick={signOut} style={styles.button}>Sign out</Button>
49 <h2>Amplify Todos</h2>
50 <input
51 onChange={event => setInput('name', event.target.value)}
52 style={styles.input}
53 value={formState.name}
54 placeholder="Name"
55 />
56 <input
57 onChange={event => setInput('description', event.target.value)}
58 style={styles.input}
59 value={formState.description}
60 placeholder="Description"
61 />
62 <button style={styles.button} onClick={addTodo}>Create Todo</button>
63 {
64 todos.map((todo, index) => (
65 <div key={todo.id ? todo.id : index} style={styles.todo}>
66 <p style={styles.todoName}>{todo.name}</p>
67 <p style={styles.todoDescription}>{todo.description}</p>
68 </div>
69 ))
70 }
71 </div>
72 )
73}
74
75const styles = {
76 container: { width: 400, margin: '0 auto', display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: 20 },
77 todo: { marginBottom: 15 },
78 input: { border: 'none', backgroundColor: '#ddd', marginBottom: 10, padding: 8, fontSize: 18 },
79 todoName: { fontSize: 20, fontWeight: 'bold' },
80 todoDescription: { marginBottom: 0 },
81 button: { backgroundColor: 'black', color: 'white', outline: 'none', fontSize: 18, padding: '12px 0px' }
82}
83
84export default withAuthenticator(App);

Step 9: Run the app using the following command.

npm start

Step 10: Change the UI of the app as shown in the following to update the placeholder text of the to-do form and to use the user’s email for the hello message.

src/App.js
1...
2 return (
3 <div style={styles.container}>
4 <Heading level={1}>Hello {*user*.attributes.email}</Heading>
5 <Button onClick={signOut} style={styles.button}>Sign out</Button>
6 <h2>Amplify Todos</h2>
7 <input
8 onChange={event => setInput('name', event.target.value)}
9 style={styles.input}
10 value={formState.name}
11 placeholder="ToDo Name"
12 />
13 <input
14 onChange={event => setInput('description', event.target.value)}
15 style={styles.input}
16 value={formState.description}
17 placeholder="ToDo Description"
18 />
19 <button style={styles.button} onClick={addTodo}>Create Todo</button>
20 {
21 todos.map((todo, index) => (
22 <div key={todo.id ? todo.id : index} style={styles.todo}>
23 <p style={styles.todoName}>{todo.name}</p>
24 <p style={styles.todoDescription}>{todo.description}</p>
25 </div>
26 ))
27 }
28 </div>
29 )
30....

The App.js file should now look like the following code snippet.

src/App.js
1import React, { useEffect, useState } from 'react'
2import { Amplify, API, graphqlOperation } from 'aws-amplify'
3import { createTodo } from './graphql/mutations'
4import { listTodos } from './graphql/queries'
5import { withAuthenticator, Button, Heading } from '@aws-amplify/ui-react';
6import '@aws-amplify/ui-react/styles.css';
7
8import awsExports from "./aws-exports";
9Amplify.configure(awsExports);
10
11const initialState = { name: '', description: '' }
12
13const App = ({ signOut, user }) => {
14 const [formState, setFormState] = useState(initialState)
15 const [todos, setTodos] = useState([])
16
17 useEffect(() => {
18 fetchTodos()
19 }, [])
20
21 function setInput(key, value) {
22 setFormState({ ...formState, [key]: value })
23 }
24
25 async function fetchTodos() {
26 try {
27 const todoData = await API.graphql(graphqlOperation(listTodos))
28 const todos = todoData.data.listTodos.items
29 setTodos(todos)
30 } catch (err) { console.log('error fetching todos') }
31 }
32
33 async function addTodo() {
34 try {
35 if (!formState.name || !formState.description) return
36 const todo = { ...formState }
37 setTodos([...todos, todo])
38 setFormState(initialState)
39 await API.graphql(graphqlOperation(createTodo, {input: todo}))
40 } catch (err) {
41 console.log('error creating todo:', err)
42 }
43 }
44
45 return (
46 <div style={styles.container}>
47 <Heading level={1}>Hello {user.attributes.email}</Heading>
48 <Button onClick={signOut} style={styles.button}>Sign out</Button>
49 <h2>Amplify Todos</h2>
50 <input
51 onChange={event => setInput('name', event.target.value)}
52 style={styles.input}
53 value={formState.name}
54 placeholder="ToDo Name"
55 />
56 <input
57 onChange={event => setInput('description', event.target.value)}
58 style={styles.input}
59 value={formState.description}
60 placeholder="ToDo Description"
61 />
62 <button style={styles.button} onClick={addTodo}>Create Todo</button>
63 {
64 todos.map((todo, index) => (
65 <div key={todo.id ? todo.id : index} style={styles.todo}>
66 <p style={styles.todoName}>{todo.name}</p>
67 <p style={styles.todoDescription}>{todo.description}</p>
68 </div>
69 ))
70 }
71 </div>
72 )
73}
74
75const styles = {
76 container: { width: 400, margin: '0 auto', display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: 20 },
77 todo: { marginBottom: 15 },
78 input: { border: 'none', backgroundColor: '#ddd', marginBottom: 10, padding: 8, fontSize: 18 },
79 todoName: { fontSize: 20, fontWeight: 'bold' },
80 todoDescription: { marginBottom: 0 },
81 button: { backgroundColor: 'black', color: 'white', outline: 'none', fontSize: 18, padding: '12px 0px' }
82}
83
84export default withAuthenticator(App);

Step 11: Use the following command to publish your changes. Amplify CLI will publish the changes and display the app URL.

amplify publish
Amplify CLI publish the app and display a URL.

Step 12: Use the URL to run the app in the browser.

Conclusion

Congratulations! Your new React app is now connected to AWS resources from a different app through AWS Amplify. This integration grants your app access to authentication resources for user management, a scalable GraphQL API backed by Amazon DynamoDB, and a hosting service for publishing your app to the cloud.

Clean up resources

Once you're finished experimenting with this demo app, we recommend deleting the backend resources to avoid incurring unexpected costs. You can do this by running the following command in the root folder of the app.

amplify delete

If you would like to expand this demo app into a production-ready app, you may need to add additional resources, such as authorization and storage. Refer to the Build & connect backend section for guides on how to add and connect other backend resources.