Amplify#
AWS Amplify is a set of tools and services that lets frontend and mobile developers build full-stack applications on AWS without needing to manually wire together individual services. The problem it solves is real: provisioning a Cognito user pool, an API Gateway endpoint, a Lambda function, and an S3 bucket — then connecting them to a React app — involves dozens of steps. Amplify collapses that into a single CLI command or a few lines of library code.
Amplify is not a single product but a platform with four distinct layers that work together:
- Amplify CLI — provisions and manages backend resources
- Amplify Hosting — deploys and hosts frontend applications
- Amplify Libraries — client-side SDKs that connect your app to those backends
- Amplify Studio — a visual interface for building backends and UI components (lower exam weight)
Amplify CLI: Backend Provisioning#
The CLI is the backbone of the local development workflow. After running amplify init inside a project, you add backend capabilities with amplify add <category>. The main categories map directly to AWS services:
| Category | Underlying service |
|---|---|
auth | Amazon Cognito |
api | API Gateway + Lambda, or AppSync |
storage | Amazon S3, DynamoDB |
function | AWS Lambda |
hosting | Amplify Hosting / S3 + CloudFront |
Running amplify push synthesizes CloudFormation templates and deploys all changes. This means every backend environment is reproducible and version-controlled. amplify pull syncs an existing cloud environment back to your local project — useful when joining a team that already has an Amplify backend. 🔗
Environments are a first-class concept in the CLI. You can have separate dev, staging, and prod backends with amplify env add, each with its own isolated set of AWS resources. This is important for the exam: Amplify environments are not the same as Amplify Hosting branch deployments, though the two are often linked together.
Amplify Hosting: CI/CD for Frontend#
Amplify Hosting provides a managed CI/CD pipeline for web applications. You connect a Git repository (GitHub, GitLab, Bitbucket, or CodeCommit), and every push to a branch triggers a build, test, and deploy cycle automatically. 🔗
Key features to know:
- Branch-based deployments — each branch maps to a URL (e.g.,
main→main.d1xyz.amplifyapp.com). This makes it trivial to run feature branches in isolation. - Branch previews (pull request previews) — Amplify can deploy a temporary environment for every open pull request, giving reviewers a live URL to test against before merging.
- Custom domains — you can attach your own domain. Amplify provisions an ACM certificate and handles HTTPS automatically.
- Build settings — controlled via an
amplify.ymlfile at the repo root, which defines pre-build, build, and post-build commands per branch. - Server-Side Rendering (SSR) — Amplify Hosting supports Next.js SSR apps natively, not just static sites.
The key distinction from a plain S3 + CloudFront setup is that Amplify Hosting handles the entire deployment lifecycle (build → test → invalidate cache → deploy), and branch environments are managed for you.
Amplify Libraries#
The Amplify Libraries are the client-side SDKs that connect your application code to the backend Amplify (or plain AWS) services. They are available for JavaScript/TypeScript, React, Vue, Next.js, iOS (Swift), Android (Kotlin/Java), and Flutter. 🔗
Rather than calling AWS SDK methods directly, you use high-level abstractions:
// Authentication with Amplify Auth (backed by Cognito)
import { signIn } from 'aws-amplify/auth';
await signIn({ username: 'user@example.com', password: 'secret' });
// File upload with Amplify Storage (backed by S3)
import { uploadData } from 'aws-amplify/storage';
await uploadData({ key: 'profile.jpg', data: file });
// API call with Amplify API (backed by API Gateway or AppSync)
import { get } from 'aws-amplify/api';
const response = await get({ apiName: 'myApi', path: '/items' }).response;The library reads from an amplifyconfiguration.json (or aws-exports.js in older versions) file generated by the CLI, so credentials, endpoint URLs, and region configuration are never hardcoded.
Amplify Auth#
amplify add auth provisions a Cognito User Pool (and optionally an Identity Pool for AWS resource access). The Amplify Auth library then wraps Cognito’s full feature set — sign-up, sign-in, MFA, password reset, social federation — into a straightforward API. 🔗
For UI, Amplify provides pre-built Authenticator components for React, Vue, and Angular that render a complete sign-in/sign-up flow with a single import. These are useful for prototyping but are customizable for production.
Amplify API#
amplify add api gives you a choice between two backends:
- REST — creates an API Gateway HTTP API + Lambda function. Good for simple CRUD operations and existing REST patterns.
- GraphQL — creates an AWS AppSync API. You define a GraphQL schema, and Amplify auto-generates resolvers, DynamoDB tables, and subscription support.
The GraphQL path is tightly integrated with AppSync and is the basis for Amplify DataStore (see below). For the exam, recognize that the GraphQL option is AppSync under the hood — not a custom Lambda.
Amplify Storage#
amplify add storage provisions an S3 bucket with Cognito-based access control. The library supports three access levels that map to S3 prefixes:
guest— publicly accessible, stored underpublic/protected— readable by all authenticated users, writable only by the owner; stored underprotected/{identityId}/private— accessible only by the owning user; stored underprivate/{identityId}/
This prefix-based model relies on Cognito Identity Pool credentials and S3 bucket policies, all generated by the CLI.
Amplify DataStore#
DataStore is the most architecturally interesting piece of Amplify and has appeared on the exam. It is a local-first data store that automatically syncs with AppSync and DynamoDB in the background. 🔗
The core value proposition: your app reads and writes to a local store (IndexedDB in browsers, SQLite on mobile). DataStore handles:
- Offline support — the app continues to function with no network connection, because all operations are local-first.
- Automatic sync — when connectivity returns, DataStore reconciles local changes with the AppSync backend using GraphQL subscriptions and mutations.
- Conflict resolution — when two clients modify the same record offline, DataStore applies a conflict resolution strategy. Built-in strategies are
Auto Merge,Optimistic Concurrency, andCustom Lambda. You configure this in your GraphQL schema with the@modeldirective.
A typical DataStore model definition looks like this in the schema:
type Todo @model @auth(rules: [{ allow: owner }]) {
id: ID!
title: String!
done: Boolean!
}Amplify generates TypeScript types, local storage operations, and all required AppSync resources from this single definition. The @auth directive controls who can read and write records — this maps directly to AppSync authorization rules.
For the exam, the key points about DataStore are: it requires AppSync as the backend, it provides offline-capable data access with automatic conflict resolution, and conflict resolution behavior is configurable per model.