AWS Amplify has been around long enough to live two distinct lives. The original — now called Gen 1 — shipped in 2018 as a CLI-driven way to provision AWS resources for a frontend project. Gen 2, launched in 2024, is a near-total rewrite of the authoring experience while keeping the same underlying AWS services. If you're starting a new project, or staring at a legacy amplify/ folder wondering whether to migrate, the differences matter.
The headline difference: how you define a backend
Gen 1 is CLI-first. You run amplify add auth, answer a series of questions, and the CLI writes JSON config files into amplify/backend/. Each command translates your answers into CloudFormation templates that get deployed to AWS. Resource configuration lives in files like amplify-meta.json, cli-inputs.json, and team-provider-info.json.
Gen 2 is code-first. Your entire backend is a TypeScript program:
// amplify/backend.ts
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';
defineBackend({ auth, data });No interactive prompts, no generated JSON. You write the shape of your backend in code, and a deployment pipeline turns that code into CDK constructs, which become CloudFormation, which becomes AWS resources. The intermediate layers are hidden by default but still accessible when you need to escape the abstraction.
Data modeling
In Gen 1, data is defined in a schema.graphql file with directives like @model and @auth. The AppSync resolvers are generated for you, but customizing them often means dropping into VTL templates — a legacy AWS templating language that few developers love.
Gen 2 keeps GraphQL under the hood but moves the schema into TypeScript:
const schema = a.schema({
Todo: a.model({
content: a.string(),
done: a.boolean(),
}).authorization(allow => [allow.owner()]),
});The win isn't just syntax. Because the schema is TypeScript, your frontend gets fully-typed client calls automatically — no codegen step, no stale types after a backend change.
Auth, storage, functions
The list of services hasn't really changed — Cognito for auth, S3 for storage, Lambda for functions — but the way you describe them has:
Auth — Gen 1 generates a Cognito User Pool from CLI prompts; Gen 2 defines it in
auth/resource.tswith typed options.Storage — Same S3 bucket underneath; Gen 2 lets you express access rules as code rather than IAM JSON.
Functions — Gen 1 functions live in
amplify/backend/function/<name>/src/; Gen 2 functions are TypeScript modules with explicit triggers and IAM grants.
Local development
This is where Gen 2 feels most different. Gen 1 gives you amplify mock — a simulator that approximates DynamoDB and AppSync locally. It works, but the gap between mock and prod is real, and bugs that only appear after deploy are common.
Gen 2 introduces per-developer sandboxes: npx ampx sandbox spins up a real, isolated AWS environment tied to your machine. You're not mocking anything — you're hitting actual AWS services in a personal stack that tears down when you stop. It costs a few cents a day, and it eliminates the mock-vs-prod drift entirely.
Deployments and environments
Gen 1 environments are named (dev, staging, prod) and switched with amplify env checkout. State for each lives in team-provider-info.json, which gets committed to the repo — including some values that arguably shouldn't be there.
Gen 2 ties environments to Git branches. Push to main, you get a main backend; push to a feature branch, you get a feature backend. PR previews are first-class. There's no team-provider-info.json equivalent — environment state lives in AWS Amplify Hosting, not in your repo.
Where Gen 1 still wins
It's not a clean sweep. Gen 1 has advantages worth naming:
Maturity. Five years of edge cases have been patched. Gen 2 still has rough corners.
Documentation depth. Stack Overflow, blog posts, and community plugins skew heavily Gen 1.
Stability. Gen 1 is in maintenance mode but it's not going anywhere soon. Existing projects don't need to migrate.
Migration: should you?
AWS does not offer an automated Gen 1 → Gen 2 migration. The two generations can coexist in the same AWS account, but the project structures are incompatible. Migrating means a manual rebuild of the backend definition, then a data migration if you're moving between AppSync instances.
The honest answer for most teams: migrate when you'd be making major changes anyway. If a project is running fine on Gen 1, the cost of a forced migration rarely pays back. If you're starting fresh, Gen 2 is the right default.
The bottom line
Gen 1 was Amplify-as-a-CLI: a productivity tool that wrote AWS config for you. Gen 2 is Amplify-as-a-framework: an opinionated, typed, code-first way to describe a cloud backend. Same AWS underneath, very different developer experience on top. For new projects, the choice is easy. For existing ones, the math depends on how much you'd be touching the backend anyway.