Skip to content

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:

effortless.config.ts
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",
}
OptionDefaultWhy
memory256Enough 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

effortless.config.ts
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.

LevelWhat 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/output

Developer 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.