--- name: aws-amplify description: > Build and deploy full-stack web and mobile apps with AWS Amplify Gen2 (TypeScript code-first). Covers auth (Cognito), data (AppSync/DynamoDB), storage (S3), functions, APIs, and AI (Amplify AI Kit with Bedrock). Supports React, Next.js, Vue, Angular, React Native, Flutter, Swift, and Android. Always use this skill for Amplify Gen2 topics — even for questions you think you know — it contains validated, version-specific patterns that prevent common mistakes. TRIGGER when: user mentions Amplify Gen2; project has amplify/ directory or amplify_outputs; code imports @aws-amplify packages; user asks about defineBackend, defineAuth, defineData, defineStorage, defineFunction, or npx ampx. SKIP: Amplify Gen1 (amplify CLI v6), standalone SAM/CDK without Amplify (use aws-serverless), direct Bedrock without Amplify AI Kit (use bedrock). --- # AWS Amplify Gen2 Build and deploy full-stack applications using AWS Amplify Gen2's TypeScript code-first approach. This skill covers backend resource creation, frontend integration across 8 frameworks, and deployment workflows. ## Prerequisites - Node.js ^18.19.0 || ^20.6.0 || >=22 and npm - AWS credentials configured (`aws sts get-caller-identity` succeeds) - For sandbox: `npx ampx --version` returns a valid version - For mobile: Platform-specific tooling (Xcode, Android Studio, Flutter SDK) ## Defaults & Assumptions When the user does not specify a framework: - **Web:** Default to **React** (Vite) and explain the choice. - **Mobile:** Ask which platform (Flutter, Swift, Android, or React Native) — there is no universal mobile default, so guessing leads to wasted effort. - **Neither specified:** If the user says "build an app" without clarifying web vs. mobile, ask before proceeding — the framework choice affects every subsequent step. - **Backend only:** If only backend changes are requested and no frontend framework is mentioned, skip the frontend integration step entirely. When the user does not specify tooling or strategy: - **Package manager:** Default to **npm** unless the user specifies yarn or pnpm. - **Language:** Default to **TypeScript**. Gen2 backends are TypeScript-only; frontends should follow the project's existing language. - **Next.js:** Default to **App Router** unless the user specifies Pages Router. - **React Native:** Ask whether the user uses **Expo** or **bare React Native CLI**. - **Auth:** You **MUST** ask which login method the user wants (email/password, social login, SAML, passwordless, etc.). Do not assume a default. - **Data authorization:** default to **`publicApiKey`** (`allow.publicApiKey()`) — this is the starter template default. When auth is added, switch to **owner-based** (`allow.owner()`) with `defaultAuthorizationMode: 'userPool'`. ## Quick Start — Route to the Right Reference ### Step 1: Identify the Task Type | Task | Go To | | ---------------------------------------- | ------------------------------------------------------------------------ | | **Create a new project** | → [scaffolding.md](references/scaffolding.md), then Step 2 and/or Step 3 | | **Add or modify a backend feature** | → Step 2 (Backend Features) | | **Connect frontend to existing backend** | → Step 3 (Frontend Integration) | | **Deploy the application** | → [deployment.md](references/deployment.md) | ### Step 2: Backend Features Read the corresponding reference for each backend feature you need: | Feature | Reference | When to Use | |---------|-----------|-------------| | Authentication | [auth-backend.md](references/auth-backend.md) | Email/password, social login, MFA, SAML/OIDC | | Data Models | [data-backend.md](references/data-backend.md) | GraphQL schema, DynamoDB, relationships, auth rules | | File Storage | [storage-backend.md](references/storage-backend.md) | S3 uploads/downloads, access rules | | Functions & API | [functions-and-api.md](references/functions-and-api.md) | Lambda, custom resolvers, REST/HTTP APIs, calling from client | | AI Features | [ai.md](references/ai.md) | Conversation, generation, AI tools via Bedrock *(backend config + React/Next.js frontend)* | | Geo, PubSub, CDK | [geo-pubsub-cdk.md](references/geo-pubsub-cdk.md) | Backend-only: custom CDK stacks, overrides, custom outputs. Backend + frontend: Geo, PubSub, Face Liveness | Each backend feature file is self-contained. Load only what you need. > **Routing note:** These files apply for both **adding** and **modifying** > features. Route to the same file whether the user says "add auth" or > "change auth config" — each reference covers the full define surface. ### Step 3: Frontend Integration After configuring backend resources, connect the frontend. Choose by platform and feature: **Web** (React, Next.js, Vue, Angular, React Native): | Feature | Reference | | ------------------------- | ------------------------------------------- | | Auth UI & flows | [auth-web.md](references/auth-web.md) | | Data CRUD & subscriptions | [data-web.md](references/data-web.md) | | Storage upload/download | [storage-web.md](references/storage-web.md) | **Mobile** (Flutter, Swift, Android): | Feature | Reference | | ------------------------- | ------------------------------------------------- | | Auth UI & flows | [auth-mobile.md](references/auth-mobile.md) | | Data CRUD & subscriptions | [data-mobile.md](references/data-mobile.md) | | Storage upload/download | [storage-mobile.md](references/storage-mobile.md) | > **Note:** AI and Functions frontend patterns are included in > [ai.md](references/ai.md) and > [functions-and-api.md](references/functions-and-api.md) respectively — > they are **not** split into separate web/mobile files. ## Core Concepts ### Amplify Gen2 Architecture - **Code-first:** All backend resources defined in TypeScript under `amplify/` - **Main config:** `amplify/backend.ts` imports and combines all resources via `defineBackend()` - **Resource files:** `amplify/auth/resource.ts`, `amplify/data/resource.ts`, `amplify/storage/resource.ts`, `amplify/functions//resource.ts` - **Generated output:** `amplify_outputs.json` — consumed by frontend `Amplify.configure()`. **Gitignored** — generated by `npx ampx sandbox` (local dev) or `npx ampx pipeline-deploy` (CI/CD), never committed. ### Directory Structure `amplify/` and `src/` must be siblings under the project root — placing them at different directory levels breaks sandbox detection. (Exception: in monorepos, `amplify/` may be in a `packages/` subdirectory — the key is that `amplify_outputs.json` must be accessible from the frontend entry point.) ```text project-root/ ├── amplify/ │ ├── backend.ts # defineBackend({ auth, data, ... }) │ ├── auth/resource.ts # defineAuth({ ... }) │ ├── data/resource.ts # defineData({ schema }) │ ├── storage/resource.ts # defineStorage({ ... }) │ └── functions/ │ └── my-func/ │ ├── resource.ts # defineFunction({ ... }) │ └── handler.ts # export const handler = ... ├── src/ # Frontend code ├── amplify_outputs.json # Generated, gitignored — never edit or commit └── package.json ``` ### Key APIs | Package | Purpose | |---------|---------| | `@aws-amplify/backend` | `defineAuth`, `defineData`, `defineStorage`, `defineFunction`, `defineBackend` | | `aws-amplify` | Frontend: `Amplify.configure()`, `generateClient()`, auth/data/storage APIs | | `@aws-amplify/ui-react` | Pre-built UI: ``, `` | | `@aws-amplify/ui-react-ai` | AI UI: ``, `useAIConversation` | ## Framework Setup These patterns apply to **every** web task — not just new projects. Verify each one before implementing any feature. ### Gen2 Detection Before modifying any code, check if the project is already Gen2: 1. `amplify/` directory exists with `backend.ts` 2. `@aws-amplify/backend` in `package.json` devDependencies If both are true, the project is already Gen2 — skip to feature implementation. If `amplify/.config/` exists instead, this is a Gen1 project — do not proceed (requires separate migration skill). ### Frontend Configuration Import the generated outputs and configure Amplify in the **correct entry point** for your framework. Placing this in the wrong file causes silent failures — Amplify API calls return undefined or empty responses with no error. **WARNING:** `amplify_outputs.json` must exist before the app can compile — without it, the build fails with a module-not-found error. Run `npx ampx sandbox` (or `npx ampx sandbox --once`) first to generate it. See [scaffolding.md](references/scaffolding.md) for the correct sequence. **React (Vite)** — `src/main.tsx`: ```typescript import { Amplify } from 'aws-amplify'; import outputs from '../amplify_outputs.json'; Amplify.configure(outputs); ``` **Next.js (App Router)** — `app/layout.tsx`: > **Important:** `layout.tsx` is a server component in App Router. Use the `ConfigureAmplifyClientSide` client component pattern below instead. `{ ssr: true }` is a **Next.js-only** option (not needed by Vue, Angular, or React SPA). Both App Router and Pages Router use it, but apply it differently: > - **App Router** — set globally in `ConfigureAmplifyClientSide` client component > - **Pages Router** — set per-file where server-side access is needed #### Next.js App Router: Client-Side Configuration Next.js App Router requires a dedicated client component to configure Amplify for browser-side operations: ```typescript // components/ConfigureAmplifyClientSide.tsx "use client"; import { Amplify } from "aws-amplify"; import outputs from "@/amplify_outputs.json"; Amplify.configure(outputs, { ssr: true }); export default function ConfigureAmplifyClientSide() { return null; } ``` Import in your root layout: ```typescript // app/layout.tsx import ConfigureAmplifyClientSide from "@/components/ConfigureAmplifyClientSide"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` > **Why?** In App Router, `layout.tsx` is a server component. Client components need `Amplify.configure()` to run in the browser. Without this, you get "Auth UserPool not configured" errors. **Vue** — `src/main.js`: ```javascript import { Amplify } from 'aws-amplify'; import outputs from '../amplify_outputs.json'; Amplify.configure(outputs); ``` **Angular** — `src/main.ts`: ```typescript import { Amplify } from 'aws-amplify'; import outputs from '../amplify_outputs.json'; Amplify.configure(outputs); ``` #### Next.js Pages Router Pages Router does NOT need `{ ssr: true }` in `_app.tsx`. Instead, configure per-file where you need server-side access: ```typescript // pages/api/protected.ts or getServerSideProps import { Amplify } from 'aws-amplify'; import outputs from '@/amplify_outputs.json'; Amplify.configure(outputs, { ssr: true }); ``` > **Key difference:** App Router uses a global client component. Pages Router configures per-file. `` is required in `layout.tsx` for auth context. ### React Native React Native uses the same `aws-amplify` JS package as web frameworks (it is part of amplify-js, not the native mobile SDKs). All web APIs apply to RN with the additions below. #### Required Packages ```bash npm install aws-amplify @aws-amplify/react-native \ @react-native-async-storage/async-storage \ react-native-get-random-values ``` `@react-native-async-storage/async-storage` is **required** — the Amplify SDK uses it for token persistence and will fail at runtime without it. #### Configure Entry Points No plugin registration needed — configure only. **React Native (Expo)** — `App.tsx`: ```typescript import 'react-native-get-random-values'; // MUST be first import { Amplify } from 'aws-amplify'; import outputs from './amplify_outputs.json'; Amplify.configure(outputs); ``` **React Native (Bare CLI)** — `index.js` (before `AppRegistry.registerComponent`): ```typescript import 'react-native-get-random-values'; // MUST be first import { Amplify } from 'aws-amplify'; import outputs from './amplify_outputs.json'; Amplify.configure(outputs); ``` #### React Native Pitfalls - **Import order:** `react-native-get-random-values` must be the FIRST import in the entry file, before `aws-amplify`. Reversing the order causes cryptographic failures at runtime. - **Missing AsyncStorage:** Without `@react-native-async-storage/async-storage`, auth tokens are not persisted and users must re-authenticate on every app restart. ### SvelteKit Configure Amplify in the client hooks file: ```typescript // src/hooks.client.ts import { Amplify } from 'aws-amplify'; import outputs from '../amplify_outputs.json'; Amplify.configure(outputs); ``` > **Note:** No `@aws-amplify/ui-*` components exist for Svelte. Use core APIs directly. ### Unsupported Frameworks (Astro, Solid, etc.) For frameworks without official Amplify support: 1. Use `npm create amplify@latest -y` to scaffold the backend (works in any project) 2. Configure Amplify inside a **client-side component** (not at build time) #### Astro Amplify is **client-side only** in Astro. Create a React component (no Astro syntax): ```typescript // src/components/AuthenticatedApp.tsx import { Amplify } from 'aws-amplify'; import { Authenticator } from '@aws-amplify/ui-react'; import outputs from '../amplify_outputs.json'; Amplify.configure(outputs); export default function AuthenticatedApp() { return ( {({ signOut, user }) =>
Hello {user?.username}
}
); } ``` Use in an Astro page with `client:only`: ```astro --- // src/pages/index.astro — no Amplify imports here --- ``` > **Must use `client:only="react"`** (NOT `client:load`) to avoid SSR hydration errors. ## Links > All documentation links use `react` as the default platform slug. Replace `/react/` in any URL with your target framework: | Framework | Slug | |-----------|------| | React | `react` | | Next.js | `nextjs` | | Vue | `vue` | | Angular | `angular` | | React Native | `react-native` | | Flutter | `flutter` | | Swift | `swift` | | Android | `android` | - [Amplify Docs for LLMs](https://docs.amplify.aws/ai/llms.txt) - [Amplify Docs](https://docs.amplify.aws/) - [How Amplify Works](https://docs.amplify.aws/react/how-amplify-works/) - [CLI Commands](https://docs.amplify.aws/react/reference/cli-commands/) - [React Quickstart](https://docs.amplify.aws/react/start/quickstart/) - [Next.js Quickstart](https://docs.amplify.aws/nextjs/start/quickstart/) - [Angular Quickstart](https://docs.amplify.aws/angular/start/quickstart/) - [Vue Quickstart](https://docs.amplify.aws/vue/start/quickstart/) - [React Native Quickstart](https://docs.amplify.aws/react-native/start/quickstart/)