jQuery: the universal browser API the web needed
This is the first post in a series I'm calling The Web We Inherited. I want to revisit the tools and people whose work became part of the web beneath us. These are projects I learned from and depended on. Some became so common that I stopped noticing them at all.
I want to give their authors their due. I also want to understand which technical decisions made the work last and what those decisions can teach us about the developer platforms, SDKs, and APIs we build today.
I want to begin with jQuery. It shaped how I wrote JavaScript, and the community around it changed how I thought about the web.
The first web conference I attended was jQuery Conference 2010: Boston. John Resig and Richard Worth gave the keynotes. Paul Irish spoke about HTML5, and Alex Sexton gave a talk called "jQuery's Best Friends." Rebecca Murphey, Yehuda Katz, Scott Gonzalez, Doug Neiner, and many others from the jQuery community were there. An amazing amount of web talent was concentrated in one place.
Boston was part of the story. jQuery had been gathering people there since 2007, and Bocoup hosted the 2010 training day from its loft. The city and the community around jQuery felt like an incubator for people who would go on to shape browsers, libraries, standards, developer tools, and the way frontend teams worked.
That weekend became a jumping-off point for me. The conference made the people and the thinking behind code I used every day feel real. From where I stood, the web exploded over the following year and JavaScript took off. The program was already reaching into HTML5, mobile interfaces, application structure, and testing. People were working out the next version of web development in talks and hallway conversations.
jQuery arrived when "the browser" was really a collection of incompatible implementations. Event models differed. DOM methods disagreed. Ajax required branches. Even finding the same elements could produce different behavior.
jQuery gathered that everyday work into a small API, tested it across browsers, and made the ugly branches somebody else's problem. DOM scripting, CSS selectors, animation, and Ajax all had prior histories. jQuery made them feel like parts of one system.
John Resig (LinkedIn, X) assembled and released jQuery. Generations of volunteers followed, represented today by the jQuery team and core maintainers Timmy Willison, Richard Gibson, and Michał Gołębiowski-Owczarek.
Plugin authors, documentation writers, bug reporters, test-case reducers, mailing-list helpers, conference organizers, educators, sponsors, and application developers turned their library into a shared layer of the web.

John Resig speaking at JSConf US in April 2010. Photo by JS Conf, resized from the original, via
Wikimedia Commons
and licensed CC BY 2.0.
The video that sent me into the source
Paul Irish (LinkedIn, X)'s 2010 screencast "10 Things I Learned From the jQuery Source", rerecorded after his TXJS talk, changed how I looked at libraries. He opened jQuery and walked through the JavaScript patterns, browser workarounds, and design decisions below $(). Libraries stopped looking like black boxes. I started reading their source to understand the language, and that habit still shapes how I evaluate developer platforms.

Watch Paul Irish walk through the jQuery source on YouTube.
One API for a room full of incompatible outlets
Imagine that every electrical outlet in a building has a different shape. One room needs a round plug, another a flat plug, and a third requires you to wiggle the switch twice before anything happens.
jQuery was the adapter panel. A developer described what to find and what to do. jQuery translated that request into the browser-specific operations underneath.

The $() call finds every element matching the CSS-style selector and wraps those elements in a jQuery object. .addClass() updates the collection, returns a chainable object, and hands it to .attr(), then .on(). The developer does not write an explicit loop or a separate browser branch.
That chain is not an asynchronous pipeline. Most mutating and traversal methods return the same collection or a related one, which makes another call possible immediately. Getter forms such as .attr("aria-live") return a value and end the chain. Plugins can join the same vocabulary by adding methods to $.fn, the prototype shared by jQuery objects.
The small syntax hid a large promise: the selection, manipulation, event, and effect should mean the same thing wherever jQuery said it supported the browser.
August 2005: the selector experiment
The idea appeared in public before the library did.
On August 22, 2005, Resig published "Selectors in Javascript". He had been studying Ben Nolan's Behaviour library, which associated CSS-like selectors with functions, but found its declarations too verbose and its hierarchical selection awkward. His alternative already contained the recognizable shape of jQuery: select #foo ol li, set an attribute, bind a click handler, narrow the selection, change a style, and keep chaining.
This was part of a lineage. Simon Willison's getElementsBySelector, Dean Edwards's cssQuery, Prototype, Behaviour, and other libraries were exploring how JavaScript could work more naturally with documents. Resig later explained the path to jQuery: several experiments and small libraries coalesced around the gap between the JavaScript language and the cumbersome browser DOM.
He finished the first release over winter break while still in college. On January 14, 2006, he introduced "jQuery: New Wave Javascript" at BarCampNYC. His contemporary write-up appeared two days later. The public jQuery history records the mailing list, first third-party plugin, and project blog arriving before the end of that month.
The project moved quickly, but not fully formed. Ajax entered the core in February. Licensing, source access, documentation, tests, and project organization evolved through the year. jQuery 1.0 arrived on August 26, 2006, almost exactly a year after the selector post.
One collection, one fluent vocabulary
jQuery's deepest ergonomic decision was the collection, not the $ character.
Native DOM APIs historically returned a single element here, a live collection there, and another array-like object somewhere else. Operations often required a manual loop. jQuery made selecting one element and selecting fifty feel alike. A method such as .addClass(), .css(), or .on() operated over the collection. Traversal methods such as .find(), .parent(), and .filter() produced another collection.
This made code read in the same order as the intention:
find these things -> narrow them -> change them -> listen to them
The wrapper did not imprison developers in an alternate universe. An indexed jQuery collection exposed its underlying DOM elements, .get() returned them explicitly, and this inside a traditional jQuery event handler was the DOM element. The project later described that coexistence as intentional. jQuery was a layer over the platform, not a replacement programming language.
Overloading $() also compressed common entry points. A string could be a selector or HTML to create. A DOM element could be wrapped. A function could run when the document was ready to manipulate, earlier than waiting for every image to finish. The surface was approachable enough for a beginner, while escape hatches remained available for deeper work.
What "works across browsers" required
The famous convenience was backed by unglamorous compatibility engineering.
Consider events. Standards-oriented browsers used addEventListener. Older Internet Explorer exposed attachEvent. One supplied an event argument. Another commonly expected window.event. Event targets, mouse buttons, coordinates, related elements, and removal behavior differed. The jQuery 1.2.6 event source shows both registration paths and a normalization pass that copied properties, turned srcElement into target, calculated missing page coordinates, and produced a consistent which value.
That normalized object let application code use one handler shape. jQuery also supplied event namespaces, synthetic triggering, and eventually the unified .on() API for direct handlers and delegation. Delegation attached a handler higher in the document and matched events from current or future descendants. Interfaces that changed after initial load could use the same handler.
None of these abstractions was perfect, and some early "magic" later became technical debt. The impressive part was the feedback loop: a browser discrepancy became a reduced test, a patch, and then shared protection for every user of the next release.
"Support" was therefore a test claim, not a hopeful compatibility badge. The core team's stated rule was that a browser counted as fully supported only when jQuery's unit suite ran against it regularly. Those tests checked that the public API produced consistent results, even when the underlying operations differed. An event from a text node, a cloned checkbox, or an Ajax status peculiar to one engine became durable institutional memory. Application teams received that memory by replacing one script file. The project's long-running habit of testing real implementations is as central to its achievement as the fluent syntax. The team's browser-support explanation made the principle explicit.
Plugins made the core larger without making it bigger
Eleven days after the BarCamp introduction, Resig announced Michael Geary's first third-party jQuery plugin, a remote JSON loader. That speed revealed how consequential $.fn would be.
A plugin was simply a method added to the jQuery object prototype. If it returned this, it participated in chaining. It received the same collection semantics and could compose core traversal, data, events, Ajax, and effects. The barrier was low enough that developers built form validators, galleries, lightboxes, table tools, menus, carousels, editors, date pickers, and countless site-specific behaviors without asking the core team to adopt every feature.
The ecosystem was not uniformly excellent. Plugin quality, accessibility, maintenance, and naming varied. But a shared extension shape made components discoverable and transferable between projects. In 2007 the community opened a plugin repository with releases, ratings, demos, documentation, bug reports, and feature requests. Karl Swedberg credited the web team and singled out Mike Hostetler's work establishing it.
The people around the code mattered just as much. Resig's 2006 introduction to the early jQuery teams credited Jörn Zaefferer with rebuilding the test suite, Brandon Aaron with core bug fixes and CSS/DOM work, Mike Alsup with the Form Plugin and improvements flowing back into Ajax, and Swedberg with tutorials and patient help for newcomers. It also described separate development, evangelism, web, and design teams.
Documentation, examples, tests, and answers turned a concise API into a common language.
The platform caught up through collective work
Modern DOM code can select with querySelectorAll, match with matches, edit classes through classList, register events with addEventListener, request resources with fetch, schedule work with promises, and animate through CSS or the Web Animations API. Browser engines now share a broad suite of tests and standards that did not exist in 2006.
That convergence was not jQuery single-handedly turning its API into the platform. Standards authors, browser engineers, library communities, test-suite maintainers, accessibility experts, and developers all shaped it. Some native APIs preceded jQuery. Others evolved beside it. None is a one-for-one copy of the full jQuery behavior.
jQuery did contribute evidence and people. Years of compatibility bugs exposed where specifications or implementations failed developers. In 2011, Yehuda Katz and Paul Irish led a new jQuery Standards Team intended to carry developer needs to standards bodies and browser vendors. The jQuery Foundation later joined W3C and Ecma International, while contributors including Katz, Rick Waldron, Paul Irish, and others participated directly in standards work.
The project wanted browsers to fix their bugs and native APIs to work predictably so libraries could build higher-level value instead of repairing the floor. The jQuery Foundation's 2014 standards essay said as much while also defending the collection API's lasting ergonomics.
As the floor improved, "use the platform" became practical for more projects. That is a shared success, not proof that the adapter was unnecessary when the outlets differed.
"You might not need it" misses the history
For a new site targeting evergreen browsers, native DOM APIs may be enough. A framework may own rendering and events. CSS may handle the animation. fetch may handle the request. Avoiding an unnecessary dependency can be a sound decision.
That deployment decision says very little about what jQuery accomplished.
It made browser behavior tractable when incompatibility was a daily design constraint. It paired selectors with collection semantics, made chaining readable, turned browser bugs into shared tests, gave Ajax and effects a common home, and opened an extension point that let thousands of authors teach the core new tricks. Its documentation and community helped an enormous population move from snippets to structured client-side programs.
Resig recognized the shape and made the first release. The early team turned it into dependable infrastructure. Plugin authors proved the extension model. The jQuery Foundation and today's OpenJS Foundation gave the work an institutional home. Willison, Gibson, Gołębiowski-Owczarek, Dave Methvin, Zaefferer, Aaron, Alsup, Swedberg, and generations of contributors carried the long middle and the still-active present.
The browser platform converged through work across standards groups, browser teams, and library communities. While that was happening, jQuery gave developers a universal-feeling API they could use on the browsers in front of them. A dependency-free querySelectorAll() call in 2026 still rests on the browser convergence that jQuery helped developers wait for.