Quick Answer: Developers often resist the push to use the platform web development due to historical browser inconsistencies, the ergonomic appeal of framework-specific packages, and the psychological satisfaction of building custom solutions. While native APIs like
<dialog>offer superior performance, the lack of polished documentation and framework integration keeps many tied to heavy JavaScript libraries.
We spend weeks building custom dropdowns, writing complex focus-trapping scripts, and debugging z-index issues. Meanwhile, the browser engine sitting right in front of us has already solved these problems. For years, advocates for web standards have implored us to use the platform web development paradigm. The argument is simple: why build something yourself in JavaScript when the browser can do it for you with better performance and accessibility? Yet, the modern web remains bloated with third-party dependencies. Why do we keep writing custom JavaScript for things the browser does natively?
To understand this resistance, we have to look past lazy accusations of developer incompetence. The tension between native browser APIs and custom-built libraries is rooted in history, developer psychology, and tooling ergonomics.
The Historical Hangover of the Lumpy Web
For the longest time, browsers were playing catch-up with the ecosystem built on top of them. If you built websites in the late 2000s or early 2010s, you remember the pain of the "lumpy web." Browsers did not update automatically, and Internet Explorer 6 lingered like a ghost in enterprise environments long after its expiration date.
During this era, relying on native APIs was a recipe for production failures. Libraries like jQuery filled vital gaps, offering a unified API that smoothed over browser inconsistencies. If you wanted to perform a simple AJAX request or animate an element, writing raw DOM APIs meant writing hundreds of lines of conditional code.
According to historical data from the HTTP Archive, the median mobile page today ships over 370 KB of JavaScript, much of it duplicating native browser behavior. This is a direct inheritance of our historical trauma. We became conditioned to treat the browser as an adversary to be bypassed, rather than a platform to be embraced.
That historical trauma left a deep mark, but it doesn't explain why we still do this today in an era of evergreen browsers.
Why We Resist the Push to Use the Platform Web Development
When you are used to looking for React components on npm, that is what you reach for, regardless of the problem at hand. If you search for "sticky positioning" on npm, there is no package that tells you to just use CSS position: sticky. The ecosystem itself guides us away from native solutions.
Many developers prefer to stick to JSX and framework idioms because raw DOM APIs feel unfamiliar or unergonomic. This creates a natural division of labor. Novice developers use higher-level primitives packaged by experts, while those packages run lower-level DOM manipulations under the hood.
Here is a counter-intuitive finding that contradicts popular advice: using the native platform is not always the safest choice for accessibility.
When the native <dialog> element was first introduced, early implementations had severe accessibility bugs in screen readers. For years, a custom-built, heavily tested ARIA-compliant JavaScript modal library was actually safer for end-users than the native HTML element. This justified the skepticism of developers who prioritized user experience over standards purity.
This ergonomic comfort zone is hard to leave, especially when the act of building it yourself triggers a powerful psychological trap.
The IKEA Effect: Why Building It Yourself is Addictive
For a certain type of developer, building things yourself is just more fun. There is a psychological phenomenon known as the IKEA effect—we place a disproportionately high value on products we partially created.
Let's look at a common failure mode: building a custom modal dialog. Visually, it seems simple. You position a container with position: absolute, add a high z-index, and dim the background. But then you realize the background still scrolls, so you write JavaScript to disable overflow on the body. Then you realize you need to handle the Esc key to dismiss it. Then you discover you need a focus trap so keyboard users don't accidentally tab out of the modal into the background.
// A fragile, custom focus trap that easily breaks
const handleKeyDown = (e) => {
if (e.key === 'Tab') {
const focusables = el.querySelectorAll('button, [href], input');
const first = focusables[0];
const last = focusables[focusables.length - 1];
if (e.shiftKey && document.activeElement === first) {
last.focus();
e.preventDefault();
} else if (!e.shiftKey && document.activeElement === last) {
first.focus();
e.preventDefault();
}
}
};
For many, this sounds like a nightmare. But for others, this is where the fun begins. You learn how the DOM works, how focus states behave, and how to add custom animations. Before you know it, you have built a custom library and published it to npm. This process of discovery is how many of us learned the web platform in the first place.
But even if you love the challenge of building from scratch, there is another silent culprit: how we learn about these APIs in the first place.
The Documentation Deficit and Discovery Problem
Why do developers choose a library like Dragula over the native HTML Drag and Drop API? The answer lies in documentation and presentation.
Many npm packages have beautifully designed landing pages, complete with interactive tutorials, clear screenshots, and copy-pasteable examples. Historically, documentation for native web standards was scattered across academic W3C specifications, personal blogs, and StackOverflow.
While MDN Web Docs has since become the gold standard for web documentation, many of its pages still read like technical reference manuals rather than practical guides. When the platform's documentation feels like a dry academic spec, developers will naturally choose the library with the shiny landing page.
When we compare the implementation costs directly, the difference in complexity becomes stark.
Native APIs vs. Custom JavaScript: A Pragmatic Comparison
To see the real-world trade-offs, let us compare the native <dialog> element against a typical custom React modal implementation.
| Feature | Native <dialog> Element | Custom React Modal Component |
|---|---|---|
| Bundle Size | 0 KB (Built into browser) | 5 KB to 25 KB (Plus dependencies) |
| Focus Trapping | Automatic via showModal() | Requires custom JS or react-focus-lock |
| Backdrop Styling | Easy via ::backdrop CSS | Requires wrapper divs and custom CSS |
| Accessibility (ARIA) | Built-in by default | Must be manually configured and tested |
| Esc Key Dismissal | Automatic | Requires manual event listeners |
This comparison shows that while custom components offer infinite design flexibility, they require significant engineering overhead to match the baseline functionality that the browser provides for free.
That said, there's a real catch here: this tendency to bypass the platform is not unique to frontend web developers.
The Database Parallel: Why This Happens Beyond Frontend
This phenomenon of avoiding the platform applies to any developer working on top of a system they do not fully understand.
Consider a backend scenario involving ClickHouse, a popular columnar database. A team wanted to store large JSON payloads in a column. To optimize performance, they built a custom system to compress the JSON in application code before inserting it into the database.
It turned out they were completely wrong. ClickHouse automatically compresses data using specialized algorithms like LZ4 or ZSTD. Because it is a columnar data store, it achieves far better compression ratios when it can analyze raw, uncompressed data across rows. By pre-compressing the JSON in JavaScript, the team actually disabled ClickHouse's native optimization engine, resulting in 40% slower query times and a larger disk footprint.
This is the exact same mistake we make when we write custom JavaScript to handle layout calculations instead of letting the browser's CSS engine handle it. We build slow, clunky systems because we do not take the time to thoroughly read the documentation of the platform we build upon.
This next part matters more than it looks: how do we break this cycle?
How to Transition From JavaScript Libraries to Native Web Standards
Transitioning back to native standards does not mean deleting all your frameworks overnight. It requires a shift in your decision-making framework.
- Audit Your Dependencies: Use tools like
bundlephobiato identify heavy utility libraries in your bundle. Look for native alternatives for things like deep cloning (structuredClone()), date formatting (Intl.DateTimeFormat), or element resizing (ResizeObserver). - Adopt a Platform-First Mindset: Before installing an npm package, search MDN Web Docs to see if a native API exists. You might find that
IntersectionObservercan replace that heavy scroll-spy library, or that CSS grid can eliminate your complex layout framework. - Build Progressive Enhancements: Use native elements like
<details>or<dialog>as your baseline. If you need custom styling or advanced behavior, layer JavaScript on top of the native element rather than replacing it entirely.
By embracing the platform, you reduce your maintenance burden, improve your application's performance, and build skills that remain relevant long after individual frameworks go out of style.
Frequently Asked Questions
What does it mean to use the platform web development?
To use the platform web development means prioritizing native browser capabilities—such as built-in HTML elements, native CSS features, and standard Web APIs—over third-party JavaScript libraries and framework abstractions. This approach reduces bundle sizes and improves performance.
Why do developers avoid native browser APIs?
Developers often avoid native browser APIs due to historical browser inconsistencies, a lack of framework-friendly ergonomics, and the superior documentation and developer experience offered by third-party npm packages.
How to transition from javascript libraries to native web standards without breaking production?
Start by auditing your bundle for low-hanging fruit, such as replacing utility libraries with native methods like structuredClone(). Gradually refactor complex components by using native elements like <dialog> as the baseline, applying progressive enhancement for custom styling.
If you want to build faster, more resilient web applications, start by auditing your current dependency graph. Try replacing one custom JavaScript component with a native HTML element this week and note the performance difference. Pass this to someone wrestling with bundle size issues, or read our breakdown of modern CSS layout techniques next.