Skip to content
Get Started for Free

Local Development

This guide walks you through starting LocalStack and deploying a serverless API consisting of a Lambda function and a DynamoDB table. You will perform the entire deployment on your local machine without an AWS account.

A successful deployment results in a:

  • Serverless API: A Lambda function with a configured function URL.
  • Persistence Layer: A DynamoDB table for message storage.
  • Local Cloud Environment: A fully functional local sandbox that emulates AWS services.

Choose your preferred deployment method: Terraform or AWS CLI.

If you haven’t installed LocalStack yet, follow the installation guide to get started.

Start LocalStack:

Terminal window
lstk start

The first run triggers a browser-based authentication flow. After authentication, the CLI pulls the LocalStack image and initializes the container.

When the container is ready, you will see the following logs:

✔︎ LocalStack ready (containerId: 400b3e61f3c6)
• Endpoint: localhost.localstack.cloud:4566
• Web app: https://app.localstack.cloud

You can deploy the Lambda function and DynamoDB table using either our AWS CLI wrapper awslocal or our Terraform wrapper tflocal. These tools automatically route AWS API calls to your LocalStack container, so you do not need AWS account credentials for this guide.

  1. Install the awslocal wrapper:

    Terminal window
    pip install awscli-local
  2. Create the Lambda function source. Execute the following to create a project directory, a function file and a Python handler:

    Terminal window
    mkdir -p /tmp/localstack-demo
    cat > /tmp/localstack-demo/handler.py << 'EOF'
    import json, boto3, os, uuid
    def handler(event, context):
    table = boto3.resource('dynamodb').Table(os.environ['TABLE_NAME'])
    method = event.get('requestContext', {}).get('http', {}).get('method', 'GET')
    if method == 'POST':
    item = {'id': str(uuid.uuid4()), **json.loads(event.get('body', '{}'))}
    table.put_item(Item=item)
    return {'statusCode': 200, 'body': json.dumps(item)}
    result = table.scan()
    return {'statusCode': 200, 'body': json.dumps(result['Items'])}
    EOF
    cd /tmp/localstack-demo && zip handler.zip handler.py
  3. Create the DynamoDB table:

    Terminal window
    awslocal dynamodb create-table \
    --table-name Messages \
    --attribute-definitions AttributeName=id,AttributeType=S \
    --key-schema AttributeName=id,KeyType=HASH \
    --billing-mode PAY_PER_REQUEST
  4. Deploy the Lambda function:

    Terminal window
    awslocal lambda create-function \
    --function-name messages-api \
    --runtime python3.12 \
    --handler handler.handler \
    --zip-file fileb:///tmp/localstack-demo/handler.zip \
    --role arn:aws:iam::000000000000:role/lambda-role \
    --environment Variables={TABLE_NAME=Messages}
    awslocal lambda wait function-active --function-name messages-api
  5. Configure a function URL and retrieve the endpoint:

    Terminal window
    awslocal lambda create-function-url-config \
    --function-name messages-api \
    --auth-type NONE
    LAMBDA_URL=$(awslocal lambda list-function-url-configs \
    --function-name messages-api \
    --query 'FunctionUrlConfigs[0].FunctionUrl' \
    --output text)
    echo $LAMBDA_URL

Send a POST request to store a message in the locally emulated DynamoDB table:

Terminal window
curl -X POST "$LAMBDA_URL" \
-H "Content-Type: application/json" \
-d '{"message": "Hello, LocalStack!"}'

You will get back a response:

Output
{ "id": "3e1b5cae-4386-447b-8567-f0615fdb0fff", "message": "Hello, LocalStack!" }

Retrieve all your messages:

Terminal window
curl "$LAMBDA_URL"

The Lambda function executes within the local environment and interacts with the locally emulated DynamoDB service. Because no actual cloud resources are created, you won’t incur any real AWS cloud costs or infrastructure changes.

View the state of your local infrastructure via the LocalStack Web Application. Navigate to the Resource Browser to inspect your Lambda functions and DynamoDB tables in real-time.

Inspect Resources using LocalStack Web Application

Stop your LocalStack container to remove all emulated resources. LocalStack is ephemeral by default; stopping the instance clears the state.

Terminal window
lstk stop

To persist resource state, like S3 buckets or DynamoDB tables, across restarts, check out our state management tools.

Remove the local files you created in this guide:

Terminal window
rm -rf /tmp/localstack-demo

You have successfully deployed and tested a serverless API on your local workstation. Proceed to the CI/CD guide to learn how to integrate LocalStack into your automated continuous integration (CI) pipelines across a wide range of providers and platforms.

Was this page helpful?