Progressive enhancement means building apps with basic features that work without JavaScript. Then, enabling more features for users who have JavaScript.
Here’s two things that will definitely sound contradictory:
Most apps don’t need to worry about working without JavaScript1.
It’s still useful to err on the side of progressive enhancement.
Why? I’m glad you asked.
Accessibility. Think about it. When progressively enhanced, you’ll tend to use native HTML elements, use form submissions, buttons, links, etc. This will tend to be more accessible.
Simplicity. Because you’ll use native HTML elements and patterns, there’s less need for client-side state2. If you make React apps (like I do), you can usually have less `useState` and client code in general.
Performance. Again, by letting the browser do more of the work, there’s often less JS code for the browser to run. The code that is there may even be simpler and more focused on little bits of functionality.
Like I said, even if we’re not worried about people browsing the web with JavaScript disabled (which I’m not), progressive enhancement has benefits. It’s not all-or-nothing, either. Just a shift towards it when possible.
This is also why I really like Remix among the full-stack React frameworks. Form submissions are the default way to make things happen. So even though your app does run on the client (after server-side rendering), the “easy path” is more accessible and simpler.
Although do your own analysis, of course
Less need, not no need. It’s fine to still have state or functionality that’s on the client. Sometimes it’s what’s appropriate for a use case.