| name | building-aws-blocks-apps |
| description | Builds fullstack TypeScript applications on AWS using @aws-blocks/blocks. Provides correct import paths, API signatures, project scaffolding, and deployment patterns. Use when working with @aws-blocks/blocks, any Building Block (KVStore, DistributedTable, Agent, AuthBasic, AuthCognito, AuthOIDC, Realtime, Database, DistributedDatabase, AsyncJob, CronJob, KnowledgeBase, AppSetting, FileBucket, EmailClient, Logger, Metrics, Tracer, Dashboard), ApiNamespace, BlocksStack, RawRoute, Pipeline, Hosting, or the create-blocks-app CLI. |
AWS Blocks Development
Prerequisites
- Node.js ≥ 22
- npm ≥ 10
- For AWS deployment (optional):
- AWS CLI configured with credentials
- CDK bootstrapped in your account (
npx cdk bootstrap)
- Dev dependencies:
typescript, tsx, vite, concurrently, aws-cdk-lib, constructs, @types/node
Decision guide
Creating a new project?
→ npm create @aws-blocks/blocks-app@latest my-app
→ Templates: default (Vite SPA), react (React SPA), nextjs (Next.js SSR), demo (todo + auth), auth-cognito (Cognito MFA/groups), amplify (Amplify Gen 2 migration), backend (API-only, no frontend), bare (minimal empty scaffold)
Adding to an existing project?
→ Scaffold into a temp dir, copy only aws-blocks/ folder, then manually merge workspace config, scripts, and dependencies. The scaffolder overwrites root package.json, tsconfig.json, vite.config.ts, .gitignore.
Which auth?
- Simple username/password + built-in UI → AuthBasic
- Passwordless, MFA, social federation, Cognito features → AuthCognito
- External IdP (Google, GitHub, Okta, Auth0, Entra) → AuthOIDC
Which storage?
Which AI?
- Conversational agent with tools + streaming → Agent
- RAG over documents (vector search) → KnowledgeBase
Core concepts
Architecture overview (Scope, ApiNamespace, JSON-RPC, CORS, withAuth): See CORE-ARCHITECTURE.md
Block references
Read the relevant file when working with a specific block:
Hosting & deployment: See blocks/hosting.md
Common errors & fixes: See TROUBLESHOOTING.md
Native mobile/desktop clients: See NATIVE-CLIENTS.md
Project structure
my-app/
├── aws-blocks/
│ ├── index.ts # Backend: Building Blocks + API (edit this)
│ ├── index.cdk.ts # CDK entry point (generated, don't edit)
│ ├── index.handler.ts # Lambda handler (generated, don't edit)
│ ├── deploy.ts # Production deploy script
│ ├── package.json # Workspace package with conditional exports
│ └── scripts/ # Dev server, sandbox, cleanup scripts
├── src/ # Frontend (any framework)
├── package.json # Root with "workspaces": ["aws-blocks"]
└── tsconfig.json
Backend lives in aws-blocks/index.ts. Frontend imports from 'aws-blocks' (workspace package). The client.js is auto-generated — never edit it.
Quick start
import { Scope, ApiNamespace, KVStore, AuthBasic } from "@aws-blocks/blocks";
const scope = new Scope("my-app");
const auth = new AuthBasic(scope, "auth", {
sessionDuration: 86400,
passwordPolicy: { minLength: 8, requireDigits: true },
});
const store = new KVStore(scope, "settings", {});
export const authApi = auth.createApi();
export const api = new ApiNamespace(scope, "api", (context) => ({
async greet(name: string) {
const user = await auth.requireAuth(context);
return { message: `Hello, ${user.username}!` };
},
}));
Frontend:
import { api } from "aws-blocks";
const result = await api.greet("World");
Running Agents locally: See blocks/agent.md
Verification workflow
After any code change to aws-blocks/index.ts:
- Run
npm run typecheck (or npx tsc --noEmit) to catch type errors before starting the server
- Start dev server (tmux) → look for "Blocks local server running"
- If type errors appear → fix → rerun typecheck → restart
- After adding new exports → run dev once to regenerate
client.js
- Test API call:
curl -X POST http://localhost:3000/aws-blocks/api -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","method":"api.methodName","params":[],"id":1}'
- Verify response is correct
Do not proceed to frontend work until the backend verifies clean.
Deployment
npm run sandbox
npm run sandbox:destroy
npm run deploy
npm run destroy
Do NOT run cdk deploy directly.
CDK imports for hosting/deployment (aws-blocks/index.cdk.ts):
import { Hosting, BlocksStack } from '@aws-blocks/blocks/cdk';
import { join } from 'node:path';
const blocksStack = await BlocksStack.create(app, 'my-app', { });
new Hosting(blocksStack, 'Hosting', {
root: join(__dirname, '..'),
buildCommand: 'npm run build',
framework: 'nextjs',
api: blocksStack,
compute: { memorySize: 1024, timeout: 30 },
domain: { domainName: 'app.example.com', certificateArn: '...' },
waf: { enabled: true },
});
Frontend UI imports (Authenticator widget):
import { Authenticator, onAuthChange, broadcastAuthChange } from "@aws-blocks/blocks/ui";
Next.js local dev — set BLOCKS_API_URL env var for server components:
{ "dev:next": "BLOCKS_API_URL=http://localhost:3000/api next dev" }
Key rules
- Always scaffold —
npm create @aws-blocks/blocks-app@latest
- Only edit
aws-blocks/index.ts for backend logic
- Use
auth.createApi() for auth — auto-wires IAM. Do NOT build custom ApiNamespace wrappers
- Use
npm run sandbox to deploy — handles CDK context, removal policies
- Frontend imports from
'aws-blocks' — conditional exports handle browser vs server
client.js is auto-generated — run dev to regenerate, never edit manually
- DistributedTable
query() takes { index, where, limit? } — index must be from indexes config
- To list all items, use a constant partition key with a GSI — no scan operation
- Use short Scope IDs (2-3 chars) — Realtime namespace names must stay under 50 chars
- Run
npm run dev once after adding new exports to regenerate client.js
- Create
aws-blocks/destroy.ts manually — scaffolder doesn't include production destroy
Troubleshooting
See TROUBLESHOOTING.md for common errors and fixes.
Additional references