Open-source project
dherault/serverless-offline avatar
dherault/serverless-offline

serverless-offline: emulating AWS Lambda and API Gateway on your machine

Emulate AWS λ and API Gateway locally when developing your Serverless project

5,262 stars811 forksJavaScriptMIT

At a glance

What is it?
serverless-offline is a Serverless Framework plugin that starts a local HTTP server mimicking API Gateway and invokes your handlers, so you can develop without deploying. It covers five runtimes and many Gateway features, but it is not a full AWS emulator.
Who is it for?
Adopt serverless-offline if your project is already described by a serverless.yml, your handlers are plain functions in Node.js, Python, Ruby, Go or Java, and you want to iterate on routes, authorizers and Velocity templates without deploying. Do not adopt it if you need real message queues, real DynamoDB or IAM enforcement, because the README lists SQS, SNS and SSM only as search terms, not as emulated services; LocalStack or a deployed dev stage is the right tool there.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 24 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem serverless-offline solves, and who hits it

The deploy loop is the cost. A change to a route handler in a Serverless Framework project normally means packaging, uploading and waiting for CloudFormation before you can send a request. serverless-offline cuts that loop by starting an HTTP server on your machine that handles the request lifecycle the way API Gateway does and then invokes your handler. The README describes it as emulating AWS Lambda and API Gateway "to speed up your development cycles".

The target user is narrow and identifiable: someone whose service is already described by a serverless.yml, who has handlers in Node.js, Python, Ruby, Go or Java (the README adds Kotlin, Groovy and Scala under the Java runtimes), and who wants route-level feedback while editing. It is not aimed at people who have not yet chosen a deployment model, and it is not a substitute for integration testing against real AWS services. The plugin's author is explicit about the maintenance model: "This plugin is updated by its users, I just do maintenance and ensure that PRs are relevant to the community." That sentence tells you what to expect from feature requests.

How the local emulation actually runs

The plugin is a Serverless Framework plugin, declared under the plugins key at the root of serverless.yml. When you run sls offline, it starts an HTTP server (localhost:3000 by default) and a separate Lambda HTTP port (3002 by default) for direct invocation. Requests hitting the HTTP port go through a path that mirrors API Gateway: route matching, authorizers, integrations, response parameters and Velocity templates, before the handler is invoked.

The README lists lazy loading of handler files as a feature, which matters because a project with many functions does not pay to load all of them at startup. The runtime set spans Node.js, Python, Ruby, Go and Java, and the README claims support for integrations, authorizers, proxies, timeouts, responseParameters, HTTPS and CORS. Two ports rather than one is the structural detail worth internalising: the HTTP port is the API Gateway stand-in, and the Lambda port exists so you can invoke a single function without constructing an HTTP request. The README also documents a process.env.IS_OFFLINE variable, which is the conventional way for handler code to branch between local and deployed behaviour.

Installing serverless-offline and running your first local request

Installation is a dev dependency plus one entry in serverless.yml. The README gives the npm command and notes that the plugins section must be at root level in serverless.yml:

bash
npm install serverless-offline --save-dev

Then add the plugin entry. If your serverless.yml has no plugins section, you create one; the README's example is exactly this shape, and it must sit at the root of the file rather than nested under provider or custom:

yaml
plugins:
  - serverless-offline

You can confirm the plugin registered by asking the Serverless CLI for verbose output. The README states the console should then list Offline among the available plugins:

bash
serverless --verbose

From the project root, start the emulator. Both spellings are documented and equivalent:

bash
sls offline

With defaults, your routes answer on http://localhost:3000 and the stage is prepended to the path. To see every option your installed version accepts, including ports, CORS and authorizer switches, run the help command the README points at:

bash
sls offline --help

The option list in the README includes host (default localhost), httpPort (default 3000), lambdaPort (default 3002), prefix for adding a path segment in front of every route, and noPrependStageInUrl for dropping the stage from the URL.

What the emulator does not cover

The README's own feature list is the boundary. It names Lambda runtimes, Velocity templates, lazy loading, integrations, authorizers, proxies, timeouts, responseParameters, HTTPS and CORS. It does not claim to emulate SQS, SNS, DynamoDB, S3 or IAM. People search for "serverless offline sqs", "serverless offline sns" and "serverless offline ssm", which suggests demand, but those services are not in the documented feature set, so a handler that publishes to a queue or reads a parameter store value still needs a real endpoint, a mock, or a different tool.

A second limitation is simulation fidelity. The README has a section titled "Simulation quality", which is an admission that the local path is an approximation of API Gateway rather than the same code. Velocity templates are the clearest example: the README documents "Velocity nuances", meaning template behaviour locally can differ from the deployed gateway. If your service leans on template edge cases, test them in a deployed stage before trusting the local result.

A third constraint is the runtime you develop on. The plugin is JavaScript and ships as an ES module ("type": "module" in package.json), and it is a peer of the Serverless Framework, so Node version compatibility is a live concern. Searches for "serverless offline node 24" and "serverless offline node 20" reflect that; the README does not publish a compatibility matrix, so the version you can use is the one your installed Serverless Framework and Node combination accepts.

serverless-offline compared with LocalStack

The two tools sit at different layers. serverless-offline reads your serverless.yml, starts a local HTTP server that imitates API Gateway, and invokes your handler functions in their native runtimes. It is a plugin inside the Serverless Framework workflow, and it knows about your routes, your authorizers and your templates because it parses the same configuration you deploy.

LocalStack takes the other approach: it emulates AWS services themselves behind local endpoints, so your code talks to a mock SQS, S3 or DynamoDB rather than to the real thing. That is the difference that decides the choice. If your problem is "I want to hit my endpoint without deploying", serverless-offline is the smaller, more direct answer. If your problem is "my handler needs a queue and a table to do anything useful", you need service emulation, and serverless-offline does not provide it. The two can be combined, but that combination is not described in this README.

There is a middle option worth naming: deploying to a personal dev stage. It is slower per iteration and costs money, but it is the only path that exercises real IAM, real service limits and real API Gateway behaviour.

Maintenance, licensing and the cost of upgrading

The repository is not archived, and the last push was on 2026-09-06, the same day as the v14.8.2 release. The two releases before it were v14.8.1 on 2026-09-04 and v14.8.0 on 2026-08-07. That is a steady patch cadence, and the versioning is semantic: v14.8.2 is a patch on the 14.8 line.

The licence is MIT, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. This is a permissive licence with no copyleft obligation on your own code. That is a statement about the licence text, not legal advice for your situation.

Upgrade cost is where this plugin deserves attention. It is a peer dependency of the Serverless Framework, so a major Serverless release can force a major plugin release, and the plugin's own major versions have historically tracked that. The changelog lives in CHANGELOG.md at the repository root and is generated by auto-changelog during the version script, so the file is the authoritative record of what changed between releases. Before bumping, read the entries between your current version and the target rather than trusting the release number alone. The package also declares a second export path, "./lambda": "./src/lambda/index.js", alongside the main entry, which means code that imports the Lambda helper directly is coupled to that path staying stable.

Editorial conclusion

Adopt serverless-offline if your project is already described by a serverless.yml, your handlers are plain functions in Node.js, Python, Ruby, Go or Java, and you want to iterate on routes, authorizers and Velocity templates without deploying. Do not adopt it if you need real message queues, real DynamoDB or IAM enforcement, because the README lists SQS, SNS and SSM only as search terms, not as emulated services; LocalStack or a deployed dev stage is the right tool there. Before committing, verify what your own service depends on: run sls offline --help to see the flags your version exposes, check whether your handlers rely on layers or Docker (both are documented, with layersDir and dockerHost options), and confirm whether the stage prefix in your URLs matches your deployed routes or whether you need noPrependStageInUrl. The plugin's own README states that it is "updated by its users", so treat the issue tracker as the place where gaps get closed rather than a promise of coverage.

Frequently asked questions

What is serverless-offline?

It is a Serverless Framework plugin that emulates AWS Lambda and API Gateway on your local machine. It starts an HTTP server that handles the request lifecycle like API Gateway and then invokes your handlers, so you can develop without deploying.

How does serverless-offline compare with LocalStack?

serverless-offline emulates API Gateway and Lambda by reading your serverless.yml and invoking your handlers locally. LocalStack emulates AWS services behind local endpoints. The README does not document SQS, SNS or DynamoDB emulation, so a handler that needs those services is outside this plugin's scope.

How do I debug serverless-offline in VS Code?

The README has a section titled Debug process, which is where the documented debugging setup lives. It does not describe a VS Code launch configuration in the parts of the README available here, so treat that section as the starting point rather than assuming a ready-made config exists.

Official sources

  1. dherault/serverless-offline on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dherault-serverless-offline.svg)](https://hysenlabs.com/projects/dherault-serverless-offline)