DEV Community

Cover image for What Falling Off a Horse Taught Me About Frontend Architecture
Maria-Lurdes Dehtiarenko
Maria-Lurdes Dehtiarenko

Posted on

What Falling Off a Horse Taught Me About Frontend Architecture

I once fell off a horse during a fast run. My horse got scared and started running at full speed. For a moment I managed to calm him down. Then the rush started again. In one sharp turn I lost balance and fell. That moment taught me something uncomfortable: You can’t force stability in an unstable system.

I’ve seen the same pattern in frontend development.

Working as a frontend engineer at Sombra, I’ve worked on projects where we tried to control complexity by adding more structure - more layers, more state management, more abstraction.

Sometimes it helped. Sometimes it made the system harder to handle.

Lesson 1: Balance Over Force

In horse riding, too much pressure creates resistance. Too little control creates chaos.

Frontend architecture behaves the same.

Overengineering - adding unnecessary layers, heavy global state, or complex abstractions - creates resistance in development.

Angular example:

Introducing a full global state management solution like NgRx for a simple feature module can easily become overengineering. Instead of simplifying the architecture, it adds actions, reducers, selectors, and effects - even when the data is used by only a few components. Suddenly, a small form with 3 fields required 20+ boilerplate files and extra mental overhead.

At the same time, having no structure - like letting multiple components directly call HTTP services or manage shared data without coordination - leads to messy data flow and unpredictable behavior.

Takeaway:

Introduce tools like state management or architectural layers only when complexity truly requires them, not because they feel "enterprise-ready"

Practical tip: If your module has <5 components and minimal shared state, consider local component state or a feature-scoped service instead of NgRx.

Lesson 2: Subtle Control Beats Micromanagement

A rider doesn’t need constant force. Small adjustments are enough.

The same applies to frontend systems.

Instead of micromanaging everything through a heavy global store, prefer:

  • Clean and simple APIs
  • Clear data flow
  • Minimal abstraction
  • Feature-scoped state when possible

Too many layers create friction and increase cognitive load — the mental effort developers need to understand how the system works.

Angular example:

Instead of putting every API call through a global store, you can keep state in a feature service.

For instance, a UserProfileService that holds only the profile state for that module, exposing getProfile() and updateProfile() methods, keeps things predictable without unnecessary boilerplate.

Takeaway: Balance between centralization and local control reduces overhead and makes debugging easier.

Lesson 3: Reacting to Unpredictability

Horses react to sudden changes - noise, movement, fear.

Frontend applications react to:

  • Async behavior
  • Race conditions
  • API failures
  • User-triggered events

When something breaks, the goal is not panic fixes but observation.

Good engineers look for patterns:

What changed? What triggered the issue? Is it reproducible?

Stability comes from understanding behavior - not patching symptoms blindly.

Lesson 4: Reading Signals

Experienced riders read subtle signals - body tension, weight shifts, breathing changes.

In frontend development, signals are everywhere:

  • Logs and warnings
  • Performance metrics
  • Small UI inconsistencies
  • Memory or state leaks

Angular example:

Using Angular’s DevTools, logging services, and ChangeDetectionStrategy can reveal subtle signals before they become major bugs. For instance, a slight lag in change detection may indicate a heavy computation in a component or inefficient subscription handling.

Debugging is interpretation, not brute force. The earlier you detect signals, the smaller the problem becomes.

Conclusion: Engineering Is Communication

You cannot dominate complex systems — you collaborate with them.

With a horse, control comes through balance and timing.

With frontend architecture, control comes through clarity, simplicity, and thoughtful design.

Stability is not something you can force into a system.
It is something you build - through understanding how the system behaves and making careful adjustments over time.

In many cases, stability doesn’t come from adding more layers, tools, or abstractions.
It comes from stepping back, simplifying where possible, and choosing the right level of structure for the problem you are solving.

So I’m curious: Where do you personally draw the line between
good architecture and overengineering?

Top comments (0)