CrewAI Tutorial (TypeScript): deploying to AWS Lambda for intermediate developers

By Cyprian AaronsUpdated 2026-04-21
crewaideploying-to-aws-lambda-for-intermediate-developerstypescript

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

  1. 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
  1. 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"]
}
  1. 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);
}
  1. 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',
      }),
    };
  }
};
  1. 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"
  }
}
  1. 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

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

Related Guides