From vfm-agent-company
Serverless - Cloud Functions & Event-Driven Architecture. Build APIs, event processing, scheduled tasks with AWS Lambda, API Gateway, DynamoDB. Use when building auto-scaling backend without managing servers.
npx claudepluginhub duylinhdang1998/claude-template-agent --plugin vfm-agent-companyThis skill uses the workspace's default tool permissions.
**Purpose**: Build scalable, cost-effective applications using serverless architecture with AWS Lambda, API Gateway, and managed services
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Purpose: Build scalable, cost-effective applications using serverless architecture with AWS Lambda, API Gateway, and managed services
Agent: Amazon Cloud Architect Use When: Building APIs, event processing, scheduled tasks, or auto-scaling backend services without managing servers
Serverless lets you run code without provisioning or managing servers. Pay only for compute time consumed.
Core Benefits:
AWS Serverless Stack:
export const handler = async (event: any) => {
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: 'Hello from Lambda!' })
}
}
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
const { httpMethod, pathParameters, body } = event
switch (httpMethod) {
case 'GET':
return respond(200, await getUsers())
case 'POST':
return respond(201, await createUser(JSON.parse(body || '{}')))
default:
return respond(405, { error: 'Method not allowed' })
}
}
function respond(statusCode: number, data: any) {
return {
statusCode,
headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' },
body: JSON.stringify(data)
}
}
# template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
ApiFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs20.x
Handler: index.handler
Events:
Api:
Type: Api
Properties:
Path: /users
Method: GET
sam build && sam deploy --guided
const table = new dynamodb.Table(this, 'Table', {
partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST
})
const handler = new lambda.Function(this, 'Handler', {
runtime: lambda.Runtime.NODEJS_20_X,
code: lambda.Code.fromAsset('dist'),
handler: 'index.handler',
environment: { TABLE_NAME: table.tableName }
})
table.grantReadWriteData(handler)
// CDK
new events.Rule(this, 'DailyReport', {
schedule: events.Schedule.cron({ hour: '9', minute: '0' }),
targets: [new targets.LambdaFunction(reportFunction)]
})
For detailed code examples: Read references/code-examples.md
// ❌ Bad: Initialize inside handler
export const handler = async () => {
const db = new DynamoDBClient({}) // Cold start every time!
}
// ✅ Good: Initialize outside handler
const db = new DynamoDBClient({}) // Reused across invocations
export const handler = async () => {
// Use db
}
export const handler = async (event: any) => {
try {
const result = await processEvent(event)
return { statusCode: 200, body: JSON.stringify(result) }
} catch (error) {
console.error('Error:', error)
if (error instanceof ValidationError) {
return { statusCode: 400, body: JSON.stringify({ error: error.message }) }
}
return { statusCode: 500, body: JSON.stringify({ error: 'Internal error' }) }
}
}
export const handler = async (event: any, context: any) => {
console.log('Request ID:', context.requestId)
console.log('Event:', JSON.stringify(event))
// ...
}
| Strategy | Description |
|---|---|
| Right-size memory | Test 128MB-10GB, find cost/speed sweet spot |
| Minimize package | Use esbuild, tree-shaking, production deps only |
| Use Provisioned Concurrency | Only for critical, consistent-load functions |
| Avoid polling | Use EventBridge/SQS instead of scheduled polling |
# Bundle with esbuild
esbuild src/index.ts --bundle --platform=node --target=node20 --outfile=dist/index.js
# Production only
npm install --production
import { DynamoDBDocumentClient, GetCommand, PutCommand } from '@aws-sdk/lib-dynamodb'
const docClient = DynamoDBDocumentClient.from(new DynamoDBClient({}))
// Get
const { Item } = await docClient.send(new GetCommand({
TableName: 'users',
Key: { id: '123' }
}))
// Put
await docClient.send(new PutCommand({
TableName: 'users',
Item: { id: '123', name: 'John', createdAt: new Date().toISOString() }
}))
For detailed code examples including:
Read: references/code-examples.md
Remember: Serverless is not "no ops" - it's "different ops". Monitor costs, optimize cold starts, and design for statelessness.
Created: 2026-02-04 Maintained By: Amazon Cloud Architect Version: AWS Lambda (Node.js 20)