Frontend Development 9 min read

Scaling React Applications: Containers vs Components, Feature‑Based Code Organization, CSS Modules, PostCSS Auto Reset, and Redux‑Saga

This article shares lessons learned from releasing React Boilerplate 3.0, covering the importance of front‑end scalability, the distinction between container and presentational components, feature‑based code organization, CSS Modules and PostCSS Auto Reset for style isolation, and using redux‑saga for readable, testable asynchronous flows.

Hujiang Technology
Hujiang Technology
Hujiang Technology
Scaling React Applications: Containers vs Components, Feature‑Based Code Organization, CSS Modules, PostCSS Auto Reset, and Redux‑Saga

We recently released React Boilerplate 3.0 and, after talking with hundreds of developers, distilled the key practices for building and scaling large web applications on the front end.

Containers and components : A container manages state and data connections without styling, while a presentational component handles only UI rendering. Separating these concerns prevents mixing data logic with visual styles.

Code structure : Traditional type‑based folders (actions/, components/, containers/, etc.) become unwieldy at scale. Organizing by feature keeps all files related to a specific UI element together. For example, the NavBar feature can be arranged as:

react-app-by-feature
├── css
├── containers
│   └── NavBar
│       ├── NavBar.jsx
│       ├── actions.js
│       ├── constants.js
│       └── reducer.js
└── components
    └── App.jsx

This layout reduces navigation overhead and minimizes merge conflicts when multiple developers work on the same feature.

Style management : Global CSS naming collisions are solved with CSS Modules . Each component’s styles live next to the component and are imported as a JavaScript object, guaranteeing unique class names:

/* Button.jsx */
var styles = require('./styles.css');

To reset inherited CSS properties per component, the PostCSS Auto Reset plugin rewrites inheritable properties to their defaults, avoiding unexpected differences between components such as line‑height.

Data fetching : While Redux Thunk allows async actions, it mixes data fetching with action creators, making testing harder. redux‑saga uses ES6 generators to write asynchronous flows that look synchronous and are easily testable.

Typical saga effects include:

put() – dispatch an action

take() – pause until a specific action occurs

select() – read a slice of state

call() – invoke a function with arguments

Because sagas run independently, they can act as glue middleware, decoupling components. For instance, a Clock component can trigger a Timer component via saga without each component knowing about the other.

Summary :

Distinguish container (stateful) and presentational (stateless) components.

Organize code by feature rather than by type.

Use CSS Modules and PostCSS Auto Reset for isolated, conflict‑free styling.

Adopt redux‑saga to obtain readable, testable asynchronous flows and to glue decoupled components together.

scalabilityreactfrontend architecturecode organizationCSS ModulesRedux-Saga
Hujiang Technology
Written by

Hujiang Technology

We focus on the real-world challenges developers face, delivering authentic, practical content and a direct platform for technical networking among developers.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.