Configuration
Every Effortless project starts with a config file in the project root. This is where you set the project name, AWS region, and tell Effortless where to find your handlers.
Overview
Create effortless.config.ts at the root of your project:
import { defineConfig } from "effortless-aws";
export default defineConfig({ name: "my-service", region: "eu-central-1", handlers: ["src/**/*.ts"],});That’s the minimum — a name, a region, and a pattern to find handlers. The defineConfig helper gives you full autocompletion and type checking. Effortless will discover all defineApi, defineTable, defineQueue, and other handler exports in matching files.
Project Config
name (required)
The project name is used as a prefix for all AWS resources: Lambda functions, DynamoDB tables, SQS queues, IAM roles, etc.
For example, with name: "orders" and stage dev, a handler named createOrder becomes orders-dev-createOrder in AWS.
Choose a short, unique name — changing it later means redeploying everything.
region
AWS region where all resources will be created. Default: "eu-central-1".
Can be overridden per deploy with eff deploy --region us-east-1.
stage
Deployment stage for resource isolation. Each stage gets its own set of resources — different Lambda functions, different DynamoDB tables, different queues. Default: "dev".
Override per deploy with eff deploy --stage prod. This lets you run multiple environments in the same AWS account without conflicts.
handlers
Glob patterns or directory paths to scan for handler exports. Used by eff deploy (without a file argument) to auto-discover all handlers.
handlers: "src"handlers: ["src/**/*.ts", "lib/**/*.handler.ts"]If you pass a file directly to the CLI (eff deploy src/api.ts), only that file is deployed — regardless of this setting.
lambda
Default Lambda settings applied to all handlers. Individual handlers can override any of these.
lambda: { memory: 256, timeout: "30 seconds", runtime: "nodejs24.x",}| Option | Default | Why |
|---|---|---|
memory | 256 | Enough for most API handlers and stream processors. AWS allocates CPU proportionally — more memory means more CPU. |
timeout | "30 seconds" | Covers typical API calls and background tasks. AWS maximum is 15 minutes. |
runtime | "nodejs24.x" | Latest Node.js LTS available in Lambda. Faster cold starts and better performance than older versions. |
Architecture
All Lambdas run on ARM64 (AWS Graviton2) by default. Graviton2 is ~20% cheaper than x86_64 and offers better price-performance for most Node.js workloads. This is not configurable — there’s no reason to use x86 for new Lambda functions.
Full Example
import { defineConfig } from "effortless-aws";
export default defineConfig({ name: "my-service", region: "eu-central-1", stage: "dev", handlers: ["src/**/*.ts"], lambda: { memory: 256, timeout: "30 seconds", runtime: "nodejs24.x", },});Per-handler Overrides
Every Lambda-backed handler accepts per-Lambda overrides (memory, timeout, permissions, logLevel) via .setup({...}). Pass an options object to .setup() directly for settings-only, or add it as a second argument after a setup factory function.
import { defineApi } from "effortless-aws";
export const processImage = defineApi({ basePath: "/images" }) .setup({ memory: 1024, // needs more memory for image processing timeout: "2m", // 2 minutes permissions: ["s3:GetObject", "s3:PutObject"], }) .post({ path: "/resize" }, async ({ req }) => { // ... });If you also need cold-start init, pass both a factory and settings:
.setup( async ({ deps }) => ({ bucket: deps.images }), { memory: 1024, timeout: "2m" },)memory and timeout
Override the project defaults for a specific handler. Timeout accepts a Duration — a plain number of seconds or a string like "30s", "2m", "1h".
permissions
Additional IAM permissions for the Lambda’s execution role. Use the service:action shorthand:
.setup({ permissions: ["s3:GetObject", "s3:PutObject", "ses:SendEmail"],})These are added on top of any permissions Effortless manages automatically (e.g., DynamoDB access for deps, SSM access for config).
logLevel
Controls the verbosity of structured logs emitted to CloudWatch. Defaults to "info" for defineApi, defineTable, and defineQueue.
| Level | What gets logged |
|---|---|
"error" | Only errors (console.error) |
"info" | Errors + execution summary (handler, type, duration) |
"debug" | Info + input/output args (truncated) |
.setup({ logLevel: "debug" }) // log everything including input/outputDeveloper console.* calls are also filtered by this level — console.debug() is suppressed at "info", and console.log()/console.info() are suppressed at "error". console.error and console.warn always pass through.