Replacing a jQuery front end one screen at a time

The interface looks like 2012 and every change takes a week. Why a front-end rewrite is rarely the answer, and how to bring in React one screen at a time.

The complaint usually comes from two directions at once. Users say the application looks dated and some screens are painful to work in. Developers say every change to the interface takes far longer than it should, because one page holds four thousand lines of jQuery, three plugins that fight each other, and event handlers attached in ways nobody can trace.

Both are right. And the proposal that follows is nearly always the same: rewrite the front end. A new single-page application, a new design, a clean start.

We almost always recommend against it — not against modern front-end code, but against getting there in one step.

Why the big front-end rewrite stalls

A front-end rewrite looks smaller than a full rewrite, because the backend stays. In practice it carries most of the same risk.

Every screen in a long-lived business application contains behaviour nobody wrote down. A field that becomes read-only when an order is part-shipped. A dropdown filtered by the customer's region. A warning that appears only on the last working day of the month. That logic lives in the jQuery, in the server-side page, and occasionally in a stored procedure called from a postback. A rewrite has to rediscover all of it, screen by screen, and it will miss some.

Meanwhile the old interface still needs changes, because the business does not stop. So the team maintains two front ends, the new one is always behind, and after a year users have seen nothing. This is how front-end rewrites end up quietly cancelled.

The alternative: one screen at a time

Modern frameworks are perfectly happy to live inside an existing page. React, in particular, can be mounted into a single element on a server-rendered page and take charge of that element only. The rest of the page — the menu, the layout, the old screens — carries on exactly as before.

So instead of a new application, you introduce modern components into the existing one, one screen at a time. Users see an improvement within weeks. Each screen ships on its own and can be rolled back on its own. And the hidden rules are rediscovered one screen at a time, with the people who use that screen available to explain them.

After enough screens have moved, the remaining old pages are few enough that replacing the shell around them is a modest final step, not a leap of faith.

The groundwork

Three pieces need to be in place before the first screen moves. None of them is large.

An API for the screen to talk to. A modern component needs data as JSON, not as a rendered page. If the application already has a service layer, this is a thin set of endpoints over it. If it does not, building one is the real first step — we have written about adding an API to an application that never had one, and the same endpoints later serve mobile apps and integrations, so the work is never wasted.

A front-end build. A modern build tool such as Vite, producing a bundle the existing pages include like any other script. The server-side application does not need to know anything about it. Run it as part of the existing build so a deployment remains a single step.

Shared visual foundations. Colours, spacing and typography defined once as CSS variables, used by both the old pages and the new components. Without this, every migrated screen looks like it belongs to a different product, and users notice the inconsistency more than they notice the improvement.

Authentication usually needs no work at all. Because the new components are served from the same site, the browser sends the same session cookie, and the API endpoints can use the same login and the same permissions as the pages around them.

Choosing the first screen

Not the easiest screen. Not the most important one either.

The best first candidate is a screen that users complain about, that is mostly self-contained, and where the improvement will be obvious. Very often that is a data-heavy grid: a list of orders, jobs or tickets that loads slowly, filters awkwardly and cannot be sorted the way people need. Replacing it with a fast, searchable, server-paged grid delivers a visible win in a few weeks, and it exercises every part of the groundwork — the API, the build, the shared styles — on something real.

Avoid starting with the screen that holds the most complicated business rules. That one comes later, when the approach is proven and the team knows the codebase.

Living alongside jQuery

The hybrid period is where projects get into trouble, and it is almost always for the same reason: two pieces of code trying to control the same part of the page.

The rule that prevents it is strict ownership. Each region of the page belongs either to the old code or to a component, never both. jQuery does not reach into a React component to change a value, and the component does not reach out to manipulate the old page. Where they need to talk — the old page needs to know a record was saved, or a component needs the currently selected customer — they do it through a small, explicit channel: a browser event the other side listens for, or a value passed in when the component is mounted.

Third-party control suites deserve a mention. Many older applications rely on commercial grids, charts and schedulers. Most of the major vendors now publish React versions of the same controls, which can make the transition far gentler: the same grid, the same features, the same licence, with a modern component around it. Check that before choosing anything new.

What users notice, and what they do not

Users notice speed, clarity and fewer clicks. They do not notice frameworks. So each migrated screen should be measurably better at the job people use it for — faster to load, quicker to filter, fewer steps to finish the task — not simply the same screen in a newer technology.

Equally, resist redesigning the workflow at the same time as the technology unless users are asking for it. A screen that behaves the same but responds instantly is an easy sell. A screen that has moved every button is a training problem.

When to stop

There is no rule that every screen must move. An admin page used twice a year can stay in jQuery indefinitely. The measure is the same as for any modernization work: move the screens that change often, cause complaints, or block something else, and leave the quiet ones alone.

Done this way, the front end improves continuously instead of all at once. Users see something better every few weeks, the development team gets faster with each screen, and nobody has to bet the business on a launch date. It is stage four of our staged modernization approach, and for most applications it is the stage users remember.

All insights Talk to us about this

Let's work together

Dealing with this yourself?

If this is close to a problem you are living with, we would be glad to hear the details and tell you what we would look at first.