Logo Blog Newsletters

Supercharge Your AWS Lambda Development Workflow

Published on January 30, 2025
~ 6 min read
serverless
lambda
aws
Article cover

Introduction

Over the years, I've worked on numerous projects. Each was unique, but they all shared a common need: standards. A way to organize code, maintain quality, and make development smoother for everyone involved.

Years have passed, and those standards evolved into something I'm proud to share. This guide isn't about complex architectural patterns or deep AWS knowledge. It's about the small things that make our daily work with AWS Lambda better.

From organizing your repository to adding the right tools, I'll show you how I like to work with Node.js and AWS Lambda. These are practices I've been using for years, refined through real projects and real teams.

Let's make your Lambda development experience better, together.

Repository Structure

A well-organized repository is the foundation of any successful Lambda project. Let's look at a structure that has worked well for me across multiple projects:

AWS Lambda Repository Structure

Core Directories

  • /src
    :
    • Each function gets its own directory (e.g.,
      service-a
      ,
      service-b
      )
    • Functions contain their handler, tests, and configuration files
  • /infra
    :
    • /cdk
      : AWS CDK stacks
    • /sst
      : SST framework configurations
    • [insert your preferred Infrastructure as Code tool šŸ˜‰]

Function Structure

Inside each function directory:

ā””ā”€ā”€ service-a/post/
    ā”œā”€ā”€ event.json        # Test events
    ā”œā”€ā”€ handler.ts        # Main Lambda handler
    ā”œā”€ā”€ index.ts         # Function exports
    ā””ā”€ā”€ index.test.ts    # Unit tests

Environment Management

Rather than managing multiple

.env
files, I prefer using AWS SSM Parameter Store for environment variables. Here's why:

  1. Security: Values are encrypted at rest
  2. Version Control: Parameter history is maintained
  3. Access Control: Fine-grained IAM permissions
  4. Organization: Hierarchical structure using paths

This structure keeps things organized while maintaining flexibility for growth. Each piece has its place, making it easier for teams to navigate and maintain the codebase.

Code Quality Tools

Code quality isn't about personal preferences, it's about team productivity. Writing consistent, maintainable code across a team is hard. That's why I'm a big fan of automated code quality tools.

ESLint Configuration

ESLint is our code quality. It catches potential bugs, enforces best practices, and maintains consistent patterns across your Lambda functions.

I use ESLint to:

  • Catch common mistakes (unused variables, undefined references)
  • Enforce TypeScript best practices
  • Prevent deployment of
    console.log
    statements
  • Maintain consistent import ordering
  • Ensure proper error handling

Prettier Setup

While ESLint handles code quality, Prettier takes care of code formatting. It removes all the mental overhead of manually formatting code. No more discussions about:

  • Where to put spaces
  • When to break lines
  • How to format long function chains
  • Whether to use single or double quotes

Why They Work Together

ESLint and Prettier are like good cop, bad cop:

  • Prettier automatically formats your code
  • ESLint makes sure it's not just pretty, but also correct
  • They run on save and before commits
  • Your IDE shows errors and warnings in real-time

Note: All these tools are pre-configured in my repository template. Just clone and start coding, the setup is already done for you.

This combination means you can focus on solving problems instead of arguing about code style. The tools handle the rest.

Development Workflow

A solid development workflow catches issues early and keeps your codebase healthy. Here's how I structure my Lambda development process.

Git Hooks and Automation

I use Husky to automate quality checks at different git stages.

Pre-commit Hook

Before code is committed:

  • Lints modified files
  • Formats code with Prettier
  • Prevents commits with
    console.log

Commit Message Standards

Every commit message follows the Conventional Commits standard:

feat: add new user authentication
fix: resolve cold start issues
chore: update dependencies

This makes our git history readable and helps with automatic versioning.

Pre-push Hook

Before code is pushed:

  • Runs all tests
  • Ensures 80% code coverage
  • Builds the project to catch compilation issues

This workflow means:

  • No broken code reaches main branch
  • Every change is tested
  • Code style remains consistent
  • Git history stays clean and meaningful

The goal isn't to make development harder, it's to catch issues when they're cheapest to fix: during development.

Middleware and Utilities

Node.js Middy with AWS Lambda and AWS Lambda Powertools

When working with AWS Lambda, middleware and utilities can significantly enhance your development experience and the quality of your functions. Two powerful tools in this space are Middy and AWS Lambda Powertools.

Implementing Middy

Middy is a lightweight middleware engine for AWS Lambda. It allows you to wrap your Lambda functions with additional functionality, making them more robust and easier to manage.

Basic setup

Setting up Middy is straightforward. You import it, wrap your handler function, and then chain middleware as needed. This modular approach keeps your main handler clean and focused on business logic.

Common middleware

Middy offers a variety of pre-built middleware for common tasks:

  • httpJsonBodyParser
    : Automatically parses JSON in request bodies
  • httpEventNormalizer
    : Normalizes HTTP events for easier handling
  • httpErrorHandler
    : Provides consistent error responses
  • httpSecurityHeaders
    : Adds security headers to responses

Using these, you can quickly add robust functionality to your Lambda functions without cluttering your main code.

Custom middleware development

One of Middy's strengths is its extensibility. You can easily create custom middleware to encapsulate recurring logic across your functions. This might include authentication checks, input validation, or any other cross-cutting concerns specific to your application.

Some custom middleware I've built:

  • SSM Parameter Store integration: fetches parameters from SSM and injects them into the AWS Lambda environment variables
  • Secret Manager integration: retrieves secrets and makes them available to your function
  • Database integration: mostly for databases connection management
  • Feature flag middleware

AWS PowerTools

AWS Lambda Powertools is a suite of utilities designed to help implement best practices and increase developer velocity. Let's look at some of them.

Logging

Powertools provides structured logging out of the box. It includes features like log sampling and correlation IDs, making it easier to trace requests across distributed systems.

Tracing

The tracing utility integrates with AWS X-Ray, allowing you to visualize and analyze your application's behavior and performance.

Metrics

With Powertools' metrics utility, you can easily create and publish custom metrics to CloudWatch. This helps in monitoring your application's health and performance over time.

Best practices

Powertools encourages several best practices:

  • Structured logging for better searchability
  • Correlation IDs for request tracing
  • Cold start labeling to distinguish between cold and warm starts
  • Easy creation of custom metrics

By leveraging these tools, you can significantly improve the observability and maintainability of your Lambda functions. The goal is to spend more time on your business logic and less on boilerplate code.

Note: All these tools are pre-configured in my repository template. Just clone and start coding, the setup is already done for you. It demonstrates how these concepts come together in a real-world Lambda function setup.

Bundling and Optimization

CDK AWS Lambda Bundling Optimization

Efficient bundling and optimization are paramount (can I say this word without this article being labeled as AI generated? šŸ˜œ) for AWS Lambda functions. They help reduce cold start times, minimize costs, and improve overall performance.

Optimization Techniques

  • Code splitting: by separating your code into smaller, more manageable chunks, you can improve load times and reduce the overall bundle size. This is particularly useful for larger applications.

  • Dead code elimination: using tools like esbuild, we can automatically remove unused code from the final bundle. The

    --tree-shaking
    flag ensures that only the code that's actually used is included in the final package.

  • Dependencies management: Carefully manage your dependencies to keep your function lean. Only essential modules are included in the

    nodeModules
    array, ensuring that only necessary dependencies are bundled with the function.

By implementing these small optimization techniques, you can significantly improve the performance and efficiency of your AWS Lambda functions. The goal is to create lean, fast-executing functions that make the most of AWS Lambda's capabilities, and spend less of course šŸ˜‰

Conclusion

Developing AWS Lambda functions doesn't have to be a complex task. By implementing the practices we've discussed, from organizing your repository structure to optimizing your deployment, you can create more efficient, maintainable, and scalable serverless applications.

These practices have evolved from real-world experience and have proven their worth across numerous projects. They're not just theory and can significantly improve your Lambda development experience.

Here's the link to my GitHub repository: https://github.com/Depaa/aws-lambda-supercharge-template šŸ˜‰

If you enjoyed this article, please let me know in the comment section or send me a DM. I'm always happy to chat! āœŒļø

Thank you so much for reading! šŸ™ Keep an eye out for more AWS-related posts, and feel free to connect with me on LinkedIn šŸ‘‰ https://www.linkedin.com/in/matteo-depascale/.

References

Disclaimer: opinions expressed are solely my own and do not express the views or opinions of my employer.