@aws-blocks/blocks

中文文档
0.9.0发布于 2026/11/02Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 6.4万

Write your backend and frontend together — fully typed, runnable on your laptop, deployable to AWS unchanged.

原始使用文档
文档目录14 节
  1. Quick Start
  2. How it works
  3. Adding auth and data
  4. Building Blocks
  5. Choosing a data block
  6. Building Block documentation
  7. Local development and deploying
  8. Testing
  9. Best practices
  10. Common mistakes
  11. Security Considerations
  12. IAM hardening
  13. VPC Support
  14. Reference

AWS Blocks

Write your backend and frontend together — fully typed, runnable on your laptop, deployable to AWS unchanged.

AWS Blocks is a backend framework built from Building Blocks: self-contained modules that each bundle a CDK construct, its AWS SDK integration, and a local mock. You compose blocks in one directory, export an API, and call it from your frontend with end-to-end type safety. No client generation, no glue code, no AWS account needed to start.

This package (@aws-blocks/blocks) re-exports every Building Block and the core primitives, so you import everything from one place:

import { Scope, ApiNamespace, KVStore, AuthBasic } from '@aws-blocks/blocks';
  • Type-safe, end to end — your frontend calls backend methods directly; types flow through automatically.
  • Local-first — every block runs as an in-memory mock, so you build and test with zero cloud setup.
  • Deploys unchanged — npm run sandbox swaps the mocks for real AWS services (DynamoDB, Aurora, S3, Lambda…). Same code.
  • Low ceremony, high ceiling — common things are one line; when you need the underlying CDK construct or AWS SDK, it's right there.

Quick Start

npx @aws-blocks/create-blocks-app my-app
cd my-app
npm run dev          # → http://localhost:3000  (mocks, no AWS account needed)

--template <name> picks a starter (react, nextjs, backend, …); see @aws-blocks/create-blocks-app.

How it works

Your entire backend lives in one directory, aws-blocks/. You create blocks, then expose methods through an ApiNamespace:

// aws-blocks/index.ts
import { Scope, ApiNamespace, KVStore } from '@aws-blocks/blocks';

const scope = new Scope('my-app');
const store = new KVStore(scope, 'cache');

export const api = new ApiNamespace(scope, 'api', (context) => ({
  async getValue(key: string) {
    return await store.get(key);
  },
  async setValue(key: string, value: string) {
    await store.put(key, value);
  },
}));

The frontend imports that API and calls it like a local function — fully typed, no fetch, no client codegen:

// src/
import { api } from 'aws-blocks';

await api.setValue('greeting', 'hello');
const value = await api.getValue('greeting'); // typed: string | null

That's the whole model: define blocks → export an API → import it on the frontend. The transport (JSON-RPC under /aws-blocks/api) is handled for you and is intentionally invisible.

Adding auth and data

Blocks compose. Here's the same API gated behind authentication and backed by a queryable table:

// aws-blocks/index.ts
import { Scope, ApiNamespace, AuthBasic, DistributedTable } from '@aws-blocks/blocks';
import { z } from 'zod';

const scope = new Scope('my-app');

const auth = new AuthBasic(scope, 'auth', { passwordPolicy: { minLength: 8 } });

const notes = new DistributedTable(scope, 'notes', {
  schema: z.object({ userId: z.string(), noteId: z.string(), text: z.string() }),
  key: { partitionKey: 'userId', sortKey: 'noteId' },
});

// Sign-up / sign-in endpoints, ready to wire to the frontend
export const authApi = auth.createApi();

export const api = new ApiNamespace(scope, 'api', (context) => ({
  async addNote(text: string) {
    const user = await auth.requireAuth(context);          // 401s if not signed in
    const noteId = crypto.randomUUID();
    await notes.put({ userId: user.username, noteId, text });
    return { noteId };
  },
  async listNotes() {
    const user = await auth.requireAuth(context);
    return await Array.fromAsync(notes.query({ where: { userId: { equals: user.username } } }));
  },
}));

Security: every ApiNamespace method is a public internet endpoint with no auth by default. Gate a method by calling auth.requireAuth(context) (or auth.requireRole(...)) at the top. The local mock enforces nothing either — an ungated method passes every local check and still ships callable by anyone.

On the frontend, @aws-blocks/blocks/ui gives you provider-agnostic auth components, or drive authApi yourself:

import { Authenticator, onAuthChange } from '@aws-blocks/blocks/ui';
import { authApi, api } from 'aws-blocks';

document.body.append(Authenticator(authApi));
onAuthChange(authApi, (user) => {
  if (user) api.listNotes().then(render);
});

Building Blocks

Start from what you need:

  • Store data
    • Simple key → value (caches, flags, user prefs) → KVStore (bb-kv-store)
    • Structured records with indexes and queries → DistributedTable (bb-distributed-table) — default for most data
    • Relational / SQL (joins, transactions) → see Choosing a data block below
    • Files, blobs, uploads, static assets → FileBucket (bb-file-bucket)
    • A single config value → AppSetting (bb-app-setting)
    • A high-value credential (API key, OAuth secret, connection string) → Secret (bb-secret), backed by AWS Secrets Manager
  • Authenticate users
    • Username/password, prototypes/MVPs → AuthBasic (bb-auth-basic)
    • Cognito user pools, MFA, groups → AuthCognito (bb-auth-cognito)
    • External identity provider (OIDC) → AuthOIDC (bb-auth-oidc)
  • Run work outside the request/response
    • Fire-and-forget background jobs → AsyncJob (bb-async-job)
    • Scheduled / recurring tasks → CronJob (bb-cron-job)
  • Push live updates to browsers (chat, presence, dashboards) → Realtime (bb-realtime)
  • Build AI features
    • Agent with tool use + conversation → Agent (bb-agent)
    • Semantic document retrieval (RAG) → KnowledgeBase (bb-knowledge-base)
  • Send transactional email → EmailClient (bb-email-client)
  • Serve a raw HTTP endpoint (webhook receiver, health check, redirect, non-JSON response) → RawRoute (core); everything else goes through ApiNamespace RPC
  • Observe and operate
    • Structured logs → Logger (bb-logger)
    • Custom metrics → Metrics (bb-metrics)
    • Distributed traces → Tracer (bb-tracer)
    • Auto CloudWatch dashboard → Dashboard (bb-dashboard)

Choosing a data block

Default to DistributedTable for your data models unless your domain specifically requires SQL engine capabilities.

Reach for one of the SQL blocks when you need to filter or join results across more than one related record, filter models on many dimensions with no preset hierarchy, store large objects, require transactions, or otherwise need the flexibility or familiarity of SQL that NoSQL does not offer.

If you need SQL, prefer DistributedDatabase for Aurora DSQL, which is PostgreSQL wire-protocol compatible; see the Aurora DSQL SQL compatibility documentation for supported SQL features. Use Database specifically when you need a full (more expensive) Postgres implementation with row level security, triggers, procedures, or PL/pgSQL functions; large transactions (more than 3,000 rows); or integration with an existing Postgres database. Note it carries an idle cost at minimum 0.5 ACU, or a cold start when scaling from zero, unlike the other two blocks.

Building Block documentation

Every Building Block ships its docs inside the @aws-blocks/blocks package under docs/<block>/: each docs/<block>/ folder contains that block's README.md, plus API.md, DESIGN.md, and CHANGELOG.md where present. To read them, locate the bundled folder:

node -p "require('path').dirname(require.resolve('@aws-blocks/blocks/docs/README.md'))"

If resolution fails, fall back to node_modules/@aws-blocks/blocks/docs. That folder holds this guide (README.md), the framework's own API.md, TROUBLESHOOTING.md, and CHANGELOG.md (version history — read when troubleshooting), plus one subfolder per block; the catalog below lists every block.

BlockWhat it doesKeywords
auth-commonShared interfaces and UI components for all AWS Blocks auth Building Blocks.—
bb-agentAI agent with streaming, tool calling, and conversation persistence.—
bb-app-settingA single application configuration value backed by SSM Parameter Store.—
bb-async-jobBackground job processing backed by SQS, run on Lambda or a container.queue, job, background, async, worker, submit, batch, retry, status, transitions, SQS
bb-auth-basicSimple username/password authentication with JWT sessions, password policy, and optional code-confirmed signup and password reset.—
bb-auth-cognitoAuthentication backed by Amazon Cognito User Pools.—
bb-auth-oidcOIDC sign-in gate for AWS Blocks applications.—
bb-computeThe Compute Building Block is the single surface for choosing where a workload runs.—
bb-cron-jobScheduled task execution backed by EventBridge Scheduler and Lambda.cron, schedule, timer, periodic, recurring, rate, EventBridge, background, interval
bb-dashboardAuto-generated CloudWatch Dashboard for application observability.—
bb-dataFull PostgreSQL database — provisions Aurora Serverless v2 by default, or connects to an existing PostgreSQL database (Supabase, Neon, etc.) via fromExisting().—
bb-distributed-dataServerless SQL database backed by Amazon Aurora DSQL.—
bb-distributed-tableStructured data storage backed by DynamoDB with secondary indexes and rich query capabilities.—
bb-email-clientTransactional email sending via Amazon SES.—
bb-file-bucketFile storage backed by Amazon S3.—
bb-knowledge-baseSemantic document retrieval backed by Amazon Bedrock Knowledge Bases.—
bb-kv-storeSimple key-value storage backed by DynamoDB.—
bb-loggerStructured logging with consistent JSON format, log levels, and contextual metadata.—
bb-metricsCustom application metrics backed by Amazon CloudWatch (via Embedded Metric Format).—
bb-realtimeReal-time pub/sub messaging backed by API Gateway WebSocket + DynamoDB.—
bb-secretA single application secret backed by AWS Secrets Manager.—
bb-tracerDistributed tracing backed by AWS X-Ray.—
coreCore primitives for building full-stack applications with the AWS Blocks.—
hostingLow-level CDK L3 constructs for deploying web applications on AWS—
pipelineCDK Pipelines-based CI/CD construct for AWS Blocks applications.—

Local development and deploying

npm run devnpm run sandbox
Blocks run asin-memory mocksreal AWS services
AWS accountnot neededrequired
Datapersists to .bb-data/ (delete to reset)lives in AWS
Use forrapid iteration, testspre-production validation against real services

Deploying needs AWS credentials. npm run dev is fully local (no creds). npm run sandbox and npm run deploy provision real AWS resources, so configure credentials first — e.g. aws login (AWS CLI 2.32.0 or later), aws configure sso + aws sso login, or aws configure (verify with aws sts get-caller-identity). If the credentials are missing or expired, both commands stop before synthesizing and print the sign-in or refresh command for the profile they use. Use least-privilege credentials scoped to the services your blocks deploy — not broad Administrator access.

Before they deploy, npm run sandbox and npm run deploy print the deployment target: the credentials that CDK deploys with (an AWS profile, environment access keys, or container or web identity credentials) and the configured Region. As in CDK, environment access keys are used before AWS_PROFILE unless cdk.json sets a profile. With valid credentials they also show the account name and the AWS account plan (Free or Paid) when those credentials allow account:GetAccountInformation and freetier:GetAccountPlanState. Otherwise they show "not available" and continue; these reads never stop a deploy. When you sign in with the AWS-managed role of the new AWS sign-up experience (a role at the path /managed/ that account-access.amazonaws.com can assume, checked with iam:GetRole), the output also links to https://settings.aws.com/billing for spend limits. In AWS Settings, verify that the project you intend to manage matches the CLI deployment target before viewing or changing its spend limit. If you sign in with aws login, set the profile Region to your project's Region before you sign in (aws configure set region <region> --profile <name>), and run aws login again if you change it later. npm run sandbox:destroy and npm run destroy print only the deployment target.

With verified credentials, npm run sandbox (including npm run sandbox:deploy) and npm run deploy also check that CDK has been bootstrapped in that account and Region: they read the SSM parameter /cdk-bootstrap/<qualifier>/version, where the qualifier is @aws-cdk/core:bootstrapQualifier from the cdk.json context, or CDK's default. When the parameter does not exist, they stop before synthesizing and print the command that bootstraps this account and Region, npx cdk bootstrap aws://<account-id>/<region> --app=. Run it from the project directory; --app= keeps CDK from synthesizing the app first. Bootstrapping is needed once per account and Region, and it creates the CDKToolkit CloudFormation stack, including IAM roles that CDK deploys with, so the commands never bootstrap for you. Any other result of the read, such as a denied read or a timeout, does not stop the deploy.

npm run deploy does a full production deploy; npm run sandbox:deploy deploys the sandbox once and exits (no watch, for scripts and CI); npm run sandbox:destroy tears the sandbox down. The same backend code runs in all three — blocks switch implementations automatically.

Importing @aws-blocks/blocks through its default (Node) entry declares the default compute (LambdaCompute) so the CLI reports it in telemetry. It is folded in only when telemetry reads the registry, after the blocks the app constructed, and an app-constructed LambdaCompute takes precedence. The cdk and browser entries do not declare it.

npm run deploy streams CloudFormation events to stdout as they happen, so npm run deploy | tee deploy.log shows live progress instead of going silent for minutes, and a deploy failure keeps its reason on stderr (that stays the place to grep for why a deploy failed). On POSIX the deploy also survives a stray reap: a single SIGTERM, or any SIGHUP — a closed terminal, a backgrounded npm run deploy & — logs a line and keeps streaming rather than abandoning a stack update CloudFormation is still applying. Press Ctrl-C, or send SIGTERM twice, to stop it. That signal resilience is POSIX-only: Windows has no process groups and no OS-delivered SIGTERM/SIGHUP, so there a kill on the process tree still ends the deploy.

Testing

The fastest loop is calling your API through its typed import in test/e2e.test.ts — no browser, no mocking:

import { test } from 'node:test';
import assert from 'node:assert';
import type { api as ApiType } from 'aws-blocks';

let api: typeof ApiType;
test.before(async () => { api = (await import('aws-blocks')).api; });

test('stores and reads back a value', async () => {
  await api.setValue('k', 'v');
  assert.equal(await api.getValue('k'), 'v');
});

Run with npm run test:e2e. Write the test first, iterate against mocks until it passes.

Best practices

  • Export every API — the frontend can only import what you export from aws-blocks/index.ts.
  • Validate with schemas — pass a Zod/Valibot schema to data blocks for compile-time and runtime type safety.
  • Don't block the request — use AsyncJob for anything slow; submit() returns a jobId immediately.
  • Guard against races — use conditional writes (ifNotExists, ifValueEquals, ifFieldEquals) instead of read-modify-write.
  • Test locally first — mocks behave like the real service; deploy once it's green.

Common mistakes

  • Ungated endpoints — methods are public unless you call requireAuth/requireRole. The local mock won't catch this for you.
  • Forgetting to export — an ApiNamespace you don't export is invisible to the frontend.
  • Database when DistributedTable would do — Aurora costs more and has cold starts; reach for SQL only when you need it.
  • Curling REST-style paths — there is no GET /api/getData. All calls are JSON-RPC POSTs under /aws-blocks/api; use the typed import instead.

Security Considerations

  • Use await auth.requireAuth(context) in every method that shouldn't be public — ApiNamespace methods are unauthenticated by default
  • Use new Secret(scope, id) for API keys and credentials — Secret is the recommended home for production secrets. new AppSetting(scope, id, { secret: true }) is a free, encrypted fallback only for a low-value secret. Don't hardcode secret values in source, and don't ship real secrets to a deployed app through plaintext environment variables — set them through Secret/AppSetting
  • Always attach a schema to KVStore/AppSetting that accepts user data — the RPC layer validates structure but not business logic
  • Do not add broad * IAM policies — each Building Block already grants least-privilege scoped to its own resources
  • Never change blockPublicAccess on FileBucket — serve public files through CloudFront instead
  • Configure defaults.allowedOrigins explicitly for production — avoid wildcards
  • defaults.allowedOrigins covers the API only — a FileBucket whose presigned URLs or file handles are fetched from the browser needs its own corsRules listing your frontend origins (including http://localhost:3000 for a local frontend against a sandbox), or uploads/downloads fail with a CORS error once deployed
  • For cross-domain deployments, pass crossDomain: true to auth constructors (enables SameSite=None; Secure; Partitioned)
  • Enable frontDoor: { features: { monitoring: { enabled: true, subscriptions: [new subs.EmailSubscription('[email protected]')] } } } on Hosting for production alerts (subs = aws-cdk-lib/aws-sns-subscriptions; email/URL only; the top-level monitoring prop is its deprecated alias)
  • Add WAF and API Gateway throttling via CDK for public-facing apps — not included by default
  • Logger provides serialization safety (circular refs, type coercion) but does NOT redact sensitive content — never pass raw credentials, tokens, or secrets to Logger methods; sanitize context objects before logging

IAM hardening

Every Blocks compute runs as one shared IAM (Identity and Access Management) execution role, and every Building Block grants its permissions onto it. Set defaults.permissionsBoundary to attach a permissions boundary, a ceiling on effective permissions, to every IAM role AWS Blocks creates. Pass the policy's name, its full ARN (required when the policy has a path), or an iam.IManagedPolicy. It's unset in both presets, and unset leaves templates unchanged.

// aws-blocks/index.cdk.ts
export const blocksStack = await BlocksStack.create(app, stackName, {
  backendHandlerPath: join(__dirname, 'index.handler.ts'),
  backendCDKPath: join(__dirname, 'index.ts'),
  defaults: { ...BlocksPresets.production, permissionsBoundary: 'my-app-boundary' },
});
  • Report. Every synth, with or without a boundary, writes the shared role's composed policy to cdk.out/<stack>.blocks-iam.json (<stack>.<backendId>.blocks-iam.json for an embedded BlocksBackend); it isn't deployed, so CI can diff it to catch permission growth.
  • Scope. On a BlocksStack the boundary covers every role in the stack; on an embedded BlocksBackend it covers the backend's subtree plus the stack-level CDK (Cloud Development Kit) singleton roles its blocks add.
  • CDK context. If CDK's @aws-cdk/core:permissionsBoundary context is also set, defaults.permissionsBoundary wins for the roles Blocks creates and synth warns.

Details, including sharing one AWS account across many apps, are in the bundled @aws-blocks/core README (docs/core/README.md), sections "IAM: permissions boundary and the composed-policy report" and "Running many apps in one AWS account (a shared platform)".

VPC Support

AWS Blocks supports running your backend in a VPC for network-level isolation or to connect to VPC-bound resources. You can let Blocks manage endpoint provisioning and security groups automatically, or bring a fully-configured VPC and handle networking yourself.

See VPC.md for usage, configuration options, cost details, and guidance on when a VPC is appropriate.

Reference

  • Per-block documentation: docs/<block>/README.md (overview), plus docs/<block>/API.md (full API reference) and docs/<block>/DESIGN.md (architecture & rationale) where present — e.g. docs/bb-distributed-table/README.md. The catalog + decision tree live in docs/README.md.
  • UI components (@aws-blocks/blocks/ui): Authenticator, AuthenticatedContent, AccountMenuBar, onAuthChange, broadcastAuthChange — framework-agnostic, return DOM nodes. See the @aws-blocks/auth-common README.
  • SSR (@aws-blocks/blocks/server): withAuth forwards browser cookies to API calls during server rendering. See the @aws-blocks/core README.
  • Wire protocol & debugging: the client is JSON-RPC 2.0 under /aws-blocks/api — you should never call it directly. For curl-level troubleshooting, see TROUBLESHOOTING.md.

版本与发布记录

@aws-blocks/blocks 共发布 23 个版本,首次发布于 2026/06/16;过去 12 个月发布了 23 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.9.0latest2026/11/025 天前
0.8.02026/10/1622 天前
0.0.0-canary.esql-canary.c93c81b.1791235863canary-esql-canary2026/10/061 个月前
0.7.02026/10/051 个月前
0.0.0-canary.esql-canary.f7f39ac.17909891272026/10/031 个月前
0.0.0-canary.ci-publish-canary-npm.f53dfdc.1790988617canary-ci-publish-canary-npm2026/10/031 个月前

关于 @aws-blocks/blocks 的常见问题

@aws-blocks/blocks 是什么?

Write your backend and frontend together — fully typed, runnable on your laptop, deployable to AWS unchanged.

如何安装 @aws-blocks/blocks?

在项目目录运行 npm install @aws-blocks/blocks,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 blocks-vendorize、blocks-generate-client,可以用 npx blocks-vendorize 直接运行。

@aws-blocks/blocks 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@aws-blocks/blocks 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@aws-blocks/blocks 可以商用吗?

@aws-blocks/blocks 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@aws-blocks/blocks 的下载量有多少?

根据 npm 官方下载统计,@aws-blocks/blocks 在 2026/10/07 – 2026/11/05 这 30 天内被下载 64,228 次,日均约 2,141 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@aws-blocks/blocks 还在维护吗?

最新版本 0.9.0 发布于 2026/11/02(5 天前);至今共发布 23 个版本,其中过去 12 个月发布了 23 个;首次发布于 2026/06/16。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。