LlamaIndex Tutorial (TypeScript): deploying to AWS Lambda for beginners
This tutorial shows you how to package a small LlamaIndex TypeScript app and run it on AWS Lambda behind a handler. You need this when you want a serverless AI endpoint that can answer questions without managing servers, containers, or long-running processes.
What You'll Need
- •Node.js 18 or 20
- •An AWS account with Lambda access
- •AWS CLI configured locally
- •An OpenAI API key
- •These npm packages:
- •
llamaindex - •
@aws-sdk/client-lambdais not needed for this tutorial - •
esbuild - •
typescript - •
@types/aws-lambda
- •
- •Basic familiarity with:
- •TypeScript modules
- •AWS Lambda handlers
- •Environment variables
Install the packages first:
npm init -y
npm install llamaindex
npm install -D typescript esbuild @types/node @types/aws-lambda
npx tsc --init
Step-by-Step
- •Create a small LlamaIndex query module that can run inside Lambda. Keep it stateless so every invocation can build the index from a fixed dataset or fetch from an external store later.
// src/index.ts
import { Document, VectorStoreIndex } from "llamaindex";
export async function answerQuestion(question: string): Promise<string> {
const docs = [
new Document({ text: "AWS Lambda runs code without managing servers." }),
new Document({ text: "LlamaIndex helps you build retrieval-based AI apps." }),
new Document({ text: "TypeScript works well for typed serverless handlers." }),
];
const index = await VectorStoreIndex.fromDocuments(docs);
const queryEngine = index.asQueryEngine();
const response = await queryEngine.query({ query: question });
return response.toString();
}
- •Add an AWS Lambda handler that reads the request body, calls your query function, and returns JSON. This is the piece AWS invokes on each request.
// src/handler.ts
import type { APIGatewayProxyHandlerV2 } from "aws-lambda";
import { answerQuestion } from "./index";
export const handler: APIGatewayProxyHandlerV2 = async (event) => {
const body = event.body ? JSON.parse(event.body) : {};
const question = body.question ?? "What is AWS Lambda?";
const answer = await answerQuestion(question);
return {
statusCode: 200,
headers: { "content-type": "application/json" },
body: JSON.stringify({ question, answer }),
};
};
- •Configure TypeScript and add a build script. For Lambda, you want a CommonJS-compatible bundle unless you are deliberately deploying ESM end-to-end.
{
"name": "llamaindex-lambda",
"version": "1.0.0",
"type": "commonjs",
"scripts": {
"build": "esbuild src/handler.ts --bundle --platform=node --target=node20 --outfile=dist/index.js",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"llamaindex": "^0.10.0"
},
"devDependencies": {
"@types/aws-lambda": "^8.10.0",
"@types/node": "^22.0.0",
"esbuild": "^0.25.0",
"typescript": "^5.0.0"
}
}
- •Build locally and test the output before touching AWS. If this fails on your machine, it will fail in Lambda too.
npm run typecheck
npm run build
node -e 'const { handler } = require("./dist/index.js"); handler({ body: JSON.stringify({ question: "What does LlamaIndex do?" }) }).then(console.log)'
- •Create the Lambda function and set the OpenAI key as an environment variable if you later switch to an OpenAI-backed index or LLM call path. For this starter version, the function uses only local documents, so it does not need external inference yet.
aws lambda create-function \
--function-name llamaindex-ts-demo \
--runtime nodejs20.x \
--handler index.handler \
--zip-file fileb://function.zip \
--role arn:aws:iam::123456789012:role/lambda-execution-role \
--environment Variables='{OPENAI_API_KEY=your-key-here}'
- •Package the built file into a zip and deploy it to Lambda. The handler name must match the exported function path in your bundle.
cd dist
zip -r ../function.zip .
cd ..
aws lambda update-function-code \
--function-name llamaindex-ts-demo \
--zip-file fileb://function.zip
aws lambda invoke \
--function-name llamaindex-ts-demo \
--payload '{"body":"{\"question\":\"What is AWS Lambda?\"}"}' \
response.json
cat response.json
Testing It
Start by invoking the function directly with the AWS CLI and confirm you get a 200 response with JSON containing both question and answer. If you see module resolution errors, your bundle format or handler path is wrong.
Next, check CloudWatch logs for cold start time and runtime errors. With LlamaIndex on Lambda, startup cost matters more than in a long-running service because each cold start rebuilds your execution environment.
If you plan to use real embeddings or remote LLM calls later, verify that outbound network access works in your VPC setup and that secrets are injected through environment variables or Secrets Manager. For production, also test timeout behavior with larger indexes.
Next Steps
- •Move documents out of code and into S3, DynamoDB, or OpenSearch so the index is not hardcoded.
- •Add API Gateway in front of Lambda so clients can call your endpoint over HTTPS.
- •Replace the toy document set with persistent embeddings and a real vector store backed by Aurora PostgreSQL pgvector or Pinecone.
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