Frontend Architecture: Managing Complexity in Scale
James Thaura Mweni
Frontend Engineer

The Spaghetti Code Crisis
We've all been there. You start a new React project. `npx create-next-app`.
It feels clean. You put everything in `components/`.
Six months later, you have a file called `Dashboard.tsx` that is 4,000 lines long. It imports 50 other components. It has 20 `useEffect` hooks. It has inline styles. It has complicated business logic mixed with UI rendering.
You change a CSS class in the Navbar, and somehow the Footer breaks.
This is Spaghetti Code. It happens because React is unopinionated. It lets you drive the car off the cliff if you want to.
The Atomic Design Methodology
At Orb21, we define strict boundaries using Atomic Design (popularized by Brad Frost).
1. Atoms (The Basics) These are the smallest building blocks. They cannot be broken down further. They have NO logic. They just render props. - *Examples:* `Button`, `Input`, `Label`, `Icon`, `Text`. - *Rule:* An Atom cannot import another component.
2. Molecules (Simple Groups) Groups of atoms functioning together as a unit. - *Examples:* `SearchBar` (Input + Button), `UserCard` (Avatar + Label + Status). - *Rule:* They can contain atoms but no business logic.
3. Organisms (Complex Sections) Distinct sections of an interface. They form the main parts of the page. - *Examples:* `Navbar`, `Sidebar`, `PricingTable`, `HeroSection`. - *Rule:* These determine the layout of molecules. They might accept data props but shouldn't fetch data themselves.
4. Templates (Page Structures) Generic page layouts without data. They define the skeleton.
This hierarchy prevents circular dependencies. An Atom never knows about an Organism.
Separation of Concerns: The Hook Pattern
The Golden Rule: UI Components should NEVER contain business logic or API calls.
Bad Code (Coupled): ```jsx // Profile.jsx const Profile = () => { const [user, setUser] = useState(null); useEffect(() => { fetch('/api/user').then(data => setUser(data)); }, []);
if(!user) return <Spinner />; return <div>{user.name}</div>; } ```
This component is hard to test. You can't test the UI without mocking `fetch`. You can't use the user logic elsewhere.
Good Code (Orb21 Style - Decoupled): ```jsx // useUser.js ( Logic Layer ) export const useUser = () => { // Handle fetching, caching (TanStack Query), error states here return { user, isLoading, isError }; }
// Profile.jsx ( View Layer ) const Profile = () => { const { user, isLoading } = useUser(); if (isLoading) return <Spinner />; if (isError) return <ErrorState />; return <ProfileCard user={user} />; } ```
Why? 1. Testability: We can test `useUser` logic in isolation. 2. Reusability: We can use `useUser` in the Navbar, Settings, and Dashboard. 3. Clarity: The component code reads like a story.
State Management: Keep it Local
Junior devs put everything in a Global Store (Redux/Context). Senior devs push state down as close to where it is used as possible.
Rule: - Is it used by 1 component? Use `useState`. - Is it used by a parent and child? Use Props. - Is it used by the whole app (Theme, Auth)? Use Context. - Is it Server Data? Use React Query / SWR.
Don't use Redux just because you saw a tutorial from 2018. Simple is better.
Stop reading. Start building.
The content is free. The execution requires a team. Find your co-founder in the Forge today.
Enter The Forge