Designing with Modularity in Mind
10.02.2025 — Ervin Parashumti
One of the biggest challenges I’ve faced in enterprise projects is integrating requirements from multiple stakeholders. When working on applications with a global reach, different teams often have conflicting needs, making it difficult to create an application that fills the needs of every team. In multiple projects, my team and I had to design applications that were going to be launched in countries, each with its own workflows, regulations, and user expectations. At first, trying to standardize everything felt overwhelming.
This issue became particularly evident during the development of a task management system. The application was intended to serve multiple teams, each with unique requirements for how they wanted to interact with tasks. Some wanted a focus on their own assigned tasks, while others prioritized team tasks. It quickly became clear that trying to hardcode specific solutions for each team would result in a loop of constant adjustments.
Modularizing the task manager
I remember the day that I shared the idea of a modular system for the task manager application with the lead developer. Rather than designing a rigid system, the idea would be to create a modular application that allowed users to configure their UI based on their needs. Instead of enforcing predefined structures, we provided users with tools to filter and categorize tasks in a way that suited them best. It sounded so simple we felt dumb for not thinking of something like this before. We were excited and couldn't wait to build the first prototype to test it.
The solution was simple: display all tasks on a single page and allow users to create custom folders with filters. For instance, users could create a "My Tasks" folder that only displayed tasks assigned to them or a "Team Tasks" folder that filtered tasks based on team assignments.
To illustrate the impact, consider a scenario where a sales team primarily needs to track follow-up tasks with clients, whereas a support team focuses on high-priority customer issues. In a rigid system, each team would need a separate, pre-defined view tailored to their needs. However, with a modular design, users can create personalized task views. A salesperson can filter tasks to show only pending follow-ups, while a support lead can view only critical support tickets. This self-configurable system drastically improves efficiency and usability while reducing the need for constant developer intervention.
By shifting from a feature-specific approach to a modular design, we reduced complexity for developers and provided a more flexible solution for users. This meant that instead of constantly reworking the application to accommodate new requests, teams could configure the application themselves, making it adaptable to their needs. The application was able to be adapted much easier by tons of other teams.
A complicated UI for a rule based system
Another significant challenge I faced was designing a rule-based system for processing and decision-making. This system involved a wide range of scenarios, each requiring specific rules and actions. Traditionally, these rules were implemented by technical teams in Camunda, making modifications slow and cumbersome. The goal was that the non-technical team is able to create this rules with a super simple UI.
We introduced a modular UI that allowed users to build rule logic through a visual interface. By using "IF" and "Action" cards, users could easily create complex workflows without needing to rely on developers. For example, a user could define a rule that is as simple as "If certain conditions are met, take a specific action" or "If an API call returns a particular response, trigger another action".
To better illustrate, imagine a claims processing system where different types of claims—such as car accidents, natural disasters, or property damage—require specific actions. In a traditional system, each claim type would require custom development work. However, with a modular approach, a user can configure rules dynamically. For example: "If the claim type is 'Car Accident' and the damage is above $5,000, escalate to a senior adjuster." or "If a natural disaster is detected, auto-approve repairs below a specific threshold."
By designing a modular rule engine, we enabled each country to define their own processing logic without affecting the core system. This flexibility allowed the application to serve diverse needs while maintaining a cohesive and scalable structure.
This approach not only simplified the user experience but also expanded the possibilities for customization, enabling teams to create rules that fit their specific needs without requiring constant intervention from the development team. Additionally, it empowered non-technical users, such as claim managers or business analysts, to configure and optimize workflows without needing deep technical expertise. Switching the UI to a modular cards interface made the application accessible to a big number of new users and also reduced the time the rules were being made.
Modularity or Over-Engineering
While modularity offers flexibility, I am always concerned of it creating complexity that is not needed. On top of the complexity, designing a modular system requires a deep understanding of both the problem and the technical challenges involved. How can you keep yourself away from over-engineering? Trying to build for every possible future scenario, which can delay implementation and create unnecessary complications is a big concern I always have.
In enterprise environments, teams often struggle with tight deadlines and full backlogs. The pressure to deliver new features can lead to a focus on short-term gains rather than long-term sustainability. However, taking the time to iterate and refine solutions can lead to more robust and scalable applications. Refactoring should be a regular part of the development cycle, ensuring that systems remain adaptable and efficient over time. Refactoring can be a good base to evaluate if something modular can be more beneficial in comparison to driving a modular approach from the very start. The team understands the problem, the stack and it's capabilities a lot better to make a much more informed decision.
A well-designed modular system makes applications more sustainable and reduces development efforts over time. It allows users to tailor the system to their needs without requiring constant updates from the development team. More importantly, it shifts the focus from enforcing rigid workflows to enabling creative and flexible applications.
Modularity is about providing a foundation that empowers users to personalize their workflows while maintaining a structured and systematic approach. By embracing modularity, we create applications that not only meet today’s needs but are also prepared for the challenges of the future.