Case studies

Nine Ember versions on a concrete logistics platform

Where's My Concrete is an order and delivery management platform for the concrete industry. Dispatchers place and track orders, manage a fleet of mixer trucks, update delivery status as loads move, and talk to drivers from the same screen. We built and maintained the Ember.js dashboards behind it. Over the engagement the application was carried from Ember 2.x through to 7.2, a span of nine major versions, without the rewrite that usually forces.

Industry
Construction / logistics
Duration
1600+ hours
Team
2 developers

What the dashboards do

Concrete is an unusual product to deliver. It starts curing the moment it is mixed, so a load is not inventory that can wait in a yard. Every order is a countdown, and a truck sitting idle is a load heading for scrap.

The dashboards carry four things: order tracking, fleet management across the mixer trucks, delivery status updated as loads move, and chat between dispatch and drivers. A dispatcher watching that screen is deciding which truck takes the next pour and whether a site is ready to receive it, with the clock running on concrete that is already mixed.

Nine major versions without a rewrite

We picked the application up on Ember 2.x and left it on 7.2. That is nine major versions, and it covers the hardest stretch in the framework’s history: the Octane edition rewrote the object model, the component lifecycle and the reactivity system, and classic components were superseded entirely.

Most applications that started on Ember 2.x did not survive that. They either froze on an old version and became unmaintainable, or they were rewritten in something else at enormous cost. This one moved continuously instead, which is only possible if somebody is doing the upgrade work in the gaps between features rather than deferring it until the version goes end of life.

Migrating the build to Vite

The jump from 4.12 to 6.12 replaced the build system, moving from the legacy pipeline to Vite.

Build migrations are deceptively risky. The application code barely changes, so there is little to review, but everything about how assets are resolved and served changes underneath it. We verified the fix for application root path handling in the built output rather than in the dev server, because those two disagree in exactly the ways that ship broken. The one failure we hit in that migration was the CI runner’s Node version, not the code.

Classic components to Glimmer

Three of the application’s largest classic components were rewritten as Glimmer components.

Glimmer changes when values are read, not just how components are declared. State that a classic component computed lazily can end up read during construction, and a rewrite that looks behaviourally identical can quietly change what is tracked and when. Every one of these was verified in the browser rather than by reading the diff.

The bug that only appeared when nobody was looking

An assertion failure surfaced on dashboards that had been left open and idle.

The cause was a getter for orders reading from a live query while records were being unloaded underneath it, mid-render. Under the old version it never showed, because the computed property depended on the collection’s reference rather than its contents, so the unload was invisible to it. Octane’s tracking is finer-grained and noticed. The fix was to defer the work until after render rather than to suppress the assertion.

That is the shape of most upgrade bugs. Nothing is newly broken; the framework simply stopped hiding something that was always wrong.

Scale

Over 1600 hours, delivered by two developers working inside the client’s engineering process rather than alongside it. Our scope was the Ember dashboard frontend, not the full stack.

Status

Engagement completed and delivered. The platform runs on the work described here.

What next

Running something like this?

The engineers who built this are the ones you would work with. Tell us what you have and we will tell you plainly whether it is work we should take.