Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Provides AWS Lambda integration patterns for TypeScript with cold start optimization. Use when creating or deploying TypeScript Lambda functions, choosing between NestJS framework and raw TypeScript approaches, optimizing cold starts, configuring API Gateway or ALB integration, or implementing serverless TypeScript applications. Triggers include "create lambda typescript", "deploy typescript lambda", "nestjs lambda aws", "raw typescript lambda", "aws lambda typescript performance".
.claude/skills/giuseppe-trisciuoglio-aws-lambda-typescript-integration/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 85% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 88% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 145% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 127% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 88% | 0% |
Patterns for creating high-performance AWS Lambda functions in TypeScript with optimized cold starts.
Two approaches for TypeScript Lambda:
Both support API Gateway and ALB integration.
| Approach | Cold Start | Bundle Size | Best For | Complexity | |----------|------------|-------------|----------|------------| | NestJS | < 500ms | Larger (100KB+) | Complex APIs, enterprise apps, DI needed | Medium | | Raw TypeScript | < 100ms | Smaller (< 50KB) | Simple handlers, microservices, minimal deps | Low |
my-nestjs-lambda/
├── src/
│ ├── app.module.ts
│ ├── main.ts
│ ├── lambda.ts # Lambda entry point
│ └── modules/
│ └── api/
├── package.json
├── tsconfig.json
└── serverless.ymlmy-ts-lambda/
├── src/
│ ├── handlers/
│ │ └── api.handler.ts
│ ├── services/
│ └── utils/
├── dist/ # Compiled output
├── package.json
├── tsconfig.json
└── template.yamlSee the References section for detailed implementation guides. Quick examples:
NestJS Handler:
typescript// lambda.ts import { NestFactory } from '@nestjs/core'; import { ExpressAdapter } from '@nestjs/platform-express'; import serverlessExpress from '@codegenie/serverless-express'; import { Context, Handler } from 'aws-lambda'; import express from 'express'; import { AppModule } from './src/app.module'; let cachedServer: Handler; async function bootstrap(): Promise<Handler> { const expressApp = express(); const adapter = new ExpressAdapter(expressApp); const nestApp = await NestFactory.create(AppModule, adapter); await nestApp.init(); return serverlessExpress({ app: expressApp }); } export const handler: Handler = async (event: any, context: Context) => { if (!cachedServer) { cachedServer = await bootstrap(); } return cachedServer(event, context); };
Raw TypeScript Handler:
typescript// src/handlers/api.handler.ts import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda'; export const handler = async ( event: APIGatewayProxyEvent, context: Context ): Promise<APIGatewayProxyResult> => { return { statusCode: 200, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: 'Hello from TypeScript Lambda!' }) }; };
TypeScript cold start depends on bundle size and initialization code. Key strategies:
See Raw TypeScript Lambda for detailed patterns.
Create clients at module level and reuse:
typescript// GOOD: Initialize once, reuse across invocations import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; const dynamoClient = new DynamoDBClient({ region: process.env.AWS_REGION }); export const handler = async (event: APIGatewayProxyEvent) => { // Use dynamoClient - already initialized };
typescript// src/config/env.config.ts export const env = { region: process.env.AWS_REGION || 'us-east-1', tableName: process.env.TABLE_NAME || '', debug: process.env.DEBUG === 'true', }; // Validate required variables if (!env.tableName) { throw new Error('TABLE_NAME environment variable is required'); }
Keep package.json minimal:
json{ "dependencies": { "aws-lambda": "^3.1.0", "@aws-sdk/client-dynamodb": "^3.450.0" }, "devDependencies": { "typescript": "^5.3.0", "esbuild": "^0.19.0" } }
Return proper HTTP codes with structured errors:
typescriptexport const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => { try { const result = await processEvent(event); return { statusCode: 200, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(result) }; } catch (error) { console.error('Error processing request:', error); return { statusCode: 500, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ error: 'Internal server error' }) }; } };
Use structured logging for CloudWatch Insights:
typescriptconst log = (level: string, message: string, meta?: object) => { console.log(JSON.stringify({ level, message, timestamp: new Date().toISOString(), ...meta })); }; log('info', 'Request processed', { requestId: context.awsRequestId });
Serverless Framework:
yamlservice: my-typescript-api provider: name: aws runtime: nodejs20.x functions: api: handler: dist/handler.handler events: - http: path: /{proxy+} method: ANY
AWS SAM:
yamlAWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: ApiFunction: Type: AWS::Serverless::Function Properties: CodeUri: dist/ Handler: handler.handler Runtime: nodejs20.x Events: ApiEvent: Type: Api Properties: Path: /{proxy+} Method: ANY
Pre-deploy checks:
npm test - verify all tests passnpm run build - confirm TypeScript compiles without errorsserverless invoke local or sam local invoke - test locallyPost-deploy verification:
serverless invoke or aws lambda invoke - verify handler executesFor complete deployment configurations including CI/CD, see Serverless Deployment.
@types/aws-lambda for proper event typingcontext.getRemainingTimeInMillis() for long operationsFor detailed guidance on specific topics:
Input: Create a TypeScript Lambda REST API using NestJS for a todo application
Process:
nest new@codegenie/serverless-express, aws-lambdalambda.ts entry point with Express adapterserverless.yml with API Gateway eventsValidation:
serverless invoke local -f api - verify handler worksOutput: NestJS project with REST API, DynamoDB integration, deployment config
Input: Create a minimal TypeScript Lambda function with optimal cold start
Process:
Validation:
sam local invoke - test locally before deployingdu -sh dist/Output: Minimal TypeScript Lambda, bundle < 50KB, cold start < 100ms
Input: Configure CI/CD for TypeScript Lambda with SAM
Process:
Validation:
npm test successfullysam validate passes in pipelineOutput: GitHub Actions workflow, multi-stage pipeline, test automation
Version: 1.0.0
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 15,317 | 12,212 | -20% | 1 | 1 | 0% | 2,855 | 5,283 | +85% | 0 | 0 | — |
case-02 | fail→pass | 13,951 | 40,363 | +189% | 1 | 1 | 0% | 2,589 | 4,858 | +88% | 0 | 0 | — |
case-03 | pass→pass | 10,696 | 8,828 | -17% | 1 | 1 | 0% | 1,900 | 4,322 | +127% | 0 | 0 | — |
case-04 | fail→fail | 12,139 | 8,320 | -31% | 1 | 1 | 0% | 2,100 | 4,259 | +103% | 0 | 0 | — |
case-05 | pass→pass | 16,599 | 13,597 | -18% | 1 | 1 | 0% | 2,918 | 5,499 | +88% | 0 | 0 | — |
case-16 | pass→pass | 16,722 | 10,133 | -39% | 1 | 1 | 0% | 2,630 | 4,560 | +73% | 0 | 0 | — |
case-06 | fail→pass | 9,321 | 3,660 | -61% | 1 | 1 | 0% | 1,376 | 3,368 | +145% | 0 | 0 | — |
case-07 | pass→pass | 9,630 | 5,384 | -44% | 1 | 1 | 0% | 1,718 | 3,805 | +121% | 0 | 0 | — |
case-08 | pass→pass | 13,798 | 11,779 | -15% | 1 | 1 | 0% | 2,730 | 5,168 | +89% | 0 | 0 | — |
case-09 | pass→pass | 12,307 | 9,528 | -23% | 1 | 1 | 0% | 2,088 | 4,521 | +117% | 0 | 0 | — |
case-10 | pass→pass | 14,263 | 6,657 | -53% | 1 | 1 | 0% | 2,294 | 3,976 | +73% | 0 | 0 | — |
case-11 | pass→pass | 7,167 | 3,348 | -53% | 1 | 1 | 0% | 1,232 | 3,352 | +172% | 0 | 0 | — |
case-12 | pass→pass | 13,749 | 5,774 | -58% | 1 | 1 | 0% | 2,411 | 3,834 | +59% | 0 | 0 | — |
case-13 | pass→pass | 11,974 | 4,197 | -65% | 1 | 1 | 0% | 1,975 | 3,365 | +70% | 0 | 0 | — |
case-14 | pass→pass | 11,897 | 6,631 | -44% | 1 | 1 | 0% | 2,005 | 4,005 | +100% | 0 | 0 | — |
case-15 | fail→fail | 12,049 | 9,854 | -18% | 1 | 1 | 0% | 2,337 | 4,450 | +90% | 0 | 0 | — |
case-17 | pass→pass | 3,019 | 2,828 | -6% | 1 | 1 | 0% | 546 | 3,332 | +510% | 0 | 0 | — |
case-18 | pass→pass | 8,766 | 8,868 | +1% | 1 | 1 | 0% | 1,533 | 4,530 | +195% | 0 | 0 | — |
case-19 | pass→pass | 21,489 | 12,983 | -40% | 1 | 1 | 0% | 3,400 | 5,010 | +47% | 0 | 0 | — |
case-20 | pass→pass | 15,978 | 14,356 | -10% | 1 | 1 | 0% | 2,907 | 5,474 | +88% | 0 | 0 | — |
case-21 | pass→pass | 31,725 | 11,661 | -63% | 1 | 1 | 0% | 3,114 | 5,450 | +75% | 0 | 0 | — |
case-22 | pass→pass | 11,357 | 12,207 | +7% | 1 | 1 | 0% | 2,236 | 5,166 | +131% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +14 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.