Serverless Offline — Local Development for Serverless
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
Not installing the plugin:
serverless-offlinemust be installed and listed in the plugins section of serverless.yml.Forgetting to mock AWS services: Functions that call S3, DynamoDB, or SQS fail locally without local emulators or mock configurations.
Ignoring cold start simulation: Serverless Offline does not simulate cold starts by default. Use the --noTimeout option for more realistic behavior.
Path parameter differences: API Gateway and local path parameters may behave differently. Test both locally and after deployment.
Not cleaning up between tests: Offline server state persists between requests. Reset state in tests or restart the server.
Practice Questions
What does Serverless Offline do? It emulates Lambda and API Gateway locally, creating HTTP endpoints for functions defined with HTTP events.
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.
How do you handle AWS service calls offline? Use DynamoDB Local, localstack, or mock the AWS SDK calls in your tests.
What is the command to start Serverless Offline?
npx sls offline start --port 3000Challenge: Set up a local development environment with Serverless Offline, DynamoDB Local, and a test script that validates all API endpoints.
FAQ
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