AWS Amplify Gen 2 — Ch.1: What is AWS Amplify Gen 2?

aws tutorial typescript web-dev

Video coming soon

Expected:

The Problem Amplify Solves

Frontend developers are extraordinarily productive in JavaScript and TypeScript. They can ship a polished Next.js interface in days. But the moment they need a backend — authentication, a database, file uploads, serverless logic — they collide with a wall of AWS complexity. IAM roles, CloudFormation syntax, VPC configuration, DynamoDB partition key design: these are full disciplines unto themselves.

AWS Amplify was created specifically to bridge this gap. The core promise: a frontend developer with TypeScript skills should be able to configure a production-grade AWS backend without becoming an AWS specialist.

Gen 1 (released 2018) tackled this with an interactive CLI. You ran amplify add auth, answered a series of questions in the terminal, and Amplify generated a CloudFormation template behind the scenes. It worked, but it had a fundamental flaw: your infrastructure lived in auto-generated JSON files that were difficult to review in pull requests, impossible to reason about, and painful to customize beyond what the wizard offered.

Gen 2 (generally available May 2024) took a different approach entirely. Instead of prompts, you write TypeScript. Your backend is a set of .ts files that you maintain, review, and version-control like any other code. This shift — from configuration files to code — is the defining characteristic of Amplify Gen 2.

// amplify/backend.ts — this IS your backend definition
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';

defineBackend({
  auth,
  data,
});

That is a complete backend definition. Three imports, one function call. Under the hood it provisions Cognito, AppSync, DynamoDB, IAM roles, and all the wiring between them.

What was the primary limitation of Amplify Gen 1's CLI wizard approach?

The Four Core Services

Amplify Gen 2 is an opinionated selection of AWS services, each mapped to a common backend concern:

Auth maps to Amazon Cognito — the AWS managed identity platform. Cognito handles user registration, login, social providers (Google, GitHub, Apple), MFA, and JWT token issuance. You configure it through defineAuth().

Data maps to AWS AppSync (managed GraphQL API) backed by Amazon DynamoDB (NoSQL database). When you define a data model in TypeScript, Amplify creates a GraphQL schema in AppSync and a DynamoDB table with appropriate indexes. You interact with data through a fully typed client generated from your schema.

Storage maps to Amazon S3. Amplify adds an opinionated path-based permission model on top of S3, so you can easily say “users can only read/write their own files” without writing complex bucket policies.

Functions maps to AWS Lambda. Serverless functions can be triggered on a schedule, in response to S3 events, as Cognito triggers, or exposed as HTTP endpoints via API Gateway.

// amplify/auth/resource.ts
import { defineAuth } from '@aws-amplify/backend';

export const auth = defineAuth({
  loginWith: {
    email: true, // Enable email/password sign-up and login → creates Cognito User Pool
  },
});
// amplify/data/resource.ts
import { a, defineData, type ClientSchema } from '@aws-amplify/backend';

const schema = a.schema({
  Post: a.model({
    title: a.string().required(),   // Required field
    content: a.string(),            // Optional field (nullable by default)
    published: a.boolean().default(false), // Boolean with default value
  }).authorization(allow => [allow.owner()]), // Only the creator can read/write their posts
});

export type Schema = ClientSchema<typeof schema>; // Generates TS types from schema for the frontend

export const data = defineData({
  schema,
  authorizationModes: {
    defaultAuthorizationMode: 'userPool', // Uses Cognito JWT tokens to authorize queries
  },
});

Which AWS service does Amplify Data use as its managed GraphQL layer?

CDK Under the Hood

One of the most important architectural decisions in Gen 2 is that it compiles down to AWS CDK (Cloud Development Kit). CDK is AWS’s infrastructure-as-code framework that lets you define cloud resources in TypeScript (or Python, Java, Go, etc.) and synthesize them to CloudFormation.

Amplify Gen 2 uses CDK L3 Constructs — the highest level of abstraction. While an L1 construct maps 1:1 to a CloudFormation resource (verbose and low-level), and an L2 construct wraps a single service with sensible defaults, an L3 construct encapsulates an entire pattern across multiple services.

defineAuth() is an L3 construct. Internally, it creates: a Cognito User Pool, a Cognito User Pool Client, a Cognito Identity Pool, IAM roles for authenticated and unauthenticated users, and all the wiring between them. What would be 200+ lines of CloudFormation YAML becomes one function call in TypeScript.

This architecture matters for two reasons. First, you are not locked into Amplify abstractions — you can always import { Stack } from 'aws-cdk-lib' and add any AWS service that Amplify does not natively support. Second, everything Amplify does is inspectable: you can run npx ampx generate to see the generated CloudFormation and understand exactly what is being deployed.

flowchart LR
  A["TypeScript Files
(amplify/)"] -->|compile| B["CDK Constructs"]
  B -->|synthesize| C["CloudFormation
Template"]
  C -->|deploy| D["AWS Resources
(Cognito, AppSync,
DynamoDB, S3)"]
  D -->|generate| E["amplifyconfiguration.json
(frontend config)"]
  style A fill:#f0f4ff,stroke:#4f46e5
  style D fill:#fff7ed,stroke:#ea580c
  style E fill:#f0fdf4,stroke:#16a34a

Amplify vs the Alternatives

Understanding when to choose Amplify requires knowing its trade-offs relative to the alternatives:

Firebase / Supabase: These are BaaS (Backend as a Service) platforms with their own proprietary databases and APIs. Amplify differs in that it deploys to your own AWS account — you own the data, you pay AWS directly, and you have full access to the underlying resources. The trade-off is more complexity during setup, but significantly more control and no vendor lock-in beyond AWS itself.

Vercel + PlanetScale/Neon: This combination offers excellent developer experience for Next.js but requires stitching together multiple vendors. Amplify keeps everything in one ecosystem (AWS) and integrates deeply with Next.js App Router including server-side rendering via Lambda@Edge.

Bare AWS CDK: CDK gives you more control but requires deep AWS expertise. Amplify’s sweet spot is precisely teams that want AWS’s infrastructure but without needing a dedicated DevOps engineer.

Choose Amplify when: your team knows TypeScript, you want AWS infrastructure, you need Auth + Data + Storage without extensive AWS expertise, and you are building a new project (greenfield). Consider alternatives when: you need relational data with complex joins (use RDS instead of DynamoDB), your team has dedicated AWS/infrastructure engineers (bare CDK gives more control), or you need a globally distributed edge database (Supabase or PlanetScale).

Setting Up Your Environment

Before writing any code, install the prerequisites:

# Node.js 18 or later (check with node --version)
node --version

# Install the Amplify backend CLI globally
npm install -g @aws-amplify/backend-cli

# Verify installation
ampx --version

# Configure AWS credentials (you need an AWS account)
# Option 1: AWS CLI
aws configure

# Option 2: Environment variables
export AWS_ACCESS_KEY_ID=your-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-key
export AWS_REGION=us-east-1

The AWS account requires an IAM user (or IAM Identity Center SSO) with AdministratorAccess during development. In production, you will scope down the permissions, but for local sandbox development, broad permissions reduce friction.

What does AWS CDK L3 Constructs provide that makes Amplify Gen 2 powerful?

Test Your Knowledge

Conclusions

  • Amplify Gen 2 replaces CLI wizards with TypeScript files — your infrastructure is code you own and version-control
  • The four core services map to real AWS: Auth → Cognito, Data → AppSync + DynamoDB, Storage → S3, Functions → Lambda
  • CDK L3 Constructs are the engine: Amplify TypeScript compiles to CDK, which synthesizes to CloudFormation
  • You always have an escape hatch: any AWS service can be added via raw CDK constructs alongside Amplify resources
  • Amplify is the right choice when you want AWS infrastructure without AWS specialization, for TypeScript-first teams
  • Install @aws-amplify/backend-cli globally (ampx) and configure AWS credentials before writing any code