Client-Side Architecture Basics [Guide]

Last updated Jun 24th, 2020
Though the tools we use to build client-side web apps have changed substantially over the years, the fundamental principles behind designing robust software have remained relatively the same. In this guide, we go back to basics and discuss a better way to think about the front-end architecture using modern tools like React, xState, and Apollo Client.

Welcome

When I first learned React and Redux in 2015, I made an enormous mess of the production codebase I was working on.

Back then, class-based components and Redux were the coolest kids on the block. This was my first time prepping up to work on a real-world React project, so I bought the best courses I could find on the topics and dove in.

After a couple of months, according to the React community, the way I was doing things were outdated. There were newer, cleaner, and recommended best practices for me to follow.

I think it's incredible that we question the way we do things. But my vast gap in knowledge of client-side architecture left me always finding it necessary to play catch up to refactor to the new approaches.

These sentiments were also recently echoed in this painfully accurate Twitter thread from Joel Hooks.

Developers are confused about where to start and what to choose when they start learning to write high-quality React applications. They want a strong foundation of knowledge and the confidence to architect React applications at scale built to current industry standards.

They are frustrated that there are no widely accepted standards for building React applications consistently, coherently, and with minimal risks to their professional reputations and livelihoods.

On top of that, there is a sea of choices and tradeoffs that React developers face every day. From how the project is even started, which framework to use, how to manage state, how does it get bundled, accessibility, and deployment just to get going.

At each f🐬kin' stop, there's a new choice to make: a new chance to be wrong.

Trying to build a solid foundation in React feels like a slot machine. — @jhooks, June 17th, 2020

Some point later in my developer journey, I too realized this was happening. I realized I could never keep up to date with the current trends of the libraries and frameworks I was using. I also decided I didn't want those nuances to dictate my professional reputation or livelihood. It wasn't good enough for me. I needed something better.

Eventually, I sought out the originating principles— the fundamentals, to client-side architecture. I sought out to construct a standard for building client-side apps. A professional one. One based on the software design principles that have helped us design robust software for decades.


This guide teaches you client-side architecture fundamentals.

It's the result of my research using first principles on how to design and develop robust, flexible, testable, and maintainable client-side applications.

During my experience working on client-side apps of varying sizes, I've realized that some serious upfront design on the architecture can have a significant impact on the quality of the code for the duration of its life.

From simple dashboards to multi-layered apps with rendering layers, domain logic, multiple types of users - this guide teaches you the essential design principles front-end developers inadvertently code around within their everyday programming jobs.

This guide proposes architectural standards for client-side web development.

While we're primarily focused on React, because it's the most popular library with the least structure, the principles are transferrable to any configuration of view-layer library or framework.

Programming tends to seem more like a trade than a science. Each tool, be it a state management library, API, or a transport-layer technology, is best suited to solve a particular set of problems. As a developer and a tradesperson, it's good to know how the tools in our toolbox are best used.

... if all you have is a hammer, everything looks like a nail.

At the end of this guide, you'll learn a standard for web development. You'll have a clear understanding of the discrete layers of concerns in a client-side app: from the view layer to various forms of state management, and how to handle interaction (app) logic.

Prerequisites

Next page

I. Architecture

Understanding what we need from a client-side architecture.

Next page →

Discussion

Liked this? Sing it loud and proud 👨‍🎤.


15 Comments

Submit
Juan Manrique
a year ago

This is a really great article, might need to come back later when Im not so overloaded with info also I want to give my two cents in the prop drilling part and the organising code, most of it can be solved with composition, it helped me tremendously in refactoring a lot of stuff that was so tightly coupled and also repeated across several react native screens.


Now you can just have really small components that only care about showing something and then "higher" components that define the layout and only pass its children. That way you can pass a lot of props without making the layout ones caring about those, they only care about the children they have inside and how to style them properly. For example, like a reusable table, you have a component for the rows, that only cares about how many children you send in as columns, they could all end up being different dumb components you created for lets say, main info, and generic info, main info in the case of the project Im on, has a button that triggers an Apollo mutation to start following or to stop following that entry, and a text with the main ID. Said button is another dumb component that just passes the type of graphql model that called it along with the ID, so the mutation is executed elsewhere. Before that that logic was shared across several screens, it was not sane whenever changes where implemented, so refactoring it that way along with composition made it much more manageable and now I only have to care about a single file for it.


Still from this article it seems I can even go even further, sadly Im still not so good with hooks so I end up using a class based component for the main screens/pages that are in charge of organizing and styling the layout to show, and all the components they call for it are just functional components.


A question though, when looking through state management I came across a few articles from Dan saying to basically, if you can keep the state in the component, just do that instead of trying to go plus ultra and sending everything to redux. In this case, if you have a single piece of logic that you know doesn't need to be shared across several pages/screens etc. would implementing the state locally would go against this architecture?

leo
a year ago

Hey, great post! thanks for this. What about MobX for state management ? I use it and I think it's a very great choice...

Steve
10 months ago

Awesome article as always, learned a ton. Thanks.

Daniel
10 months ago

This is fantastic! It's been difficult to find good advice structuring medium-sized frontend applications, but this is exactly what I needed. Our stack is Vue (and REST instead of GraphQL) but the concepts translate pretty easily with a little thought. I don't think it's an exaggeration to say that if the concept of UI-as-pure-function defined the past few years of my frontend skill development, these insights into state management will define the next few years.

Tomasz
10 months ago

Great article! I have a question about using pages as containers https://khalilstemmler.com/articles/client-side-architecture/introduction/#Container-components-are-pages. Is it possible to have simple relation pages/container => Section<view components>? Most of time I ended with more nested architecture and if there is more nesting then passing all those props is nightmare. Also if we have simple relation pages/container => Section<view components> then Section component, which holds all view components, will be a huge one. As it would have to manage all those view components. Maybe you suggest some article about it? Or you can share your knowledge :)

Suzanna
10 months ago

Fantastic article! Answered a lot of the questions I had but didn't quite know how to frame.

Oleg
8 months ago

I just want to say thanks. great job!

Internet Person
8 months ago

Would it be possible to build frontend apps that are framework-agnostic ? i.e. the way clean architecture lets you push frameworks to the edge so that they can be easily swapped out if the need arises

Li
8 months ago

Great post! Thank you!

Rowan Weismiller
7 months ago

I really appreciate you taking the time to share your thoughts with such helpful illustrative examples. You're a gift to the community. Thanks so much.

sanaya
7 months ago

A very nice guide. I will definitely follow these tips. Thank you for sharing such detailed article. I am learning a lot from you.


https://nareshit.com/reactjs-online-training/

Farren
7 months ago

Is the complexity related to nature of the problem itself, or is it just related to the way we're solving it?


Having worked on several large SPA apps over the last 4 years, in general they scream accidental rather than essential complexity IMO. There's a pretty tremendous increase in logic on the client compared to server rendered templates, not worth it in many use cases. Not to mention the initial load / render and SEO hit, which pushes you towards SSR adding even more complexity.


Nice thinking but many parts need to be challenged
5 months ago

Hi there. I applaud that you have taken the time to think about how to write web apps upfront. Architecture and design do matter. However, I would recommend you to pass your article through an actual architect and see what is his feedback. I read up to a quarter of this and I feel like this should be reviewed by professionals with experience in design and architecture.

Pavel
4 months ago

C'est magnifique! Merci!

cardeal
10 days ago

Teste do React


Stay in touch!



About the author

Khalil Stemmler,
Developer Advocate @ Apollo GraphQL ⚡

Khalil is a software developer, writer, and musician. He frequently publishes articles about Domain-Driven Design, software design and Advanced TypeScript & Node.js best practices for large-scale applications.



View more in Client-Side Architecture



You may also enjoy...

A few more related articles

GraphQL Schemas vs. RESTful DTOs
GraphQL schemas serve a similar purpose to RESTful DTOs. One of the main differences is tooling. In this post, I aim to strengthen...
GraphQL's Greatest Architectural Advantages
There's a lot of advantages to using GraphQL instead of REST on your server, and there's a lot of advantages to using Apollo Clien...
How to Learn Software Design and Architecture | The Full-stack Software Design & Architecture Map
Software Design and Architecture is pretty much its own field of study within the realm of computing, like DevOps or UX Design. He...
Does DDD Belong on the Frontend? - Domain-Driven Design w/ TypeScript
Should we utilize Domain-Driven Design principles and patterns in front-end applications? How far does domain modeling reach from ...

Want to be notified when new content comes out?

Join 8000+ other developers learning about Domain-Driven Design and Enterprise Node.js.

I won't spam ya. 🖖 Unsubscribe anytime.

Get updates