Why I still care about progressive enhancement
In an era of JavaScript-heavy frameworks, progressive enhancement sounds old-fashioned. It's actually more relevant than ever.

Does your website work with JavaScript turned off? If you've been in web development for any length of time, you'll have heard of progressive enhancement, one of those principles everyone nods along to in talks and blog posts and then quietly ignores in practice. The idea is simple: build the core experience with the most resilient technology (HTML), enhance it with styling (CSS), and layer on interactivity (JavaScript) for browsers and connections that support it. If any layer fails, the layers below still work.
I understand why it's fallen out of fashion. Modern JavaScript frameworks make it easy to build everything as a client-rendered application, and when your entire page is a React component, progressive enhancement feels like it belongs to a different era. But the reasons it mattered haven't gone away, they've just changed shape.
The resilience argument
JavaScript fails more than we like to admit. A CDN goes down, a corporate firewall blocks a script, a browser extension interferes, a mobile connection drops halfway through loading, an older device runs out of memory parsing a 500KB bundle. The GOV.UK team published data showing that roughly 1 in 93 visitors don't get JavaScript, and their audience is the general UK population, not a niche edge case.
When JavaScript fails on a progressively enhanced page, the user still gets content and can still complete core tasks. When it fails on a JavaScript-dependent SPA, the user gets a blank screen or a loading spinner that never resolves.
How this applies to modern frameworks
The good news is that the frameworks are moving back in this direction, even if they don't use the term. React Server Components render HTML on the server. Next.js's App Router serves complete HTML pages before JavaScript hydrates. Remix was built explicitly around progressive enhancement, forms work without JavaScript, and the framework enhances them with client-side behaviour when available.
For the sites I build, this translates into specific practices. Links use actual anchor tags with real hrefs, not click handlers on divs. Forms use proper form elements with action attributes, even when we add client-side validation, the form submits to the server if JavaScript fails. Navigation works without JavaScript. Content is in the HTML, not injected by client-side data fetching.
Where it gets practical
Consider a contact form. The progressive enhancement approach: build it as a standard HTML form that posts to a server endpoint. The server validates the input, processes the submission, and redirects to a thank-you page. Then enhance it with client-side validation for immediate feedback, and use fetch to submit without a page reload for a smoother experience. If JavaScript fails, the form still works. If the client-side validation fails, the server validation catches it.
The alternative, a React component that renders a form, validates entirely in JavaScript, submits via an API call, and shows a success message by updating state, breaks completely if JavaScript doesn't load. The user sees a form that does nothing when they click submit. That's a lost lead.
Not dogma, but discipline
I don't apply progressive enhancement rigidly to everything. A complex data visualisation dashboard can reasonably require JavaScript. An interactive product configurator needs client-side code. The principle isn't "no JavaScript", it's "don't require JavaScript for things that don't need it." Content, navigation, forms, and core functionality should work without it. Enhancements should be exactly that: enhancements.
If you're building something and want to make sure it works for the widest possible audience, I'd be glad to help, get in touch.

Chris Ryan
Managing Director
17+ years in full-stack web development, most of it leading teams agency-side across e-commerce, CMS platforms, and bespoke applications. Specialises in infrastructure, system integration, and data privacy, with hands-on experience as a Data Protection Officer. Founded Innatus Digital in 2020 to offer the kind of honest, technically-led partnership that he felt was missing from the agency world.