Your Framework Is Replaceable. Your Architecture Is Not.

Published: (February 7, 2026 at 10:05 AM EST)
4 min read
Source: Dev.to

Source: Dev.to

Frameworks are transient by nature.
They emerge, gain traction, dominate discussions for a few years, and are eventually replaced or fundamentally re‑worked. This is not a flaw of frontend development; it is a natural consequence of rapid innovation in tooling, browsers, and developer expectations.

The mistake many teams make is not choosing the “wrong” framework, but assuming that the framework they choose today will still shape their codebase in the same way tomorrow. What should remain stable over time is the business logic of an application: the rules, validations, workflows, and constraints that represent real‑world requirements. Unfortunately, in many frontend projects these two concerns are tightly intertwined.


The Problem: Framework Coupling

In theory, a framework is just a tool and business rules are implemented inside components. At first this feels efficient—everything is close together, the mental overhead is low, and progress is fast. Over time, however, the framework stops being a replaceable detail and starts defining how the system works at its core. Changing the framework then becomes a fundamental rewrite rather than a simple UI tweak.

Typical scenarios that expose this coupling:

  • Migrating to a new framework version
  • Introducing a second UI (e.g., mobile or desktop)
  • Reusing logic in a different environment
  • Improving test coverage in a meaningful way

When the business logic is entangled with framework concepts, extracting it requires pulling in component rendering, lifecycle simulation, and extensive mocking. Small changes ripple through the UI layer even when the underlying rules remain unchanged.

Guiding Principle: Separate by Rate of Change

A useful architectural principle is to separate concerns based on their expected rate of change:

  • Frameworks change quickly.
  • UI paradigms evolve.

Guideline: The UI layer coordinates. The domain layer decides.

  • UI layer – handles user interaction and presentation. It gathers input, invokes application logic, and renders outcomes. It should not contain validation rules, business decisions, or side‑effects.
  • Domain layer – contains the core business rules and workflows, independent of any UI technology.

Example: UI vs. Domain Code

UI‑centric implementation (framework code)

// UI component (framework code)
component CheckoutForm {
  state email = ""

  onSubmit() {
    if (!email.includes("@")) {
      showError("Invalid email")
      return
    }

    const response = http.post("/checkout", { email })

    if (response.ok) {
      navigate("/success")
    } else {
      showError("Checkout failed")
    }
  }

  render() { /* ... */ }
}

Problems:

  • Validation and checkout workflow are locked into component lifecycle, framework state management, and UI‑level error handling.
  • Reusing or testing the logic requires the framework to be present.

Refactored separation (plain domain code)

// Domain / application layer (plain code, no framework)
function validateEmail(email) {
  if (!email) return { error: "Email is required" }
  if (!email.includes("@")) return { error: "Invalid email" }
  return { ok: true }
}

async function submitCheckout(email, httpClient) {
  const validation = validateEmail(email)
  if (validation.error) return validation

  const response = await httpClient.post("/checkout", { email })
  if (!response.ok) return { error: "Checkout failed" }

  return { ok: true }
}
// UI component (framework code) using the domain layer
component CheckoutForm {
  state email = ""
  state error = null
  state loading = false

  async onSubmit() {
    loading = true
    error = null

    const result = await submitCheckout(email, http)

    loading = false

    if (result.error) {
      error = result.error
    } else {
      navigate("/success")
    }
  }

  render() { /* ... */ }
}

Benefits:

  • The domain functions are callable from anywhere (UI, CLI, background jobs, tests).
  • They are testable without rendering a component.
  • They remain reusable even if the UI framework changes, keeping the UI slim and replaceable.

Why This Matters Beyond Testability

  • Risk reduction: Lower migration risk and refactoring cost when frameworks evolve.
  • Longevity: A longer useful lifespan for the codebase.
  • Clarity: Business behavior lives in one place, separate from UI mechanics, improving overall code quality.

Framework upgrades are often assumed to be incremental, but many frameworks change their mental models dramatically. Architecture, therefore, is less about elegance and more about managing risk.

Practical Reflection

If you were forced to replace your frontend framework in five years, ask yourself:

  1. Which parts of your system would survive unchanged?
  2. Which parts would need to be rewritten from scratch?

If the answer is “almost everything needs to be rewritten,” the framework has become your architecture—a choice worth reconsidering.

0 views
Back to Blog

Related posts

Read more »

Risks When Business Logic Is Forgotten

!Cover image for Risks When Business Logic Is Forgottenhttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%...

Bora falar do padrão Strategy?

Se você já se pegou pensando “putz, esse if/else aqui tá crescendo demais” ou “cada nova regra quebra algo que já funcionava”, é bem provável que o padrão Strat...