CrewAI Tutorial (TypeScript): deploying to AWS Lambda for intermediate developers
This tutorial shows you how to package a CrewAI workflow written in TypeScript and run it on AWS Lambda behind a simple handler. You’d use this when you want an agentic job to execute on demand, on a schedule, or from an API without keeping a server running.
What You'll Need
- •Node.js 20+
- •AWS CLI configured with an IAM user or role that can deploy Lambda
- •An AWS Lambda execution role with:
- •
AWSLambdaBasicExecutionRole - •permission to read secrets if you store API keys in Secrets Manager
- •
- •A CrewAI-compatible TypeScript project
- •
crewai,zod,dotenv,esbuild, and@types/aws-lambda - •An LLM API key, for example:
- •
OPENAI_API_KEY
- •
- •A basic familiarity with:
- •async/await
- •AWS Lambda handlers
- •bundling TypeScript for Node.js
Step-by-Step
- •Start with a clean TypeScript project and install the packages you need for Lambda and CrewAI. The important part here is that Lambda runs a single bundled file, so we’ll build for Node.js rather than ship raw source.
mkdir crewai-lambda-demo
cd crewai-lambda-demo
npm init -y
npm install crewai zod dotenv @types/aws-lambda
npm install -D typescript esbuild @types/node
npx tsc --init
- •Set your TypeScript config for Node.js Lambda output. Keep the module system compatible with AWS Lambda, and make sure the compiler emits modern JavaScript that Node 20 can run directly.
{
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"moduleResolution": "Node",
"outDir": "dist",
"rootDir": "src",
"strict": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"types": ["node", "aws-lambda"]
},
"include": ["src/**/*.ts"]
}
- •Create your CrewAI workflow in TypeScript. This example keeps it simple: one agent, one task, one crew, and a JSON result returned from the Lambda handler.
// src/crew.ts
import { Agent, Crew, Task } from 'crewai';
export async function runCrew(input: string): Promise<string> {
const analyst = new Agent({
role: 'Insurance Claims Analyst',
goal: 'Summarize claim notes into a concise operational update',
backstory: 'You write clear internal summaries for claims operations teams.',
verbose: false,
});
const task = new Task({
description: `Summarize this claim note in 3 bullet points:\n\n${input}`,
expectedOutput: 'A short operational summary with three bullets.',
agent: analyst,
});
const crew = new Crew({
agents: [analyst],
tasks: [task],
verbose: false,
});
const result = await crew.kickoff();
return String(result);
}
- •Add the Lambda handler and load environment variables at runtime. In production, don’t hardcode keys into the bundle; use Lambda environment variables or Secrets Manager.
// src/handler.ts
import type { APIGatewayProxyHandlerV2 } from 'aws-lambda';
import dotenv from 'dotenv';
import { runCrew } from './crew';
dotenv.config();
export const handler: APIGatewayProxyHandlerV2 = async (event) => {
try {
const body = event.body ? JSON.parse(event.body) : {};
const input = String(body.input ?? 'Customer reported delayed payment after policy update.');
if (!process.env.OPENAI_API_KEY) {
return {
statusCode: 500,
body: JSON.stringify({ error: 'OPENAI_API_KEY is not set' }),
};
}
const output = await runCrew(input);
return {
statusCode: 200,
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ output }),
};
} catch (err) {
return {
statusCode: 500,
body: JSON.stringify({
error: err instanceof Error ? err.message : 'Unknown error',
}),
};
}
};
- •Add a build script that bundles everything into one file for Lambda. Esbuild keeps deployment small and avoids shipping your entire node_modules tree.
{
"name": "crewai-lambda-demo",
"version": "1.0.0",
"main": "dist/index.js",
"scripts": {
"build": "esbuild src/handler.ts --bundle --platform=node --target=node20 --outfile=dist/index.js",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@types/aws-lambda": "^8.10.147",
"crewai": "^0.0.0",
"dotenv": "^16.4.5",
"zod": "^3.23.8"
},
"devDependencies": {
"@types/node": "^22.0.0",
"esbuild": "^0.24.0",
"typescript": "^5.6.3"
}
}
- •Deploy the bundle to AWS Lambda and wire the environment variable in the function configuration. If you want HTTP access, put API Gateway in front of it; if you want scheduled runs, use EventBridge.
npm run build
zip -j function.zip dist/index.js
aws lambda create-function \
--function-name crewai-ts-demo \
--runtime nodejs20.x \
--role arn:aws:iam::123456789012:role/lambda-exec-role \
--handler index.handler \
--zip-file fileb://function.zip \
--timeout 60 \
--memory-size 1024 \
--environment Variables="{OPENAI_API_KEY=sk-your-key}"
aws lambda invoke \
--function-name crewai-ts-demo \
--payload '{"body":"{\"input\":\"Claim submitted after storm damage; adjuster requested follow-up\"}"}' \
response.json
cat response.json
Testing It
Run npm run typecheck first to catch any TypeScript issues before deployment. Then run npm run build and confirm dist/index.js exists and is under Lambda’s size limits.
For local verification, invoke the compiled handler through aws lambda invoke or use the AWS console test event with a JSON body containing input. If the function returns a structured response with your summary text, your bundling and runtime config are correct.
If it fails with an auth or model error, check the Lambda logs in CloudWatch first; most issues at this stage are missing environment variables or IAM misconfiguration rather than CrewAI code bugs.
Next Steps
- •Move API keys out of Lambda env vars and into AWS Secrets Manager with KMS encryption.
- •Add structured outputs with Zod so your agent returns validated JSON instead of free text.
- •Wrap the Lambda behind API Gateway or EventBridge depending on whether you need synchronous requests or scheduled jobs.
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit