AWSServerlessLocal DevelopmentDevOpsOpen SourceCloud CostsProductivityEmulationTesting

Floci Local AWS Development: Cut Costs, Ship Faster

Slash AWS dev costs and accelerate feedback loops. This guide shows how to set up Floci for robust local AWS development, comparing it to Localstack.

U

Umair · Senior Flutter Developer

March 22, 2026 · 11 min read

Every single Lambda change uploading to AWS for testing was costing me minutes and pennies. Those pennies add up, and the slow feedback loop drove me nuts. After enough frustration, I dug in. This is how I finally got fast, free Floci local AWS development working, completely transforming my local serverless workflow. Forget the cloud for dev; this is the way.

Why Your Wallet Hates Cloud-First Dev (And Why Floci Wins)

Honestly, developing directly against AWS for every little change is a trap. You get hit with:

  1. Slow Feedback Loops: Deploying a Lambda, even a tiny one, takes time. Waiting for logs, checking metrics, re-deploying. It kills flow.
  2. Hidden Costs: Those "free tier" allowances run out. Every SQS message, every S3 PutObject, every Lambda invocation adds up. Next thing you know, your personal dev account is racking up $50-$100 a month for stuff you shouldn't be paying for.
  3. Internet Dependency: What happens when your internet drops? Or you're on a flight? You're completely blocked from doing offline AWS testing. This is just bad for productivity.
  4. Complex Debugging: Debugging remote Lambda functions is painful. Local tools are always better for breakpoints and rapid iteration.

This is where Floci shines. It's a genuine Localstack alternative free solution, specifically built to handle core serverless services locally. You get your AWS local serverless environment running on your machine, no internet needed.

Here’s why Floci is a game-changer for me:

  • Zero AWS Costs: Develop all day, every day, without seeing a single charge on your bill. This alone helps reduce AWS dev costs significantly.
  • Instant Feedback: Invoke Lambdas, push SQS messages, store S3 objects locally with near-instant responses.
  • True Offline Capabilities: Build and test anywhere, anytime. Plane, train, remote cabin – doesn't matter.

Floci vs. Localstack: The Real Showdown for AWS Local Serverless

Everyone knows Localstack. It's the go-to for many, and for good reason: it’s powerful, supports a ton of services, and has a mature ecosystem. But here’s the thing — Localstack has a tiered pricing model. A lot of the advanced features you really want for local dev, like Kinesis or DynamoDB Streams, are locked behind their Pro subscription. For basic S3, Lambda, SQS, DynamoDB, the free version is okay, but it can still be a heavy Docker image.

Floci, on the other hand, is built differently. It's designed to be a lightweight, truly free, open-source emulator for common serverless components. It's not trying to emulate every single AWS service in excruciating detail. Instead, it focuses on the ones you use daily for serverless apps: Lambda, SQS, S3, DynamoDB, API Gateway, SNS.

Here’s my take:

  • Localstack (Free Tier): Good for basic S3/SQS/DynamoDB. Can be a bit slow to start, and the full power is behind a paywall.
  • Localstack (Pro Tier): If your company is paying, and you need a very broad, highly accurate emulation of many AWS services, it’s a strong contender. But it’s not your free solution.
  • Floci: This is my winner for individuals and small teams focused on AWS local serverless development who want to reduce AWS dev costs to zero. It's faster, lighter, and crucially, 100% free and open-source, forever. It nails the core services you need for everyday development, offering a fantastic Localstack alternative free that doesn't nickel and dime you. For pure offline AWS testing of serverless patterns, Floci is hard to beat.

Is Floci as feature-rich as Localstack Pro? No, not yet. But for 90% of what I do day-to-day with serverless, it's perfect. The emphasis on speed and being completely free makes it invaluable.

Getting Down with Floci: Your Local AWS Environment Setup

Setting up Floci is straightforward, mainly involving Docker. If you're building modern cloud apps, you probably already have Docker installed. If not, get it.

First, make sure Docker is running on your machine. Then, you just need to pull the image and run it. The beauty of Floci is its simplicity.

  1. Pull the Floci Docker Image: This command grabs the latest stable version of Floci.

    docker pull umgmd/floci:latest
    

    It's a relatively small image, so it should download quickly.

  2. Run Floci: Now, let's fire it up. We'll map ports so our local services can talk to Floci. I usually pick a consistent port like 4566 to mimic Localstack's default, just for muscle memory.

    docker run -d --rm \
      --name floci-dev-env \
      -p 4566:4566 \
      -p 4510:4510 \
      umgmd/floci:latest
    
    • -d: Runs the container in detached mode (background).
    • --rm: Automatically removes the container when it exits. Clean.
    • --name floci-dev-env: Gives it a memorable name.
    • -p 4566:4566: Maps the main Floci API port. This is where your AWS SDKs and CLI will connect.
    • -p 4510:4510: This is often used for specific services like API Gateway endpoints in some setups. Good to include.

    Once you run this, you'll have a local AWS emulator humming along. You can check its status with docker ps.

    docker ps
    

    You should see floci-dev-env listed and running.

  3. Configure Your AWS CLI/SDK: This is the crucial part for Floci local AWS development. You need to tell your AWS CLI and SDKs to talk to your local Floci instance instead of the real AWS cloud.

    For AWS CLI: You can export an environment variable or add --endpoint-url to every command. For quick dev, I prefer the export.

    # Set this in your shell config (.bashrc, .zshrc, etc.) or just run it per session
    export AWS_ENDPOINT_URL="http://localhost:4566"
    export AWS_ACCESS_KEY_ID="test" # Floci doesn't care about real credentials for local calls
    export AWS_SECRET_ACCESS_KEY="test"
    export AWS_DEFAULT_REGION="us-east-1" # Or whatever region you use
    

    Now, any aws command will automatically point to your local Floci instance. No more cloud billing for test commands!

    For AWS SDK (Node.js example): When initializing your AWS SDK clients, you explicitly tell them where to find the endpoint.

    const { SQSClient, SendMessageCommand } = require("@aws-sdk/client-sqs");
    const { LambdaClient, InvokeCommand } = require("@aws-sdk/client-lambda");
    const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
    const { S3Client } = require("@aws-sdk/client-s3");
    
    // Common configuration for local Floci
    const localAwsConfig = {
      endpoint: "http://localhost:4566",
      region: "us-east-1", // Must match your default region
      credentials: {
        accessKeyId: "test",
        secretAccessKey: "test",
      },
      // This is important for Floci with some services, like S3 paths
      forcePathStyle: true,
    };
    
    const sqsClient = new SQSClient(localAwsConfig);
    const lambdaClient = new LambdaClient(localAwsConfig);
    const dynamoDbClient = new DynamoDBClient(localAwsConfig);
    const s3Client = new S3Client(localAwsConfig);
    
    // Now you can use these clients to interact with Floci
    async function sendLocalSqsMessage() {
      try {
        const queueUrl = "http://localhost:4566/000000000000/my-local-queue"; // Floci often uses dummy account ID
        const command = new SendMessageCommand({
          QueueUrl: queueUrl,
          MessageBody: "Hello from local Floci!",
        });
        const response = await sqsClient.send(command);
        console.log("Local SQS message sent:", response);
      } catch (error) {
        console.error("Error sending local SQS message:", error);
      }
    }
    
    // Example usage:
    // sendLocalSqsMessage();
    

    Remember forcePathStyle: true for S3; it's a common requirement for local S3 emulators to work correctly with the SDK. This is critical if you're doing any local S3 interactions.

Integrating Floci: A Serverless Example (Node.js Lambda + SQS)

Let's build a quick example where a Lambda processes messages from an SQS queue, all running locally using Floci local AWS development. This pattern is super common.

Scenario: We have an SQS queue where messages are sent. A Lambda function is configured to process these messages.

Step 1: Create a Local SQS Queue With AWS_ENDPOINT_URL set, this is simple.

aws sqs create-queue --queue-name my-local-queue

You should get a response like:

{
    "QueueUrl": "http://localhost:4566/000000000000/my-local-queue"
}

Keep this QueueUrl handy. The 000000000000 is Floci's default dummy account ID.

Step 2: Write Your Local Lambda Function Create a file named my-local-lambda.js:

// my-local-lambda.js
const { SQSClient, SendMessageCommand } = require("@aws-sdk/client-sqs");
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3");

// IMPORTANT: Ensure your localAwsConfig is aligned with your Floci setup
const localAwsConfig = {
  endpoint: "http://localhost:4566",
  region: "us-east-1",
  credentials: {
    accessKeyId: "test",
    secretAccessKey: "test",
  },
  forcePathStyle: true, // Crucial for local S3
};

const sqsClient = new SQSClient(localAwsConfig);
const s3Client = new S3Client(localAwsConfig);

exports.handler = async (event) => {
  console.log("Received event:", JSON.stringify(event, null, 2));

  for (const record of event.Records) {
    const messageBody = record.body;
    console.log("Processing SQS message:", messageBody);

    try {
      // Simulate some processing, maybe saving to S3
      const bucketName = "my-local-bucket";
      const objectKey = `processed-messages/${Date.now()}.json`;
      const s3Command = new PutObjectCommand({
        Bucket: bucketName,
        Key: objectKey,
        Body: JSON.stringify({ originalMessage: messageBody, processedAt: new Date().toISOString() }),
        ContentType: "application/json",
      });
      await s3Client.send(s3Command);
      console.log(`Saved message to S3: s3://${bucketName}/${objectKey}`);

      // Optionally, send a follow-up message to another SQS queue
      // const anotherQueueUrl = "http://localhost:4566/000000000000/another-local-queue";
      // const followUpCommand = new SendMessageCommand({
      //   QueueUrl: anotherQueueUrl,
      //   MessageBody: `Processed: ${messageBody}`,
      // });
      // await sqsClient.send(followUpCommand);
      // console.log("Sent follow-up SQS message.");

    } catch (error) {
      console.error("Error processing message or interacting with local S3/SQS:", error);
      // Important for SQS: If you throw an error, SQS will re-deliver the message
      throw error;
    }
  }

  return {
    statusCode: 200,
    body: JSON.stringify('Messages processed successfully'),
  };
};

Make sure you have @aws-sdk/client-sqs and @aws-sdk/client-s3 installed (npm i @aws-sdk/client-sqs @aws-sdk/client-s3).

Step 3: Create a Local S3 Bucket (for the Lambda to use)

aws s3 mb s3://my-local-bucket

Step 4: Create and Deploy the Local Lambda Function to Floci This requires zipping your Lambda code.

# Create a zip file of your Lambda code
zip my-local-lambda.zip my-local-lambda.js

# Create the Lambda function in Floci
aws lambda create-function \
  --function-name my-local-processor \
  --runtime nodejs18.x \
  --handler my-local-lambda.handler \
  --zip-file fileb://my-local-lambda.zip \
  --role arn:aws:iam::000000000000:role/lambda-role # Floci doesn't validate IAM, a dummy ARN is fine

Step 5: Invoke the Lambda Function (simulating an SQS event) While Floci can configure event sources, for rapid offline AWS testing, it's often faster to manually craft an event.

# Create a sample SQS event payload (save as event.json)
cat << EOF > event.json
{
  "Records": [
    {
      "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
      "receiptHandle": "MessageReceiptHandle",
      "body": "{\"data\":\"Hello Floci! This is a test message.\"}",
      "attributes": {
        "ApproximateReceiveCount": "1",
        "SentTimestamp": "1523232000000",
        "SenderId": "AIDEXAMPLE",
        "ApproximateFirstReceiveTimestamp": "1523232000001"
      },
      "messageAttributes": {},
      "md5OfBody": "098f6bcd4621d373cade4e832627b4f6",
      "eventSource": "aws:sqs",
      "eventSourceARN": "arn:aws:sqs:us-east-1:000000000000:my-local-queue",
      "awsRegion": "us-east-1"
    }
  ]
}
EOF

# Invoke the local Lambda
aws lambda invoke \
  --function-name my-local-processor \
  --payload file://event.json \
  output.json

Check output.json for the Lambda's response, and importantly, check your Docker logs for floci-dev-env to see the console.log output from your Lambda.

docker logs floci-dev-env

You should see your Lambda's console.log messages indicating it processed the SQS message and saved to S3. To verify the S3 object:

aws s3 ls s3://my-local-bucket/processed-messages/

This whole workflow lets you rapidly iterate on your Lambda code and AWS local serverless interactions without hitting the cloud even once. It's a massive win for feedback speed and reducing reduce AWS dev costs.

What I Got Wrong First

I've wasted hours on silly things that are obvious in hindsight. Here are some of the common pitfalls I hit with local AWS emulation, especially with a tool like Floci:

  • Endpoint URL Mismatch:

    • Error: Could not connect to the endpoint URL: "http://localhost:4566/" or Unknown endpoint: http://localhost:4566.
    • My Mistake: Forgetting that my Docker container wasn't actually running, or the port mapping was wrong. Sometimes, I'd forget to set AWS_ENDPOINT_URL for the CLI, or hardcode the wrong port in my SDK.
    • The Fix: Always check docker ps first. Make sure your Floci container (floci-dev-env in our case) is up and running. Double-check your -p flag in docker run. For SDKs, ensure the endpoint URL in localAwsConfig is http://localhost:4566 (or whatever port you chose). Remember, localhost refers to your host machine's localhost, which is exposed to the Docker container via port mapping.
  • IAM Credentials & Permissions:

    • Error: The request signature we calculated does not match the signature you provided. or AccessDeniedException.
    • My Mistake: Overthinking local IAM. I'd try to pass real AWS credentials or create complex local IAM setups.
    • The Fix: Floci (and most local emulators) generally doesn't care about real AWS credentials for local calls. For the AWS CLI and SDKs, providing any non-empty AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY (like "test"/"test" as I showed) is usually sufficient for it to attempt signing, which Floci then ignores. For Lambda create-function, the role ARN can be a dummy value; Floci doesn't validate it. The key insight here is that you're operating in a mock environment, so security credentials aren't enforced the same way.
  • S3 Path Style vs. Virtual Host Style:

    • Error: S3 operations fail, sometimes with obscure DNS errors or bucket not found.
    • My Mistake: Not setting forcePathStyle: true in the AWS SDK for S3 operations. AWS by default tries to use virtual host addressing (e.g., my-bucket.s3.us-east-1.amazonaws.com), but local emulators often expect path-style (e.g., localhost:4566/my-bucket).
    • The Fix: Always add forcePathStyle: true to your S3Client configuration when working with Floci. This ensures the SDK formats requests in a way local emulators understand.
  • "My Lambda logs aren't showing up!"

    • My Mistake: Looking for Lambda logs in CloudWatch (which doesn't exist locally) or expecting them to just print to my terminal.
    • The Fix: Lambda logs go to the Floci Docker container's standard output. Use docker logs floci-dev-env to see your console.log statements from your local Lambda invocations. This is how you debug your local functions.

Anyway, these little gotchas cost time. Knowing them upfront will save you pain.

Beyond the Basics: Quick Wins & Gotchas

  • Cleaning Your Local State: Floci, by default, is ephemeral if you use --rm. If you want to explicitly clear all local data (SQS messages, S3 objects, DynamoDB tables), just stop and remove the container:
    docker stop floci-dev-env
    # (if not using --rm, then also)
    docker rm floci-dev-env
    
    Then restart it with the docker run command. It's a fresh slate every time, which is great for repeatable tests.
  • Persistent Data (if you need it): If you do need data to persist across container restarts (e.g., for long-running dev tasks where you don't want to re-seed DynamoDB), you can use Docker volumes.
    docker run -d --rm \
      --name floci-dev-env \
      -p 4566:4566 \
      -p 4510:4510 \
      -v floci-data:/var/lib/floci # This creates a named volume
      umgmd/floci:latest
    
    I honestly don't use this much for Floci because I prefer a clean state for most offline AWS testing, but it's there if you need it.
  • Supported Services: Floci focuses on common serverless services: Lambda, SQS, SNS, S3, DynamoDB, API Gateway, CloudWatch Events (for scheduling). Don't expect it to emulate things like ECS, RDS, Glue, or Kinesis Streams yet. For those, you'd likely still need cloud or a more comprehensive (and potentially paid) tool. This is a design choice that keeps Floci lean and fast.

FAQs

Does Floci support all AWS services?

No. Floci focuses on core serverless services like Lambda, SQS, SNS, S3, DynamoDB, and API Gateway. It's optimized for lightweight, fast emulation of these common services, not every single AWS offering.

How do I make my existing AWS SDK code work with Floci?

You need to explicitly configure your AWS SDK clients (e.g., SQSClient, S3Client) with endpoint: "http://localhost:4566", region: "us-east-1", and dummy credentials. For S3, also add forcePathStyle: true.

Is Floci suitable for CI/CD pipelines?

Yes, absolutely. Because it's Docker-based and truly open-source, you can spin up Floci containers as part of your CI/CD pipeline to run integration tests against a local AWS environment, saving costs and speeding up test execution.

Look, this isn't rocket science, but getting your local Floci local AWS development environment humming smoothly makes a huge difference. For offline AWS testing and serious reduce AWS dev costs on serverless applications, Floci is an underrated gem. It's fast, free, and gets the job done for 90% of what you need day-to-day. Stop paying AWS for your dev cycles and get your feedback loops tight. Go spin up Floci; your wallet and your sanity will thank you.

Need a Flutter developer?

I build production apps from scratch — iOS, Android, AI features, payments. Let's talk.

Book Free Call →