Article cover image

Designing Composable Software Architecture

  • Claudio
    Claudio
    Director of Engineering
  • TJ
    TJ
    Creative Director
  • Hackmamba
    Hackmamba
    Marketing

For both new and existing products with an active customer base or those looking to onboard new customers, dealing with a surge of requests or feedback is inevitable. Common requests like, “Can you make the navigation menu collapsible to save screen space?”, “It would be useful if the app could sync with Google Calendar” and “Can you add more themes and customization options for user profiles?” often determine what to prioritize when building new features or extending existing products.

Traditional monolith systems still struggle to address the surge of requests effectively despite having access to tools like Canny and UserVoice that help teams collect, organize, and prioritize feature requests. These challenges have driven businesses to turn to composable architecture — an approach that breaks down complex systems into autonomous components that can be independently built, tested, and deployed.

This article will cover the use of composable architecture in software development. We will explain its advantages and explore its core principles and success stories.

Before exploring how to design composable software architecture, let’s first examine its principles and understand what makes it a unique approach and an ideal solution for building a robust application.

Principles of composable software architecture

Image for Designing Composable Software Architecture

These are the principles that define composable architecture and make it an ideal approach for developing software:

  • Modular components: One of the core principles of composable architecture is breaking down a large system into smaller, self-contained modules or components that can perform specific functions and be independently developed, tested, and deployed. The modular approach makes both new and existing components easy to maintain.
  • Reusability: The composable approach encourages the design of generic reusable components, making them flexible and easily adaptable for various use cases. It reduces duplication of efforts and speeds up time to market because components can be shared within and between teams.
  • Scalability: Its modular architecture promotes the design of independent components, allowing for resource allocation (both vertical and horizontal scaling) to the affected components without burdening the overall system.
  • Resilience: Components are designed to be fault-tolerant and capable of recovering from failures by proactively monitoring activities and implementing self-healing capabilities.
  • Interoperability: While software components are developed independently, the composable architecture ensures they work together seamlessly using common protocols, standards, and formats that enable communication and seamless integration.
  • Flexibility: It promotes the design of components that are easy to modify, extend, or replace when needed without disrupting the entire system.
  • Loose coupling: An integral part of the composable architecture principle is minimizing the dependencies between essential components to ensure that changes to one component don't adversely affect the others. This can be achieved by using application programming interfaces (APIs), messaging patterns, or other well-defined interfaces to facilitate smooth communication and data exchange between components.

Designing composable software: Strategies and best practices

Designing flexible software with composable architecture involves structuring your system in a way that various parts of the system can be combined, reused in multiple systems, and replaced with little or no friction.

Here’s a guide to help you design such a system:


Single responsibility

Start by identifying your system's building blocks and breaking them into logical, independent components. Make sure that each module has a single responsibility with related functionalities. This will make it easier for you and your team to maintain and understand each component.

In addition, individual components can be scaled independently without affecting the overall performance of the system.


Clear interfaces

Create well-defined, stable interfaces for each component. Remember that these interfaces need to be minimal and focus on what’s necessary for interaction. By doing this, you can achieve a loosely coupled system between components.

Minimize dependencies

Use dependency injection and other dependency management techniques to manage component dependencies. When you build your components with separate dependencies, you can easily replace or upgrade them without hassle.

Encapsulation

A best practice to follow when designing your component is to expose just what your components need to interact and function with other components and the overall system. Keep the internal details and any other information that is not required for interaction closed. This helps maintain the integrity and security of your components.


Testing

Testing is an important part of the software development lifecycle (SLDC). You need to write unit tests to ensure that the component functions as designed, integration tests to ensure that they interact well with each other, and end-to-end tests to ensure they work together on the overall system level.


Versioning

The components you design will need dependencies upgrades, extended with new features, and sometimes repurposed. You must set up a versioning system and best practices to ensure this process is seamless.


Logging and monitoring

In application development, you'll encounter bugs—some are easy to replicate, and others are not. Implementing logging, monitoring, and tracing systems helps you debug your system faster, monitor component performance, and optimize it as needed.


Documentation

You need to document the module’s purpose, usage, naming conventions, and coding standards and include inline comments as needed. This will help you and your team quickly understand why certain decisions were made, how to use specific components, and what trade-offs were considered.


Continuous Refactoring

Adopting composable architecture into your development process is not a one-time thing; you need to continuously refactor and improve modules based on customer feedback and changing requirements.

Composable approach in software development: Microservices


Microservices

Microservices architecture is an approach that structures an application as a collection of loosely coupled services. Each service is a modular and independent unit of functionality that can be developed, tested, and deployed separately.

In the context of composable architecture, each service can be scaled independently, faults are isolated, and multiple technologies can be used to best fit the requirements. Below are some of the benefits of microservices that make it a composable approach:

  • Uses smaller and focused codebases that are easier to manage and update.
  • Faster SLDC as teams can work on different services concurrently.
  • Services can be scaled individually based on market demand.
  • Enhanced flexibility as codebases and technologies can be reused.


How to set up a composable Microservices project

To set up a composable architecture using Microservices, you'll do the following:

  • Select a framework: Choose a framework that aligns with the project requirement and the business goal. The frameworks you can select from include Ruby on Rails (Ruby), ASP.Net Core (C#), Express.js (JavaScript), and Spring Boot (Java).
  • Create independent services: Develop each service as an independent unit with its own repository.

    #example using Express.jsimport express from 'express';
    const app = express();
    app.get('/api/service1', (req, res) => { res.send('Service 1 Response');});
    app.listen(3000, () => { console.log('Service 1 running on port 5000');});
  • Implement APIs: Ensure each service exposes well-defined APIs for communication.
  • Deploy Services: Use containerization (Docker) and orchestration (Kubernetes) to deploy and manage your services.

When should you adopt composable architecture?

Composable architecture comes with a lot of benefits, but it’s not always the right choice for every situation. It’s a strategic decision that you, as an individual or as a member of the development team, must carefully make. Below are some points you need to evaluate before adopting composable architecture:

  • Mode of operation: If your business operates in an environment that requires rapid updates of requirements and technologies, composable architecture will help you develop, test, and deploy in isolation, which leads to faster iterations and releases.
  • Scalability issue: You can adopt composable architecture if you’re dealing with complex systems that are becoming difficult to maintain or if you need to frequently update or modify parts of your system.
  • Leveraging third parties at scale: Since composable architectures are all about choices, you can adopt them if you follow the API-first approach and use a lot of third-party services.
  • Budget constraint: If your goal is to reduce cost, composable architecture will help you shift away from traditional architectures by optimizing resource utilization and using open-source alternatives when building your system.
  • Improved developer experience: When you want to enable development teams to work on different components simultaneously without hindering one another, composable architecture is your go-to solution.

Composable in the real world: Use cases

Composable architecture has a wide range of use cases in software development. Let’s explore some of these use cases and how Monogram, a composable digital agency, helps its clients build, scale, and migrate traditional monolithic platforms to a composable architecture.

Use case 1: GitHub

GitHub is a developer platform that allows developers to create, store, manage, and share their code. A major challenge they faced was that their customers found it hard to find resources quickly and in an intuitive manner.

GitHub teamed up with the Monogram team to create a resource hub that is incredibly fast, intuitive, and composable. To achieve this, Monogram used a wide range of technologies such as Next.js, TypeScript, GitHub Actions, and Playwright.

Monogram transformed GitHub Resources from an old-fashioned, unmaintainable website to a modern platform with ultrafast performance and a simple experience for users and content editors.

Use case 2: Gateway First Bank

Gateway First Bank is a financial institution that provides customers with banking services. A major challenge they faced was that their digital identity was not properly represented compared to the excellence of their service.

To improve the digital experience, Gateway First Bank teamed up with Monogram for a comprehensive marketing website redesign and redevelopment. To achieve this, Monogram used a wide range of technologies such as Contentful, Next.js, Vercel, and Tailwind CSS to build a truly composable system.

Use case 3: Hy-Vee

Hy-Vee is a prominent Midwest supermarket chain offering grocery shopping and delivery, pickups, prescription refills, and more.

Hy-Vee partnered with Monogram to help build its customer-facing applications (Hy-Vee Red Media, Hy-Vee Opportunity Summit, and Hy-Vee KidsFit). To achieve this, they used composable technologies like Sanity, Next.js, Vercel, and Tailwind CSS to deliver applications that are fast, secure, and easy to update.

Another popular use case of composable architecture you might not be familiar with is its usage in cloud computing. Cloud computing uses the concept of composable infrastructure to provision resources such as storage, computing power, and networking resources as needed, enabling efficient resource utilization and scalability.

Next steps

In conclusion, composable architecture is a great approach to designing and building flexible software systems that free you from technical hurdles, provide creative control, and enable collaboration between you and your team.

While migrating from traditional monolithic architecture to composable architecture or starting from scratch can be complex and challenging, partnering with an expert like Monogram will help reduce development time and operational risk, minimize disruption, and seamlessly transition your applications and websites.

View our portfolio to see what a composable version of your application could look like, and contact us today for a free consultation.