Handbook
Purposeful Architecture

Factoring Business Needs Into Architectural Decisions

Last updated by Noel Varanda (opens in a new tab),
Frontend Development
Architecture
Repository Setup
Frontend
Architecture
Decision guide

When deciding on the architecture of your frontend application, it is important to consider the business factors that will affect your decision. These factors include:

  • Team size and structure
  • Functionality and features
  • Scalability and performance
  • Security and compliance
  • Cost and time to market

Though these factors are not exhaustive, they are a good starting point to consider when deciding on the architecture of your frontend application.

Business factors

Team size and structure

Considerations

  • How big is your team?
  • Who owns the API(s)?
  • Do you require multiple teams adopting parallel development?

  • Is your team highly collaborative or independent?

  • Is there a need for easy sharing of code, components, and data within the team?

Implications and suggestions
Comparison of needs for different sized teams
FactorsSmall TeamsLarge Teams
CollaborationEasierRequire extensive collaboration
CommunicationMore streamlinedMore communication channels and needs
ModularitySimpler architecture preferredModular architecture is beneficial
ParallelizationDevelopment is often sequentialParallel development is crucial
ConflictFewer conflicts and dependenciesPotential for conflicts and dependencies
AutonomyGreater individual autonomyMore division of responsibilities
ScalabilityScalability may be less of a concernNeed for scalability and flexibility
Decision-makingDecision-making can be quickerMultiple stakeholders, decision-making process may be longer
Resource allocationLimited resources may require optimizationMore resources available
  • Small teams don't require the complexities of multi-repos or even monorepos potentially.

  • If the team that owns the frontend also owns the API then use tRPC (opens in a new tab) in combination with a monorepo (preferable) or GraphQL (opens in a new tab) for an end-to-end typesafe API.

  • If you have a team which constantly needs shared code, then a shared libs directory is a good idea.

~/my-project/
├── apps
│   ├── app-1
│   │   └── ...
│   ├── app-2
│   │   └── ...
│   └── ...
├── libs
│   ├── ui
│   │   ├── components
│   │   └── ...
│   └── ...
⚠️

If using a shared libs directory between projects, be sure to provide a clear separation of concerns and ownership beforehand. It is fairly common for people to stick anything that shared code can quickly become messy if un-managed. See tips on managing shared code.

Functionality and features

Considerations

  • What are the key functionalities and features your application needs to deliver?

  • How SEO-friendly does your app need to be?

  • Are there any specific business logic or workflow requirements?

  • How accessible should the project be?

Implications and suggestions
  • Consider libraries out there that solve key features that your application.

  • Different expectations require different data fetching, or even rendering approaches for optimal UX. For example, if you have a blog then you will want an SEO-friendly app which requires server-side rendering. Read more on SSR vs SSG vs. CSR.

  • Adopt a state management solution like Redux to handle complex business logic and workflow requirements.

  • Identify what a11y level of conformance (opens in a new tab) you need to be at before setting up appropriate linting.

Scalability and performance

Considerations

  • What is the expected growth and scalability needs of your application?

  • How many users are anticipated, and what is the expected data volume?

  • Do you need data in real-time?

  • Will you need user collaboration?

  • How important is performance optimization for your application?

Implications and suggestions

Expected growth

If this is a throw-away, POC (proof-of-concept), then avoid architectural complexities like monorepos and micro frontends. If you don't need to share code with any other team, nor will you ever, then adopting a monolith could be suitable.

However, if your codebase needs to grow then think about how you can be efficient now whilst catering for the future.

E.g. You start with a team of 2 software developers working on a single SaaS product, knowing that your will continuously grow.

  1. Start with a monolith.
  2. Evolve into a monorepo.
  3. Move to a micro frontend architecture.
💡
Incremental changes are the best changes.

Performance and Rendering

  • Will you need to employ techniques like lazy loading or pagination for handling large data volumes? How can the use technologies like GraphQL, tRPC, or REST APIs for efficient data retrieval help?

  • If you need data in real-time, then using websockets is a must. tRPC has native websocket support (opens in a new tab), so if your team owns the API, this could be a real gain. Either way considering the transport protocol early on will help a lot down the line.

  • Consider implementing server-side rendering (SSR) or static site generation (SSG) using Next.js (opens in a new tab) to improve initial page load times. Use performance monitoring tools to identify and optimize performance bottlenecks.

  • Network protocols could also help influence this decision.

Technology constraints

Considerations

  • Are there any existing systems, infrastructure, or tools that need to be considered?

  • Are there any technology constraints or preferences defined by the project?

  • Are there any regulatory or compliance requirements that could impact architectural choices?

Implications and suggestions
  • If there's a requirement to integrate with a specific backend technology for example Django or Ruby on Rails, consider how this might impact API library and architecture decisions.

  • Consider the team's preferences on technology stack, the front end guild's preferences, and where the guild wants to be moving forward; is there any new tech we can incorporate provided the time allows for it?

  • Ensure compliance with regulatory and compliance requirements. Choose architectures that provide security features and meet the necessary compliance standards. Consider adopting secure coding practices and encryption mechanisms for sensitive data.

Development timeline

Considerations

  • What is the project timeline and any specific development constraints?

  • Are there any time constraints, such as specific deadlines or milestones?

Integration requirements

Considerations

  • Are there any external systems or services that need to be integrated into the application?

Maintenance and extensibility

Considerations

  • What are the long-term maintenance and extensibility requirements of the project?

  • Does the chosen architecture allow for easy maintenance, updates, and addition of new features?

  • Is it important to avoid excessive technical debt and ensure future scalability?

Implications and suggestions

If this is a throw-away, POC (proof-of-concept), then avoid architectural complexities like monorepos and micro frontends. If you don't need to share code with any other team, nor will you ever, then adopting a monolith could be suitable.

However, if your codebase needs to grow then think about how you can be efficient now whilst catering for the future.

E.g. You start with a team of 2 software developers working on a single SaaS product, knowing that your will continuously grow.

  1. Start with a monolith.
  2. Evolve into a monorepo.
  3. Move to a micro frontend architecture.
💡
Incremental changes are the best changes.

Type of application

Considerations

  • What sort of project is it?

  • What is the nature of the application being built (e.g., app, PWA, blog, etc.)?

  • Should the chosen architecture consider a specific rendering approach based on the application type (SSR, CSR)?

Implications and suggestions
  • SaaS based projects are generally continuously growing and expect large teams working in parallel to work together on a single project. Here, a micro frontend architecture could be beneficial due to its isolated nature.

  • Isolated projects however have no reason to adopt the complexities of micro frontends and so are free to use their own repos. Bare in mind, however, that if you have mulitple projects that have common code (e.g. component library), and there is no reason for separation of repos (e.g. privacy or law) a monorepo could still be benficial in these cases.

  • PWAs need offline support, blogs need to render on the server for better UX, interactive apps generally don't need great SEO and can afford to render more on the client. So understanding the nature of the application has a huge impact on framework selection.

Architectural factors

In order to make an informed decision about the right frontend architecture, it's important to understand the following factors and questions. They will help you gain a better understanding of your project's needs and align with your requirements and business goals.

Application type

The application type refers to the architectural style used to structure the frontend codebase. Two common approaches are:

  • Monolith: A monolithic architecture represents the entire frontend as a single, tightly-coupled application. It is simpler to develop and deploy but may become harder to maintain and scale over time. Read more about monolithic architecture (opens in a new tab).

  • Micro Frontends: Micro frontends divide the frontend into multiple independent, loosely-coupled applications, each responsible for a specific feature or functionality. It enables independent development, deployment, and scalability. Read more about micro frontends (opens in a new tab).

Deciding Factors

  • Monolith for smaller projects or when simplicity and rapid development are essential.

  • Micro frontends when different teams need to work independently on specific parts of the application.

  • Adhering to fundamental principles should allow for starting with monolith and only later upgrading.

State management

Determine the approach to manage the state of your application. Options include local component state, global state management libraries like Redux, or state management patterns like React Context.

  • Local State: Managing state within individual components without using external libraries or frameworks. It is suitable for simple applications with limited shared data.

  • Global State (Context API): Utilizing the Context API provided by frameworks like React to share state across multiple components without external dependencies.

  • State Management Libraries: Employing dedicated state management libraries such as Redux. These libraries provide centralized, predictable state management with advanced features like middleware and time-travel debugging.

Deciding Factors

  • Local state or the Context API for small-scale applications or when the state is relatively simple

  • Redux for complex applications with multiple shared states or asynchronous actions

Api paradigms

API paradigms are tools or technologies used to communicate with the backend server and retrieve data. Some common options include:

  • REST: Representational State Transfer (REST) is a widely used architectural style for designing networked applications. It follows a stateless client-server communication model using HTTP requests. Learn more about REST (opens in a new tab).

  • tRPC: tRPC is a modern framework for building end-to-end typesafe APIs in TypeScript. It simplifies API development, provides type safety, and supports server-rendered pages, WebSocket subscriptions, and more. Visit the tRPC website (opens in a new tab) for further information.

  • GraphQL: GraphQL is a query language and runtime for APIs that enables clients to request specific data and shape the response according to their needs. It offers flexibility, efficient data fetching, and strong typing. Read more about GraphQL (opens in a new tab).

Deciding Factors

  • REST if you don't own the API, or if widespread adoption and interoperability is a priority.

  • Use tRPC or GraphQL if type safety, efficient data fetching, and advanced features like real-time updates are essential.

Network protocols

Websockets

WebSockets provide full-duplex communication channels over a single TCP connection. They enable real-time data exchange between client and server, allowing instant updates and bidirectional communication. Learn more about WebSockets (opens in a new tab).

  • Use cases: Real-time applications, efficient data transfer, bi-directional communication.
  • Advantages: Instant data updates, low-latency transfer, interactive and dynamic applications, reduced network overhead.

Http (hypertext transfer protocol)

Hypertext Transfer Protocol (HTTP) is the foundation of communication on the web. It follows a request-response model and is suitable for traditional client-server interactions. Read more about HTTP (opens in a new tab).

  • Use cases: Web-based applications, content-heavy applications, bandwidth optimization.
  • Advantages: Universal compatibility, caching and proxies, stateless nature, extensive tooling and library support.

Deciding Factors

  • WebSockets when real-time, bidirectional communication is required, such as chat applications, live dashboards, or collaborative tools.

  • Use HTTP for traditional client-server communication, RESTful APIs, or when real-time updates are not necessary.

Integration approach

Integration approach refers to how different components, services, or libraries are integrated within the application. There are two common approaches:

  • Libraries: Integrating functionality through libraries or packages that provide specific features or utilities. Examples include integrating UI component libraries like Material-UI or Bootstrap.

  • Services: Integrating functionality through separate, independent services that communicate with each other through well-defined APIs. This approach is common in microservices architectures.

Deciding Factors: Choose a library-based approach when specific functionalities can be easily achieved through existing libraries without the need for complex communication. Select a service-based approach when the project requires independent, scalable, and loosely coupled services that can be developed and deployed independently. Consider factors like project requirements, complexity, scalability, and team

expertise.

Note: Each topic mentioned here provides only a brief overview. It is recommended to explore the provided links and conduct further research to make informed decisions based on your specific project requirements and constraints.


Keep up to date with any latest changes or announcements by subscribing to the newsletter below.