# runl

> Run AWS Lambda functions locally

Latest version **1.3.1** (published 2026-03-27) · MIT license · 0 weekly downloads

## Install

```sh
npm install runl
pnpm add runl
yarn add runl
bun add runl
```

Provides the command `runl`.

## Health

**Score 65/100 (B)** — status: stable.

Positive: has types; esm support; no vulnerabilities; has provenance; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.3.1 |
| Published | 2026-03-27 |
| First published | 2022-03-01 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=18.0.0 |
| Dependencies | 0 |
| Unpacked size | 67.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 3 |
| Author | Janno Rothfos |
| Maintainers | janro |
| Keywords | aws, amazon, dev-server, lambda, local |

## Links

- npm: https://www.npmjs.com/package/runl
- Repository: https://github.com/janro1/runl
- Homepage: https://github.com/janro1/runl#readme
- Issues: https://github.com/janro1/runl/issues
- npm.io page: https://npm.io/package/runl

## Alternatives

- [@opentelemetry/exporter-zipkin](https://npm.io/package/@opentelemetry/exporter-zipkin.md) — 14.8M weekly downloads
- [pusher-js](https://npm.io/package/pusher-js.md) — 2.0M weekly downloads
- [browserify](https://npm.io/package/browserify.md) — 1.7M weekly downloads
- [sqs-consumer](https://npm.io/package/sqs-consumer.md) — 1.7M weekly downloads
- [@sanity/eventsource](https://npm.io/package/@sanity/eventsource.md) — 930.8K weekly downloads

## Recent versions

- 1.3.1 (latest) — 2026-03-27
- 1.3.0 — 2026-03-25
- 1.2.0 — 2023-12-01
- 1.1.0 — 2023-11-30
- 0.8.2 — 2023-11-29
- 0.8.1 — 2023-01-12
- 0.8.0 — 2023-01-12
- 0.7.0 — 2023-01-03
- 0.6.0 — 2022-06-07
- 0.5.2 — 2022-04-08
- 0.5.1 — 2022-03-30
- 0.5.0 — 2022-03-18
- 0.4.0 — 2022-03-18
- 0.3.5 — 2022-03-10
- 0.3.4 — 2022-03-09
- … 8 more at https://npm.io/package/runl/versions

## README

# RunL

**Run** AWS **L**ambda functions locally in node.

The main focus of this project is to enable you to use your functions locally, either in a dev-server or for testing, without any adjustments needed.

With a variety of alternatives available, why choose this library?

It's lightweight and comes with zero runtime dependencies. Moreover, it runs your lambda functions as isolated as possible, executing each lambda in a separate child process.

## How does it work?

Instead of loading the lambda handler directly into the current node process,
`RunL` forks a child process in which the handler is executed. To execute the
handler the child process requires the handler code, executes it and passes the
result back to the parent process.

Why so complicated?  
Other libraries, which repeatedly re-import lambda code in the same node process, encounter an issue where residual memory from each import is not fully cleared by the garbage collector. This results in memory leaks. Consequently, when running numerous tests locally or doing a lot of requests, these memory leaks can cause the development server to eventually cease functioning.

Unfortunately, this scenario is not merely theoretical; in fact, it was the primary motivation behind the creation of this library.

## Modes

RunL comes with two execution modes, `Ephemeral` and `Persistent`. `Ephemeral`
always forks a new child process, executes the handler within this process and
passes the result to the parent process.

This has the advantage that every request runs totally isolated from every other
request. The disadvantage is, that the lambda handler code must always be newly
required inside the child process. This can take a few seconds if the handler is
several megabytes in size.

### How to use `Ephemeral` mode

```
const { Lambda } = require('runl');

const lambda = new Lambda({
  mode: 'Ephemeral',
  lambdaPath: __dirname + '/handler/example-handler.js',
  environment: {
    BASE_URL: '/'
  }
});

lambda.execute({ path: '/index.html' });
```

The `Persistent` mode in contrast creates a long running fork that is reused for
every invocation. The advantage is that the handler code must _not_ be newly
required for every request, which can drastically reduce the request times in
your dev server.

### How to use `Persistent` mode

```
import { APIGatewayProxyResult } from 'aws-lambda';
import { Lambda, LambdaMode } from 'runl';

const lambda = new Lambda({
  mode: LambdaMode.Persistent,
  lambdaPath: __dirname + '/handler/example-handler.js'
});

const result = lambda.execute<APIGatewayProxyResult>();

// you can manually stop the child process
// otherwise the child process lives
// until the parent process is terminated
lambda.stop();
```

## Options

The `Lambda` constructor accepts the following options:

required:

- **lambdaPath**: absolute path to the lambda handler.

optional:

- **environment**: environment variables accessible in the lambda handler.

- **lambdaHandler**: the name of lambda handler, defaults to **handler**.

- **lambdaTimeout**: maximum execution time for the lambda, defaults to
  **30.000ms**.

- **autoReload**: if true, the lambda handler is automatically updated every
  time the file associated with lambdaPath is changed. Defaults to **false**.

- **debugPort**: when node is started with the debug flag
  `(--inspect or NODE_OPTIONS="--inspect")` and a **debugPort** is specified,
  the forked process will listen on this port for debug messages.

The `execute` method:

- **event**: The
  [APIGatewayProxyEvent](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format)
  that is passed to the lambda handler.


## CLI
You can also use the CLI to run a lambda function from a file.

| CLI Options | |
| --- | ------------- |
| -t, --timeout | Maximal execution time in ms |
| -e, --env  | Environment variables, either a JSON object or file path |
| -o, --event  | The event object passed to the lambda function, either a JSON object or file path   |
| -h, --handler  | The name of lambda handler, defaults to: handler    |

#### Examples:
```
# passing environment variables 
runl -e '{"LOG_LEVEL": "DEBUG"}' ./index.cjs

# specify event data and milliseconds until lambda timeout
runl -o '{"action": "delete"}' -t 1000 ./index.cjs
```

---
_Source: https://npm.io/package/runl · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
