How Functional Programming Shaped (and Twisted) Frontend Development Published on 04 Oct 2025 by Ahmad Alfy --- Introduction Modern frontend development is deeply influenced by functional programming (FP) principles like immutability, determinism, and side-effect elimination. This shift brought powerful constructs such as React components, Redux state management, and TypeScript types. However, this FP-driven paradigm often conflicts with the web's original design: a mutable, side-effectful platform based on documents, hyperlinks, and cascading styles. The pursuit of purity leads to reinventing browser features in JavaScript, adding complexity rather than embracing the web's natural idiosyncrasies. --- The Nature of the Web The web is inherently side-effectful: CSS cascades globally, allowing styles to emerge through inheritance and specificity. The DOM is a mutable tree optimized for direct manipulation. User interactions are asynchronous and unpredictable, making pure functions insufficient to model intent. The web's apparent chaos is intentional, enabling scalability, backward compatibility, and interoperability. Functional programming's disdain for mutation, globals, and side effects contradicts this foundation, leading to a defensive approach to the platform. --- Enter Functional Programming Ideals FP advocates pure functions, immutable data, explicit state changes. Before React, libraries like Underscore.js, Lodash, and Ramda popularized FP ideas in JavaScript. React introduced thinking of UI as a function of state. Elm inspired Redux with its pure update functions (state, action) => newState. React Hooks emphasized functional composition, purity, and explicit side effects management with useEffect. FP provided discipline in an era of unmaintainable, spaghetti-like JavaScript codebases. --- How FP Purism Shaped Modern Frontend CSS-in-JS: The War on Global Scope CSS was designed to be global, but FP views global scope as dangerous. CSS-in-JS (styled-components, Emotion) scoped styles to components, but: Added runtime overhead blocking main thread. Involved complex Server-Side Rendering (SSR) hydration. Lost the power of CSS cascade. Tailwind CSS shifted away from runtime generation towards utility classes—compile-time but still fights cascade. Attempts to reintroduce some cascade-like features in Tailwind sparked community backlash due to anti-cascade ideology. Result: ideological opposition to native CSS features. Synthetic Events: Abstracting Away the Platform React synthetic events normalize browser differences and use event delegation. Adds overhead and debugging difficulty. Trains developers to ignore native event APIs. Creates friction working with third-party/custom libraries. The web's native events are well-optimized but sacrificed for FP control. Client-Side Rendering & Hydration: Reinventing the Browser Client-side rendering treats UI as a pure function of state, but: Causes blank screens initially. Breaks progressive rendering and accessibility. Hydration repeats work: Server renders page. Client fetches data again to rehydrate and attach handlers. Doubles network requests and costs. Browser capabilities like streaming HTML and instant interactivity are replaced by heavy JavaScript reconstructions. The Modal Problem: Teaching Malpractice Native <dialog> handles accessibility, focus, keyboard interaction, and scroll control out of the box. Tutorials discourage <dialog> in favor of recreating modals with <div> and manual JS. Developers learn to ignore browser-native solutions. Popular UI libraries replicate this flawed approach due to framework constraints. When Frameworks Can't Keep Up with the Platform Native elements like <dialog> manage their own state, conflicting with React's JavaScript-controlled state model. Framework authors