TNS
VOXPOP
As a JavaScript developer, what non-React tools do you use most often?
Angular
0%
Astro
0%
Svelte
0%
Vue.js
0%
Other
0%
I only use React
0%
I don't use JavaScript
0%
NEW! Try Stackie AI
Frontend Development / JavaScript

Beyond JSX: Rethinking the Component Model in Frontend

As apps get more complex, JSX (JavaScript XML) struggles. To move frontend development forward, we need to rethink the role of components.
Aug 11th, 2025 10:40am by
Featued image for: Beyond JSX: Rethinking the Component Model in Frontend
Image via Unsplash+.

JSX (JavaScript XML) gave developers a familiar way to write interfaces, blending HTML-like syntax with JavaScript’s power. But as applications scale in complexity, the model surrounding JSX begins to show its age.

The problem isn’t JSX itself, but the assumptions baked into how we use it. To move frontend development forward, we need to rethink the role of components and the structures we’ve built around them.

Components Are Collapsing Under the Weight of Their Own Abstractions

React started with components that were small and focused. They rendered markup based on props, and that was enough. But over time, components have become overloaded. They now handle business logic, data fetching, side effects, state transitions and performance tuning. Instead of being clean units of UI, many now resemble miniature applications.

This creates fragility. A small state change deep in the tree can break functionality somewhere else. Performance dips. Debugging becomes harder. And when every concern is co-located inside the same file, documentation can’t keep up with the complexity that developers are expected to hold in their heads.

Let components describe structure and appearance. Place logic in services or state layers that can be reused and tested independently.

A more resilient approach means untangling these concerns. Let components describe structure and appearance. Place logic in services or state layers that can be reused and tested independently. At the same time, render functions should be predictable and declarative, not juggling orchestration alongside layout.

Function-Based UI Models Struggle With Stateful, Event-Driven Realities

The idea that UI is a function of state sounds elegant on paper. But web applications aren’t simple data pipelines. They respond to events, user input, latency and timing. Treating components as pure functions that re-run on every change creates unnecessary work.

React’s re-render model demands that developers step in with useMemo, useCallback and other tools to avoid waste. These optimizations are layered on top of a reactive system that wasn’t designed for fine-grained updates.

Some modern frameworks take a different route. Instead of re-executing entire functions, they track which parts of the UI depend on which data. When something changes, only that specific part updates. This model does far more than improve performance; it makes behavior easier to reason about. Developers no longer need to anticipate every render and instead can focus on defining how data flows and reacts.

This shift is less about syntax and more about how updates are handled. It reflects a growing realization that precision and clarity matter more than repeating function calls.

Co-Locating Effects With UI Creates Coupling, Not Cohesion

React hooks made it easy to keep logic close to where it’s used. For a while, this felt like good design. Everything was in one place. But over time, this convenience introduced a new kind of mess. Effects for data fetching, animations or subscriptions now sit side by side with layout code.

The problem pertains to entanglement here, instead of just visibility. When effects live in the component body, they’re tied to the lifecycle of that component. They become harder to extract, test and reuse. Slight mistakes in dependency arrays or async logic introduce bugs that are tough to track.

Services, state machines or reactive stores can manage the logic, freeing the component to focus on rendering.

A better pattern places these responsibilities elsewhere. Services, state machines or reactive stores can manage the logic, freeing the component to focus on rendering. For instance, sensitive data workflows might be handled entirely in secure backend services using HIPAA-compliant hosting, ensuring privacy and regulatory alignment.

Likewise, components become easier to understand. They receive state as input and output a view — nothing more. Testing becomes simpler, behavior becomes more reliable and the codebase becomes easier to scale.

Structural Composition Shouldn’t Rely on Tree Nesting

Nesting is the go-to strategy for composing UI in JSX. Want to provide a theme? Wrap your app in a ThemeProvider. Add routing? Add another wrapper. Before long, the component tree is ten levels deep, and most of those layers don’t render any visible output.

This pattern clutters the tree and hides where logic is coming from. Passing data through props or contexts creates a web of implicit dependencies. Tracing what a component depends on or why it behaves a certain way becomes a guessing game.

Modern frameworks are moving toward more flexible composition.

Modern frameworks are moving toward more flexible composition. Instead of wrapping everything in a tree, they let reactive values flow independently. A component can subscribe to a value or state without being buried in a specific structural context. The logic lives outside the visual hierarchy, making the interface flatter and more predictable.

Composition doesn’t need to mean nesting. It can mean relationships between behavior and structure that aren’t physically bound to one another.

JSX Isn’t the Issue, but the Way It’s Executed Holds It Back

It’s clear that JSX offers a crisp and expressive syntax. It lets developers describe UI in a way that reads like HTML and supports JavaScript expressions. The challenge isn’t the syntax itself, but how it’s used at runtime. JSX compiles into function calls that re-run on state changes. This approach ties rendering to function execution, and that’s where problems start.

A better model treats JSX as a description, not a process.

A better model treats JSX as a description, not a process. Instead of rerunning the same functions again and again, the system can compile JSX into a static layout with reactive bindings. When state changes, only the relevant parts update.

Here are a few frameworks that rethink how JSX is compiled and executed:

  • Marko: Compiles JSX-like syntax into streaming output, allowing the browser to begin rendering before all JavaScript is loaded. This approach reduces time-to-interactive and improves perceived performance.
  • Qwik: Resumes execution where it left off on the server rather than rerunning the whole function on the client. This eliminates the need for hydration and makes applications load faster by skipping redundant rendering logic.
  • SolidJS: Uses fine-grained reactivity with compile-time optimizations to update only the parts of the DOM that change. It avoids virtual DOM diffing entirely for a faster, more predictable rendering model.
  • Svelte: Compiles components into highly efficient imperative code that surgically updates the DOM. Svelte shifts work from runtime to build time, resulting in smaller bundles and snappier apps.

JSX can remain the syntax of choice, but it works best when paired with a model that respects stability and minimizes churn.

Components Are Still the Foundation of Every Frontend Idea

Components brought structure to frontend development, and they still play a useful role. But building everything around them places limits on how we model state, behavior and rendering.

The frontend ecosystem has matured. We now understand that state needs to live outside the view, that updates should be precise and that reactivity should be independent of visual structure. Components help organize views, but they shouldn’t manage logic, orchestrate effects or carry the burden of reactivity.

The next wave of frontend development is already arriving.

When we treat components as part of a system instead of the system itself, we unlock more flexible designs. State management becomes more scalable. Views become easier to test. Interfaces become more predictable.

The next wave of frontend development is already arriving. Tools and frameworks are embracing finer-grained reactivity, resumable rendering and clearer boundaries. JSX and components can be part of that future — as long as we’re willing to rethink how they’re used.

Created with Sketch.
TNS DAILY NEWSLETTER Receive a free roundup of the most recent TNS articles in your inbox each day.