Symphony Apps Development logo — teal interlocking S monogram beside the studio wordmark
All writing

The checkout that had to work with JavaScript disabled

An accessibility requirement we treated as a constraint turned out to make the whole checkout more resilient, including for people with JavaScript on.

Category
Engineering
Reading time
6 min
Published
30 Mar 2026
Topics
Engineering, Quality, Case study

A public-sector client's accessibility requirements included a line we initially treated as a formality: the checkout had to remain usable with JavaScript disabled. It stopped being a formality once we actually tried to build it and found the requirement improved the checkout for everyone, not just the small number of users it was written for.

Why the requirement exists

A minority of users disable JavaScript deliberately, for privacy, performance, or accessibility tooling reasons, and public-sector procurement rightly treats them as users who have to be served, not an edge case to be tolerated. We expected this to mean building a second, simpler checkout in parallel.

What building it actually required

A checkout that works without client-side JavaScript has to do its validation, its state transitions and its error handling entirely server-side, with each step a genuine page load rather than a client-managed state update. That's more constrained than the JavaScript-enabled version we'd normally build first and layer progressive enhancement onto.

What we noticed once it existed

The server-side version was, independently of the accessibility requirement, more robust against a category of bug the JavaScript version had quietly accumulated: state that existed only in the browser and could get out of sync with the server if a request failed partway through. Building the server-side version first forced every piece of checkout state to have a canonical, server-owned representation, because there was nowhere else for it to live.

  • The JavaScript-enabled version became an enhancement on top of the server-side one, not a separate implementation, which meant a bug fixed in one was a bug fixed in both by construction.
  • A failed request left the user on a coherent page reflecting real server state, rather than a client-side view that had drifted from what actually happened, in both versions.
  • Testing got simpler, not harder, because the core checkout logic had exactly one source of truth to test against instead of two.

The instinct we had to overcome

Treating the no-JavaScript requirement as extra scope to be minimised, built quickly and separately from the "real" checkout. Building it as the foundation instead, with JavaScript as enhancement, cost more up front and produced a single, more resilient system rather than two systems to maintain.

An accessibility requirement written for a minority of users is often, quietly, a robustness requirement for all of them.

What we'd tell a client scoping something similar

Ask whether the accessible version can be the primary implementation rather than a parallel one. It's a different way of sequencing the same amount of work, and in this case it produced a better system than building the JavaScript version first ever would have.

Tell us what you’re trying to ship

A first call is thirty minutes and costs nothing. Bring the problem, not a spec — working out what to build is the part we are good at.

Or email office@symphonyapps.ro. We reply within one business day, in English or Romanian.