šŸš€ LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
šŸŽ“ COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
HTML MASTER CLASS /// LEARN TAGS /// BUILD STRUCTURE /// SEMANTIC WEB /// HTML MASTER CLASS /// LEARN TAGS ///

Component Architecture: Colocation, Roles, and Granularity

Learn component-level architecture in React: colocation folders, presentational vs. container components, and splitting overgrown components.

⚔ Total XP: 0|šŸ’» react XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

System Hub

Component architecture fundamentals.

Quick Quiz //

What does the colocation pattern group together?


šŸš€ LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
šŸŽ“ COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

As a component gains styles, tests, and stories, how its related files are organized starts to matter. This lesson covers colocating a component's files in its own folder, the presentational-vs-container mental model, and a practical test for knowing when a component has grown too large.

1A Component Is More Than One File

As a component gains styles, tests, and a Storybook story alongside its implementation, cramming everything into one file — or scattering related files across type-based folders — stops scaling. Component architecture addresses how a single component's related files should be organized together.

2Colocation: One Folder Per Component

The recommended pattern gives each non-trivial component its own folder holding everything specific to it — implementation, styles, tests, stories — with an index.ts re-exporting the component so it can still be imported cleanly from the folder's path.

3Presentational vs. Container Components

A useful mental model splits components into 'presentational' ones that only render UI from received props, with no data-fetching or business logic, and 'container' ones that handle data and pass it down. This isn't a rule to enforce everywhere, but a genuinely useful lens for deciding where logic should live.

4Component Granularity: When to Split

A component that's grown past a couple hundred lines, manages several unrelated pieces of state, or mixes multiple distinct visual sections is usually ready to be split. A practical test: if describing the component's job requires the word 'and', it's likely doing too much and should become several components.

5Step-by-Step Breakdown

A Component Is More Than One File. You've been building components as single .tsx files. As a component gains styles, tests, and a Storybook story, cramming everything into one file — or scattering it across type-based folders — stops scaling. Component architecture is about how a single, non-trivial component's related files should actually be organized.

Colocation: One Folder Per Component. The recommended pattern is a folder per non-trivial component, holding everything specific to it — the component itself, its styles, tests, and stories — with an index.ts re-exporting the component so it can still be imported cleanly from the folder path.

In the colocation pattern, why does a component's .test.tsx and .module.css file live in the same folder as its .tsx file?

  • →Everything specific to one component is kept together, easy to find and delete as a unit
  • →It's required for the build tool to compile the component at all

Presentational vs. Container Components. A useful mental split: 'presentational' components only render UI based on props they receive, with no data-fetching or business logic of their own; 'container' components handle data and pass it down. This isn't a strict rule to enforce everywhere, but it's a genuinely useful lens for deciding where logic belongs.

Component Granularity: When to Split. A component that's grown past ~150-200 lines, handles multiple unrelated pieces of state, or mixes several distinct visual sections is usually a sign it should be split. A useful test: can you describe the component's job in one sentence without using 'and'? If not, it's probably doing too much.

A component's job is described as 'renders the search form AND the results table AND the pagination controls.' What does that suggest?

  • →It's doing too much and should likely be split into separate components
  • →This is a healthy, well-scoped component as-is

Mastery Achieved. You now understand component architecture: colocating a component's implementation, styles, tests, and stories in one folder, the presentational-vs-container mental model for where logic belongs, and using the 'and' test to know when a component has grown too large. Next, you'll learn Atomic Design, a formal system for organizing components by complexity level.

Level Up šŸš€

Advanced cheat sheets, SEO tricks, and interview prep for this topic.

Browser Support

ChromeSupported

This is a code organization convention, not a browser feature.

FirefoxSupported

Fully applicable.

SafariSupported

Fully applicable.

EdgeSupported

Fully applicable.

Accessibility (A11y)

1Colocated Tests Make Accessibility Regression Testing Easier to Maintain

Keeping a component's accessibility-focused tests (like keyboard navigation or ARIA attribute checks) directly alongside its implementation makes it far more likely they get updated whenever the component's markup changes.

SEO Implications

  • 1

    Component Organization Has No Direct SEO Effect

    This is a codebase maintainability concern with no direct bearing on runtime output, server-rendered HTML, or crawlability.

Best Practices

Reserve Dedicated Folders for Genuinely Non-Trivial Components

A tiny, single-file component with no separate styles or tests doesn't need the full colocation-folder treatment — apply it once a component actually accumulates multiple related files.

Treat the Presentational/Container Split as a Guideline, Not a Rigid Rule

Not every component cleanly fits one category — small components mixing a bit of local UI state with light data access are fine; use the split as a lens for larger, clearly mixed-responsibility components.

Frequent Bugs

THE BUG

A single component file has grown to several hundred lines and become difficult to navigate or test.

THE FIX

Apply the 'and' test: describe the component's job in one sentence. If it requires 'and', split it into the separate components that sentence implies, each with a single, describable responsibility.

THE BUG

A component's test file is hard to find because it lives in a completely separate top-level tests/ folder, far from the component itself.

THE FIX

Colocate the test file directly alongside the component's implementation (e.g. Button.test.tsx next to Button.tsx) so they're always discovered and updated together.

Real-World Examples

Splitting an Overgrown Dashboard Component

A single Dashboard.tsx file had grown to handle data fetching, a stats summary section, a chart, and a recent-activity feed all in one 400-line file. Applying the 'and' test revealed it was really four responsibilities; splitting it into a DashboardContainer (data fetching) rendering StatsSummary, ActivityChart, and RecentActivityFeed made each piece independently testable and much easier to navigate.

function DashboardContainer() {
  const { data } = useDashboardData();
  return (
    <>
      <StatsSummary stats={data.stats} />
      <ActivityChart data={data.activity} />
      <RecentActivityFeed items={data.recent} />
    </>
  );
}

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Placing a component's test file in a separate, disconnected top-level tests/ folder

Button/ Button.tsx Button.test.tsx // colocated, not in a separate tests/ folder

The Solution //

Colocate the test file directly next to the component's implementation instead, so they're discovered and updated together whenever the component changes.

The Error //

A component keeps growing because new, loosely related features keep getting added to it

// Before: one component doing three jobs function SearchPage() { /* form + table + pagination */ } // After: three focused components function SearchPage() { return <><SearchForm /><ResultsTable /><Pagination /></>; }

The Solution //

Apply the 'and' test periodically as a component grows — as soon as its description needs 'and', extract the additional responsibility into its own component.

Lesson Glossary

[01]Colocation

Keeping a component's implementation, styles, tests, and stories together in one dedicated folder.

Code Preview
Button/{Button.tsx, Button.test.tsx}

[02]Presentational Component

A component that only renders UI from its props, with no data-fetching or business logic.

Code Preview
function UserProfileView({ user })

[03]Container Component

A component that handles data-fetching or business logic and passes results down as props.

Code Preview
function UserProfileContainer({ userId })

[04]The 'and' Test

A heuristic: if a component's job requires 'and' to describe, it's likely doing too much.

Code Preview
"Renders the form AND the table" → split it

Continue Learning