Skip to content

aws-amplify

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).

6,493
installs
0 up / 0 down, score 0.00
votes
2,930
repo stars
Updated
less than a month ago
In the catalog since
1 Oct 2026
From
aws/agent-toolkit-for-aws
Get it through your agent npx skills add aws/agent-toolkit-for-aws@aws-amplify

Skill instructions

Rendered from the published SKILL.md, 381 lines.

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, 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

Step 2: Backend Features

Read the corresponding reference for each backend feature you need:

Feature Reference When to Use
Authentication auth-backend.md Email/password, social login, MFA, SAML/OIDC
Data Models data-backend.md GraphQL schema, DynamoDB, relationships, auth rules
File Storage storage-backend.md S3 uploads/downloads, access rules
Functions & API functions-and-api.md Lambda, custom resolvers, REST/HTTP APIs, calling from client
AI Features ai.md Conversation, generation, AI tools via Bedrock (backend config + React/Next.js frontend)
Geo, PubSub, CDK 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
Data CRUD & subscriptions data-web.md
Storage upload/download storage-web.md

Mobile (Flutter, Swift, Android):

Feature Reference
Auth UI & flows auth-mobile.md
Data CRUD & subscriptions data-mobile.md
Storage upload/download storage-mobile.md

Note: AI and Functions frontend patterns are included in ai.md and 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/<name>/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.)

project-root/
├── amplify/
│   ├── backend.ts            # defineBackend({ auth, data, ... })
│   ├── auth/resource.ts      # defineAuth({ ... })
│   ├── data/resource.ts      # defineData({ schema })
Show the whole skill (261 more lines)

│ ├── 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: `<Authenticator>`, `<StorageBrowser>` |
| `@aws-amplify/ui-react-ai` | AI UI: `<AIConversation>`, `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:

// 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:

// app/layout.tsx
import ConfigureAmplifyClientSide from "@/components/ConfigureAmplifyClientSide";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        <ConfigureAmplifyClientSide />
        {children}
      </body>
    </html>
  );
}

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:

import { Amplify } from 'aws-amplify';
import outputs from '../amplify_outputs.json';
Amplify.configure(outputs);

Angular — src/main.ts:

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:

// 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.

<Authenticator.Provider> 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

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:

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):

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:

// 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):

// 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 (
    <Authenticator>
      {({ signOut, user }) => <main>Hello {user?.username}</main>}
    </Authenticator>
  );
}

Use in an Astro page with client:only:

---
// src/pages/index.astro — no Amplify imports here
---
<html>
  <body>
    <AuthenticatedApp client:only="react" />
  </body>
</html>

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