Four Kitchens: The browser has grown up. Have we?

By Mari Núñez and Andrés Díaz Soto

Over the years, though, the platform evolved. Browsers standardized. APIs matured. ES6 modernized the language. CSS grew far more capable. Many of the problems jQuery once addressed were absorbed directly into the browser.
The platform changed.
The important point is not that every project should avoid frameworks. It is that many of the problems we once solved with external libraries now have first-class support in the browser itself. So, what does that mean in practice?
Frameworks offer guardrails and shared patterns, and that consistency is valuable. But when the tool becomes the starting point for every conversation, it can narrow the range of options we consider. We stop asking what the browser already provides. We begin to treat complexity as the baseline for modern work.

Abstraction solved real problems

When you subscribe to our newsletter!
None of this is particularly flashy. It is simply what the browser now provides.
CSS has evolved as well. Layout systems, transitions, scroll behaviors, and positioning features eliminate entire categories of JavaScript we once considered unavoidable.

When thoughtful choices become defaults

Need to integrate with a device’s native share dialog? There is an API for that.
Before long, you are manipulating a web page. You grab an element, change its content, add a class, and attach a click handler. The browser responds. The page changes. It finally feels tangible.
Need to know when something enters the viewport? There is Intersection Observer.
More than anything, we hope it sparks a conversation.
In our session, “Elevating Drupal Experiences with Vanilla JavaScript,” we’ll share how we’ve used modern browser capabilities to build rich, interactive experiences within Drupal — not by rejecting frameworks, but by pairing Drupal’s strengths with what the browser already does well.
We’ll walk through:
It was a necessary abstraction at the time.

The foundation is stronger than we remember

None of this requires abandoning modern tooling. It simply widens your decision tree. And it costs almost nothing but attention.
If you study computer science or web development, you’ll take an introductory JavaScript course. Everyone starts in a similar place: variables, let and const (or var if you’re old enough), maybe even a conversation about the difference. You write a few functions, do some math, and concatenate some strings. It feels like learning a language in the abstract — technically correct, but removed from real work.
Need to persist data between sessions? Local storage is there.
But even then, JavaScript can feel like a layer you add on top rather than the foundation of the experience itself. And almost inevitably, you move to a library or framework. For many of us, that once meant jQuery.
But over time, thoughtful decisions can quietly become defaults. A subtle assumption can creep in: if something feels modern or interactive, it probably requires a framework.
Add one small pause to your workflow. Before installing a dependency, check the platform. Search MDN. Look up “browser API for…” and see what comes back. You might discover that Intersection Observer replaces the scroll library you were about to add. Or that CSS handles the animation without JavaScript at all.
And the language itself has matured. Modules, promises, async and await, richer array methods, cleaner syntax. These are no longer experimental features. They are part of the platform.
It means keeping a short list of native capabilities in your mental toolkit: MatchMedia. Local storage. Native form validation. ResizeObserver. The goal is not to memorize every API. It is important to remember that vanilla JavaScript is an option.
It means reframing how you evaluate tradeoffs. When a feature request comes in, write down the requirement in plain language before you write down the stack. What actually needs to happen? A modal opens. Content animates on scroll. State persists between visits. Once the behavior is clear, ask whether the browser can already do it.

The hard part is not writing JavaScript. It is knowing what exists.

We may be living through a similar moment with modern frameworks. React and other tools solve meaningful problems. They help teams move quickly and provide structure, especially for developers early in their careers. In many cases, they are exactly the right choice.
Need to react to changes in the DOM without polling? Mutation Observer is built in.
jQuery did not become dominant because developers were lazy. It solved real problems. Browsers were fragmented. There was no consistent way to select elements from the DOM. Event handling varied. AJAX required wrestling with verbose XMLHttpRequest code and awkward callback patterns. jQuery unified those concerns behind a clean, approachable interface: the dollar sign selector, the on method, simple get and post helpers, animations like fadeIn and slideUp.
This is not bad architecture.It is often just unexamined architecture.
While we have been refining our build pipelines and debating frameworks, the browser has continued to evolve. Quietly and steadily. Modern JavaScript is not what it was 10 or even five years ago. Today’s browsers ship with stable, well-documented APIs that address many of the use cases we once handled with libraries.
Need to respond to screen size changes? MatchMedia handles that cleanly.

Join us at DrupalCon Chicago

It shows up in small ways: adding a dependency before exploring a native API, reaching for a heavy client-side solution when progressive enhancement might be enough, and introducing new tooling because that is what modern projects tend to do. Each decision is understandable on its own. Over time, though, they expand the surface area of a project: more dependencies, more upgrades, more maintenance. Fewer dependencies can mean fewer upgrades to manage, fewer compatibility conflicts, and a smaller maintenance surface over time.

  • Where native APIs replaced heavier dependencies
  • Where progressive enhancement simplified complexity
  • Where we had to rethink our own assumptions

The shift is not dramatic. It is behavioral. Instead of beginning with the problem, we sometimes begin with the stack. If an interaction feels dynamic or app-like, we assume it needs something larger.

Similar Posts