This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
MicroApps enables deploying many web applications to AWS on a single shared hostname with CloudFront, S3 static assets, and API Gateway routing. Applications are deployed as Lambda functions with version-based routing controlled by the microapps-router Lambda@Edge function.
# Build all TypeScript and bundle Lambda functions
npm run build:all
# Build TypeScript only (all packages)
npm run build
# Build individual Lambda bundles
npm run esbuild:deployer # Bundles deployer Lambda
npm run esbuild:router # Bundles router Lambda
npm run esbuild:edge-to-origin # Bundles edge function# Run all unit tests (uses jest-dynalite for local DynamoDB)
npm test
# Run integration tests
npm run test:integration
# Run tests for specific package
cd packages/microapps-router && npm testnpm run lint # ESLint check
npm run lint-and-fix # ESLint with auto-fix
npm run format # Prettier formattingnpm run clean # Remove dist/ and .tsbuildinfo
npm run clean:super # Also remove node_modules# Deploy the example CDK stack
./deploy.sh
# Or manually:
npx cdk deploy --context @pwrdrvr/microapps:deployReleaseApp=true microapps-basicThis is a Yarn workspace monorepo with TypeScript project references. Key packages:
- microapps-cdk: Turn-key CDK construct (published via jsii for multi-language support)
- microapps-deployer: Lambda function that handles app deployments (invoked by pwrdrvr CLI)
- microapps-router: Lambda@Edge function that routes requests to app versions
- microapps-edge-to-origin: Alternative CloudFront edge function for routing
- microapps-datalib: Shared DynamoDB models and data access layer
- microapps-deployer-lib: Message types/interfaces for deployer operations
- microapps-router-lib: Shared routing utilities
- pwrdrvr: CLI tool for publishing apps (uses oclif framework)
- cdk: Example CDK stack demonstrating MicroApps usage
- demo-app: Test application without any UI framework
pwrdrvr CLI → invokes → microapps-deployer Lambda
↓
DynamoDB (via microapps-datalib)
↓
CloudFront → microapps-router Lambda → API Gateway → App Lambda Functions
Request Flow:
- User hits CloudFront URL:
/{appname}/ - Router Lambda looks up current version for app in DynamoDB
- Router returns redirect or iframe to versioned app endpoint
- App Lambda serves the request via Lambda Function URL or API Gateway
Lambda functions use a three-layer build strategy:
- TypeScript compilation (
tsc --build) - Compiles all packages - esbuild bundling - Bundles Lambda functions to single files:
- Deployer →
packages/cdk/dist/microapps-deployer/index.js - Router →
packages/cdk/dist/microapps-router/index.js - Edge-to-Origin →
packages/microapps-cdk/lib/microapps-edge-to-origin/index.js
- Deployer →
- CDK fallback - If pre-bundled code unavailable, uses NodejsFunction
The CDK construct looks for pre-bundled Lambda code first (for CI/CD speed), then falls back to runtime bundling.
Both Router and Deployer use ts-convict with YAML configuration files:
- Base config:
config.yml - Environment-specific:
config-{dev|qa|prod|local}.yml - Selected via
NODE_ENVenvironment variable - Lambda environment variables override YAML settings
Key config sections:
- db: DynamoDB table name, region
- fileStore: S3 staging and destination buckets
- apiGateway: Base URLs, endpoints
- iam: Role names for upload operations
- routing: Root path prefix, default files
DBManager (packages/microapps-datalib/src/manager.ts) provides DynamoDB access using AWS SDK v3:
DynamoDBDocumentfor simpler operationsDynamoDBClientfor low-level operations- Models: Application, Version, Rules
Message Types (packages/microapps-deployer-lib/src/messages/):
IRequestBasewith operation types:createApp,deployVersion,deleteVersion, etc.AppType:lambda,lambda-url,url,staticAppStartupType:iframe(transparent iframe) ordirect(framework with relative URLs)
- Framework: Jest 29 with ts-jest preset
- Test files:
**/*.spec.ts - Local DynamoDB: jest-dynalite for integration tests
- Mocking: aws-sdk-client-mock for AWS SDK v3, sinon for spies/stubs
- Coverage: Collected automatically, output to
/coverage
To test Lambda functions locally:
// Override dependencies for testing
import { overrideDBManager } from './index';
overrideDBManager({ dbManager: mockDB, dynamoClient: mockClient });- Edit source in
packages/microapps-{deployer|router}/src/index.ts - Run
npm run esbuild:{deployer|router}to bundle - Run
npm testto verify changes - Update config if adding new environment variables
- Add message type to
packages/microapps-deployer-lib/src/messages/ - Implement handler in
packages/microapps-deployer/src/controllers/ - Add switch case in
packages/microapps-deployer/src/index.ts - Export new types from deployer-lib
index.ts
- Core logic:
packages/microapps-router-lib/src/get-route.ts - Lambda handler:
packages/microapps-router/src/index.ts - Update tests in both locations
- Rebuild with
npm run esbuild:router
The MicroApps construct (packages/microapps-cdk/src/MicroApps.ts) is the turn-key solution. For more control, use individual constructs:
MicroAppsSvcs- DynamoDB, Router, Deployer LambdasMicroAppsCF- CloudFront distributionMicroAppsS3- S3 buckets for static assetsMicroAppsAPIGwy- API Gateway HTTP API
- This repo uses Yarn, not npm (npm has dependency resolution issues with jest)
- Lambda functions target Node 18 runtime
- All Lambda function code is bundled with esbuild (not webpack)
- TypeScript uses project references (tsconfig.json references packages)
- The CDK construct uses jsii for multi-language support (Python, Java, .NET)
- Router Lambda uses Lambda@Edge pricing (3x more expensive than origin Lambda)
- Test files use
isolatedModules: truein ts-jest for faster compilation - The microapps-cdk package is managed by projen and has its own ESLint config with
@stylisticrules - it's excluded from root linting via.eslintignore
If changes to Lambda functions aren't appearing after CDK deploy:
- Ensure you ran the esbuild command for that Lambda
- Check that
packages/cdk/dist/microapps-{deployer|router}/index.jswas updated - Verify
npm run build:allcompleted successfully
If tests fail with DynamoDB errors:
- Ensure
jest-dynaliteis properly initialized (checksetupBeforeEnv.js) - Verify
jest-dynalite-config.jshas correct table definitions - Check that
AWS_PROFILEis unset during test runs
If CDK deploy fails with Lambda bundling errors:
- Try running
npm run build:allfirst to pre-bundle - Check that all package dependencies are installed
- Verify
node_modules/@typeshas required type definitions
If you see errors like Error while loading rule '@stylistic/indent':
- The
microapps-cdkpackage is managed by projen and uses@stylistic/eslint-plugin - This package is excluded from root linting in
.eslintignore - To lint microapps-cdk, use
cd packages/microapps-cdk && npx projen eslint - Do not modify
.eslintrc.jsonin microapps-cdk directly - edit.projenrc.jsinstead