Home / Insights / Architecture and Modernization
Architecture and Modernization
Reuse or Customise? A Practical Framework for Product Development Decisions
Reuse saves time and money; customisation creates differentiation and fit. Too much of either causes problems. This guide gives a decision framework, the architecture patterns that let one product serve many needs, and the hidden costs that tip the balance.
TopicsArchitecture and ModernizationProduct Design and DiscoverySoftware Costs and Budgets
Key takeaways
- Reuse what is common and stable — authentication, payments, notifications, design-system components — and customise what differentiates your product or is unique to a customer’s process.
- Prefer configuration over code: settings, rules, templates and feature flags let one product serve different needs without forks.
- Every customisation has a lifetime cost in testing, upgrades and support. Price it before agreeing to it.
- Reuse has hidden costs too: dependency risk, licence obligations, abstractions that fit nobody well and libraries you cannot change.
- Revisit the balance regularly: today’s custom feature may become tomorrow’s reusable module, and yesterday’s shared component may need to split.
On this page
- Three levels of the decision
- The differentiation test
- Prefer configuration over code
- Architecture patterns that make reuse work
- The hidden costs on both sides
- Pricing a customisation request
- Worked example: a B2B scheduling product
- Reuse inside an agency or multi-client team
- Measuring whether the balance is right
- Revisit the balance regularly
- Frequently asked questions
- Sources and methodology
Every product team faces the same tension. Reusing existing code, components and services makes delivery faster and cheaper, and spreads the cost of quality across many uses. Customising — building specifically for a market, a customer or a use case — creates fit and differentiation. Lean too far towards reuse and the product feels generic or forces users into awkward workflows. Lean too far towards customisation and every release becomes slower and riskier.
This guide offers a practical way to make these decisions, at the level of features, components and whole products. For the related question of building versus buying a whole system, see our guide to build versus buy decisions.
Three levels of the decision
- Component level: use a library, an internal shared module or a managed service — or write something new?
- Product level: should a capability be a standard feature, a configurable option or a customer-specific extension?
- Portfolio level: should several products share a platform, or does each need its own architecture?
The same principles apply at each level, but the stakes rise from component to portfolio.
The differentiation test
Ask of any capability:
- Does it differentiate us? Would customers choose us because of how this works?
- Is it stable? Will the requirements change often?
- Is it common? Do many products or customers need it in the same form?
- Is it risky to get wrong? Security, payments and compliance are better served by proven components.
| Capability profile | Usual approach |
|---|---|
| — | — |
| Common, stable, not differentiating | Reuse a proven library or service |
| Common, but varies by customer in predictable ways | Build once, make it configurable |
| Differentiating and evolving | Build custom, keep it well-bounded |
| Unique to one customer and unlikely to recur | Extension point or separate integration, outside the core |
| High-risk (security, payments, identity) | Reuse proven components; customise only at the edges |
A starting point for discussion, not a rule.
Prefer configuration over code
The most effective way to serve different needs without multiplying code is to make variation explicit and data-driven:
- Settings and feature flags switch capabilities on or off by tenant, plan or region.
- Rules engines and decision tables let business users change thresholds and policies without releases.
- Templates for documents, emails and workflows allow tailored output from one engine.
- Custom fields and metadata let customers capture extra information without schema changes.
- Theming and white-labelling through design tokens rather than forked front ends.
Configuration has limits: too many options make a product hard to test and understand. Keep a register of configuration options with owners, and remove options nobody uses.
Architecture patterns that make reuse work
| Pattern | What it gives you | Watch out for |
|---|---|---|
| — | — | — |
| Modular architecture with clear boundaries | Modules reused and changed independently | Boundaries must follow business domains, not technical layers |
| Shared libraries and design systems | Consistent behaviour and UI across products | Versioning and upgrade discipline; a team to own them |
| Platform services (identity, notifications, billing) | One implementation for many products | Become bottlenecks without clear APIs and service levels |
| Extension points and plug-ins | Customer-specific behaviour outside the core | Stable extension APIs needed; test extensions on upgrades |
| Headless or API-first core | Different front ends on one back end | API design effort upfront |
Our comparison of MACH and modular monolith architectures covers these trade-offs at system level.
The hidden costs on both sides
Hidden costs of customisation
- Testing multiplies: each variant must be tested on every release.
- Upgrades get harder: custom code may conflict with platform changes.
- Knowledge concentrates: a few people understand each customisation.
- Support becomes complex: different customers run different behaviour.
- Forks drift: a copied codebase for one customer quickly falls behind the main product.
Hidden costs of reuse
- Dependency risk: third-party libraries can be abandoned, change licence or introduce vulnerabilities.
- Over-generalisation: a shared component built for every case becomes complex and fits none well.
- Coordination overhead: changes to shared code need agreement and careful releases.
- Licence obligations: some open-source licences impose conditions on distribution.
- Lock-in: managed services and frameworks shape the rest of the architecture.
Pricing a customisation request
When a customer or stakeholder asks for custom behaviour, estimate its full cost, not just the build:
| Cost element | Questions |
|---|---|
| — | — |
| Build | Design, development and testing effort |
| Ongoing testing | How many test cases are added to every release? |
| Upgrade effort | How likely is it to break when the core changes? |
| Support | Will support staff need special knowledge? |
| Opportunity cost | What roadmap work is displaced? |
If the same need is likely to recur, consider building it as configurable core functionality instead.
Worked example: a B2B scheduling product
A hypothetical company sells workforce scheduling software. A large customer asks for a custom shift-approval process with three levels of approval and special rules for weekend shifts.
- Option A — custom code for this customer: fast to build, but adds a branch in the scheduling engine that every release must test, and the next customer with a similar need gets another branch.
- Option B — configurable approval workflows: takes longer, but lets any customer define approval levels and rules. The large customer’s process becomes configuration.
The team checks the sales pipeline and finds four prospects asking for variations of approval rules. They choose option B, delivering it in two stages so the large customer is not kept waiting, and price the faster interim delivery accordingly.
Reuse inside an agency or multi-client team
Software partners face this decision constantly: every client wants something tailored, yet good engineering depends on proven building blocks. A healthy approach separates three things:
- Internal accelerators: authentication templates, CI pipelines, infrastructure modules, design-system starters and testing harnesses that speed up any project without carrying one client’s business logic.
- Client-owned code: everything specific to the client’s product, which belongs to the client and should never be reused for another client without permission.
- Open-source and commercial components: chosen per project with licence and maintenance checks, documented in a software bill of materials.
Being explicit about these boundaries protects clients’ intellectual property and lets teams move quickly on the parts that genuinely are generic.
Measuring whether the balance is right
| Signal | What it suggests |
|---|---|
| — | — |
| Release cycle lengthening as customers grow | Too many custom branches or configuration combinations |
| Same bug fixed in several places | Missing shared module; logic duplicated |
| Shared component changes blocked for weeks | Over-centralised reuse; ownership or versioning problem |
| Customers working around the product with spreadsheets | Too little configurability for real needs |
| High share of support tickets from one customer’s custom features | Customisation not priced or designed sustainably |
Review these signals in quarterly architecture and product reviews.
Revisit the balance regularly
- Quarterly architecture review: which customisations have been requested more than once and should become core features?
- Usage data: which configuration options are unused and can be removed?
- Dependency review: which reused components are unmaintained or risky?
- Rule of three: when the same pattern appears in three places, consider extracting a reusable module — not before.
Frequently asked questions
Should we ever fork the product for a customer?
Rarely. Forks are cheap to create and expensive to maintain. Prefer configuration or extension points; if a fork is unavoidable, plan and price how it will be merged back or retired.
When is it worth building a shared internal library?
When at least two or three products need the same capability in the same form, and a team can own it with versioning and support.
How do we stop a configurable product becoming too complex?
Keep a register of options with owners and usage data, set sensible defaults, and remove options that are rarely used.
Is low-code a way to balance reuse and customisation?
For internal tools and simple workflows, low-code platforms can provide fast customisation on a reusable base. Watch for limits in testing, version control and portability.
Sources and methodology
Facts in this article were checked against the sources below on 6 November 2026. Directory data (ratings, review counts, rate bands and team sizes) changes over time and is shown as published on the date accessed. Illustrative examples are labelled as such and are not quotes.
Related reading
Continue your research
Balancing speed, fit and long-term cost?
Share your product and roadmap. We will help you decide what to reuse, what to configure and what to build, and design an architecture that stays maintainable.
