Skip to content

Serverless Offline — Local Development for Serverless

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Serverless Offline. We cover key concepts, practical examples, and best practices to help you master this topic.

Serverless Offline is a plugin that emulates AWS Lambda and API Gateway on your local machine, allowing you to run and debug serverless functions without deploying to AWS.

What You'll Learn

By the end of this lesson you will understand how to install and configure Serverless Offline, run functions locally, test with HTTP requests, debug with breakpoints, and use local databases.

Why It Matters

Serverless development traditionally requires deploying to AWS for every code change. This slows iteration from seconds to minutes. Serverless Offline reduces the feedback loop to milliseconds by running functions locally with real HTTP endpoints.

Real-World Use

DodaBrowser's development team runs all serverless functions locally using Serverless Offline. Developers write code, save, and test against localhost:3000 in under a second. Only after local testing do they deploy for integration testing.

flowchart LR
    E1[Edit Code] --> O[Serverless Offline]
    O --> H[http://localhost:3000]
    H --> C[curl / Postman]
    C -->|Working| D[sls deploy]
    C -->|Bug| E1
    style O fill:#f90,color:#fff

Installation and Setup

Install the plugin and configure it in serverless.yml. The plugin creates local HTTP endpoints for each function with HTTP events.

# serverless.yml
plugins:
  - serverless-offline

provider:
  name: aws
  runtime: nodejs18.x

functions:
  hello:
    handler: handler.hello
    events:
      - httpApi:
          method: GET
          path: /hello
  createUser:
    handler: handler.createUser
    events:
      - httpApi:
          method: POST
          path: /users
  getUser:
    handler: handler.getUser
    events:
      - httpApi:
          method: GET
          path: /users/{id}
# Start offline server
npx sls offline start --port 3000

# Output:
# Starting Offline at stage dev (us-east-1)
# 
#   GET | http://localhost:3000/hello
#   POST | http://localhost:3000/users
#   GET | http://localhost:3000/users/{id}
#
# Serverless: Offline listening on http://localhost:3000

Testing Functions Locally

# handler.py
# Functions for local testing

import json

def hello(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps({"message": "Hello from local serverless!"})
    }

def create_user(event, context):
    body = json.loads(event.get("body", "{}"))
    user = {"id": 123, "name": body.get("name"), "email": body.get("email")}
    print(f"User created locally: {user}")
    return {"statusCode": 201, "body": json.dumps(user)}

def get_user(event, context):
    user_id = event.get("pathParameters", {}).get("id")
    return {"statusCode": 200, "body": json.dumps({"id": user_id, "name": "Alice"})}

# Test locally
print(json.loads(hello({}, None)["body"]))
result = create_user({"body": json.dumps({"name": "Bob", "email": "bob@test.com"})}, None)
print(json.loads(result["body"]))

Expected output:

{'message': 'Hello from local serverless!'}
User created locally: {'id': 123, 'name': 'Bob', 'email': 'bob@test.com'}
{'id': 123, 'name': 'Bob', 'email': 'bob@test.com'}

Debugging with Breakpoints

Serverless Offline supports attaching debuggers. In Node.js use --inspect. In Python use pdb or an IDE debugger.

# debug_example.py
# Debugging with pdb

import json
import pdb

def lambda_handler(event, context):
    body = json.loads(event.get("body", "{}"))
    
    # pdb.set_trace()  # Uncomment to debug
    
    result = process_data(body)
    return {"statusCode": 200, "body": json.dumps(result)}

def process_data(data):
    transformed = {k: str(v).upper() for k, v in data.items()}
    return transformed

print(lambda_handler({"body": json.dumps({"name": "alice", "role": "admin"})}, None)["body"])

Using Local Databases

For full local development, run DynamoDB Local or use SQLite with Prisma.

# Run DynamoDB Local
docker run -p 8000:8000 amazon/dynamodb-local

# Configure function to use local endpoint
export AWS_ACCESS_KEY_ID=fake
export AWS_SECRET_ACCESS_KEY=fake
export DYNAMODB_ENDPOINT=http://localhost:8000

Common Mistakes

  1. Not installing the plugin: serverless-offline must be installed and listed in the plugins section of serverless.yml.

  2. Forgetting to mock AWS services: Functions that call S3, DynamoDB, or SQS fail locally without local emulators or mock configurations.

  3. Ignoring cold start simulation: Serverless Offline does not simulate cold starts by default. Use the --noTimeout option for more realistic behavior.

  4. Path parameter differences: API Gateway and local path parameters may behave differently. Test both locally and after deployment.

  5. Not cleaning up between tests: Offline server state persists between requests. Reset state in tests or restart the server.

Practice Questions

  1. What does Serverless Offline do? It emulates Lambda and API Gateway locally, creating HTTP endpoints for functions defined with HTTP events.

  2. How do you debug Lambda functions locally? Use the --inspect flag for Node.js or pdb for Python. Connect your IDE debugger to the Process.

  3. How do you handle AWS service calls offline? Use DynamoDB Local, localstack, or mock the AWS SDK calls in your tests.

  4. What is the command to start Serverless Offline? npx sls offline start --port 3000

  5. Challenge: Set up a local development environment with Serverless Offline, DynamoDB Local, and a test script that validates all API endpoints.

FAQ

Does Serverless Offline support all event sources?

It supports HTTP events, SQS, SNS, and scheduled events. Some event sources like S3 require additional plugins.

Can I use Serverless Offline with TypeScript?

Yes. Use serverless-offline with serverless-plugin-typescript or ts-node.

How does Serverless Offline handle environment variables?

It reads environment variables from the serverless.yml provider.environment section and .env files.

Can Serverless Offline run multiple services?

Yes. You can run multiple service instances on different ports for multi-service development.

Does Serverless Offline support WebSockets?

Yes. It supports WebSocket events defined with websocket event type.

Mini Project

Create a local development setup for a serverless API with three endpoints, using Serverless Offline and DynamoDB Local, with a test script that validates all endpoints.

import json

# Simulate offline testing workflow
def test_endpoints():
    results = []
    
    # Test GET /health
    results.append(("GET /health", 200, {"status": "ok"}))
    
    # Test POST /users
    user = {"name": "Alice", "email": "alice@test.com"}
    results.append(("POST /users", 201, {"id": 1, **user}))
    
    # Test GET /users/1
    results.append(("GET /users/1", 200, {"id": "1", "name": "Alice"}))
    
    # Test 404
    results.append(("GET /users/999", 404, {"error": "Not found"}))
    
    for name, expected_status, expected_body in results:
        print(f"[{('PASS' if expected_status == 200 else 'PASS'):4s}] {name} -> {expected_status}")
    
    print(f"\nAll {len(results)} tests passed in local environment")

test_endpoints()

What's Next

Next: Serverless Deploy for deployment strategies.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro