Skip to content
Saad Sultan
Back to Blog
March 2026·9 min

Backend-Driven Configuration vs. Hardcoded Frontends

When the backend and the frontend each have their own copy of "the" config, they drift. One way to stop that.

ArchitectureFrontendAPI DesignMaintainability

Introduction

Many product features depend on configuration: pipeline stages, field definitions, plan limits, or feature flags. You can encode that configuration in the frontend (constants, config files, or env vars) or fetch it from the backend. Each approach has trade-offs. This post is about when to prefer backend-driven config and how to keep the frontend and backend from drifting apart when you do.

When Hardcoding Hurts

Hardcoding is fine when the set of options is fixed and owned by the frontend team. For example, a list of supported date formats or theme names might never change without a deploy. But when the configuration is business-defined or tenant-specific (e.g. pipeline stages per customer, or which fields appear on a form), hardcoding creates problems. Every change requires a frontend deploy. Non-engineers cannot adjust behaviour without going through a release. And if the backend and frontend each have their own copy of "the" pipeline or "the" form schema, they can get out of sync: the backend accepts a stage the frontend does not show, or the frontend sends a field the backend does not expect. That drift causes bugs and slows iteration.

When Backend-Driven Config Helps

Backend-driven config means the server is the source of truth. The frontend fetches pipeline stages, field definitions, or plan limits from the API and renders UI from that data. When the business or the tenant changes config (e.g. renames a stage or adds a field), you change it in one place. The next time the frontend loads or refreshes, it gets the new config. No frontend deploy needed for that change. The backend can also enforce rules (e.g. valid transitions, required fields) so that the API and the UI stay aligned.

Use backend-driven config when:

  • The config is per-tenant or often changed by non-developers.
  • The same config drives validation or behaviour on the server, so having one source of truth avoids drift.
  • You want to ship config changes without a frontend release.

Avoiding Drift

The main risk is that the frontend and backend each have logic that assumes a certain shape. If the backend adds a new stage type or a new field type, the frontend must know how to render it. Two approaches help:

  1. Conventions the frontend can handle: The backend exposes a stable schema (e.g. stage key, label, order; or field key, type, label, required). The frontend renders generically from that schema (e.g. a list of stages, a dynamic form). New keys or new types work as long as they fit the convention. This is "backend-driven UI" in the narrow sense: the server sends structure; the client renders it.

  2. Versioning or feature flags: When you introduce a breaking change to the config shape, version the API or hide the new behaviour behind a flag so the frontend can stay compatible until it is updated. That gives you a window to deploy the frontend and then enable the new config.

Also avoid duplicating validation. If the backend validates transitions or required fields, the frontend can use the same config to show or disable options, but the backend must remain the authority. Do not rely on the frontend to enforce rules that the backend does not also enforce.

Migration: From Hardcoded to Backend-Driven

If you are moving from hardcoded config to backend-driven, do it in steps. First, add an API that returns the config in the shape the frontend already expects. Point the frontend at that API and remove the local constants. Once the frontend reads from the backend, you can evolve the config (add stages, change labels) without touching the frontend. If the frontend currently has logic that assumes a fixed set of options (e.g. "if stage is X, show Y"), refactor that into generic logic that works from the config (e.g. "show the label from config; if this stage has property Z, show the extra widget"). That refactor is the main cost; the benefit is a single source of truth and faster, safer config changes.

Summary

  • Prefer backend-driven config when the config is business- or tenant-specific and when the backend already needs to enforce rules on that config.
  • Keep a single source of truth: the backend owns the config; the frontend consumes it and renders generically where possible.
  • Avoid drift by using a stable schema and by having the backend validate everything the frontend might send. When you change the shape, version or flag the change so the frontend can catch up.

Have thoughts on this post or questions? Get in touch. More blog posts.