NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #451 most downloaded on npm
A JavaScript implementation of many web standards
Last release 10 days ago
22 Sep 2026
Release timing varies
gaps range from 2 weeks to 3 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
15 years old
287 releases · first in 2011
Add: missing window.console methods, viz. assert, clear, count, debug, group, groupCollapse, groupEnd, table, time, timeEnd, and trace. All except ass
window.console methods, viz. assert, clear, count, debug, group, groupCollapse, groupEnd, table, time, timeEnd, and trace. All except assert do nothing for now, but see #979 for future plans. (@jeffcarp)childNodes, and the many places in jsdom that use it, much faster. (@Joris-van-der-Wel)Tweak: faster implementation of NodeList.prototype.length, which should speed up common operations like appendChild and similar. (@Joris-van-der-Wel)
NodeList.prototype.length, which should speed up common operations like appendChild and similar. (@Joris-van-der-Wel)One column per quarter.
Fix: HTMLInputElement.prototype.checked and defaultChecked now behave per the spec. (@Joris-van-der-Wel)
HTMLInputElement.prototype.checked and defaultChecked now behave per the spec. (@Joris-van-der-Wel)HTMLOptionElement.prototype.selected now behaves per the spec. (@Joris-van-der-Wel)HTMLInputElement.prototype.value now behaves per the spec. (@Joris-van-der-Wel)HTMLTextAreaElement.prototype.value and defaultValue now behave per the spec. (@Joris-van-der-Wel)HTMLTextAreaElement.prototype.defaultValue now has a setter, and HTMLTextAreaElement.prototype.textLength now exists. (@Joris-van-der-Wel)<form> now behaves per spec for all different types of form elements. (@Joris-van-der-Wel)document.cloneNode now works. (@AVGP)hasAttribute is now case-insensitive, as it should be. (@AVGP)div.toString() now returns [object HTMLDivElement]. (@AVGP)Fix: check if module.parent exists before using it to construct a document's initial URL. Apparently some testing frameworks like Jest do not correctl
module.parent exists before using it to construct a document's initial URL. Apparently some testing frameworks like Jest do not correctly emulate the module environment; this compensates. (@SegFaultx64)Fix: changing attributes on elements will now have the correct consequences. For example changing the id attribute now interacts correctly with docume
<option> elements will now have the correct consequences. For example changing the id attribute now interacts correctly with document.getElementById. (@Joris-van-der-Wel)Add: moved focus and blur methods to HTMLElement.prototype, instead of having them only be present on certain element prototypes. Our focus story is s
focus and blur methods to HTMLElement.prototype, instead of having them only be present on certain element prototypes. Our focus story is still not very spec-compliant, but this is a step in the right direction. (@vincentsiao)Tweak: improve performance of Node.prototype.insertBefore, Node.prototype.removeChild, and several AttributeList methods. (@Joris-van-der-Wel)
Node.prototype.insertBefore, Node.prototype.removeChild, and several AttributeList methods. (@Joris-van-der-Wel)Fix: querySelectorAll correctly coerces its argument to a string; notably this allows you to pass arrays. (@jeffcarp)
querySelectorAll correctly coerces its argument to a string; notably this allows you to pass arrays. (@jeffcarp)data setter on text nodes correctly coerces the new value to a string. (@medikoo)document.toString() now returns [object HTMLDocument]. (@jeffcarp)Fix: handling of element parsing and serialization, now that it is supported by parse5. (@inikulin)
<template> element parsing and serialization, now that it is supported by parse5. (@inikulin)Add: NodeFilter, in particular its constants. (@fhemberger)
NodeFilter, in particular its constants. (@fhemberger)history.length should be 1, not 0. (@rgrove)history.pushState and history.replaceState should not fire the popstate event. (@rgrove)Add: document.implementation.createHTMLDocument(). (@fhemberger)
document.implementation.createHTMLDocument(). (@fhemberger)localName was sometimes null for elements when it should not be. (@fhemberger)Update: no longer requiring separate cssstyle and cssstyle-browserify dependencies; now cssstyle can be used directly. This also un-pins the cssstyle
cssstyle and cssstyle-browserify dependencies; now cssstyle can be used directly. This also un-pins the cssstyle dependency so that future fixes arrive as they appear upstream.Fix: temporarily pin cssstyle dependency to at most 0.2.18 until chad3814/CSSStyleDeclaration#20 is fixed.
cssstyle dependency to at most 0.2.18 until chad3814/CSSStyleDeclaration#20 is fixed.dependencies instead of devDependencies. (@Sebmaster)jsdom.env in a browser environment now correctly defaults options.url to location.href instead of trying to infer a reasonable fil:// URL using techniques that fail in the browser. (@rattrayalex)Fix: the return value of EventTarget.prototype.dispatchEvent should be true when the default is *not* prevented; previously it was the opposite. (@eve
EventTarget.prototype.dispatchEvent should be true when the default is not prevented; previously it was the opposite. (@eventualbuddha)For a consolidated list of changes from 0.11.1 to 1.0.0, see this wiki page.
For a consolidated list of changes from 0.11.1 to 1.0.0, see this wiki page.
EventTarget.getListeners; EventTarget.forwardIterator; EventTarget.backwardIterator; EventTarget.singleIterator.document.innerHTML. (@jorendorff)value and defaultValue properties of a HTMLInputElement are now correctly synced to the value="" attribute. (@Sebmaster)Remove: support for old, untested HTML and XML parsers, namely davglass/node-htmlparser and isaacs/sax-js. In the future we plan to work toward a stan
document.write) and parsing disconnected fragments (for document.innerHTML). (@Sebmaster)parsingMode configuration, to allow you to manually specify XML or HTML. (@Sebmaster)<?xml or similar to attempt to auto-detect XHTML documents. Instead, it will by default treat them the same as browsers do, with the <?xml declaration just being a bogus comment. If you need your document interpreted as XHTML instead of HTML, use the parsingMode option. (@Sebmaster)getElementsByTagName, querySelector, etc.) to improve performance. (@ccarpita)Fix: another parsing issues with void elements and innerHTML, this time related to disconnected nodes. This was a regression between 0.11.1 and 1.0.0-
innerHTML, this time related to disconnected nodes. This was a regression between 0.11.1 and 1.0.0-pre.1. (@paton)Fix: sometimes calling window.close() would cause a segfault. (@paton)
window.close() would cause a segfault. (@paton)Fix: attributes and elements now have their prefix, localName, and namespaceURI properties set correctly in all cases. (Excepting application/xhtml+xm
prefix, localName, and namespaceURI properties set correctly in all cases. (Excepting application/xhtml+xml mode, which jsdom does not support yet.) (@Sebmaster)Fix: parsing and serialization of attributes in the form x:y, e.g. xmlns:xlink or xlink:href. This was a regression between 0.11.1 and 1.0.0-pre.1. (@
Fix: parsing and serialization of attributes in the form x:y, e.g. xmlns:xlink or xlink:href. This was a regression between 0.11.1 and 1.0.0-pre.1. (@Sebmaster)
Fix: void elements no longer parsed correctly when using innerHTML. This was a regression between 0.11.1 and 1.0.0-pre.1. (@Sebmaster)
jsdom.level: levels are deprecated and will probably be removed in 2.0.0
This is a prerelease of jsdom's first major version. It incorporates several great additions, as well as a general cleanup of the API surface, which make it more backward-incompatible than usual. Starting with the 1.0.0 release, we will be following semantic versioning, so that you can depend on stability within major version ranges. But we still have a few more issues before we can get there, so I don't want to do 1.0.0 quite yet.
This release owes a special thanks to @Sebmaster, for his amazing work taking on some of the hardest problems in jsdom and solving them with gusto.
<html>, <head>, or <body> in their source. We also use parse5 for serialization, fixing many bugs there. (@Sebmaster)jsdom.createWindow: use document.parentWindow after creating a documentjsdom.html: use jsdom.jsdomjsdom.version: use require("jsdom/package.json").versionjsdom.level: levels are deprecated and will probably be removed in 2.0.0jsdom.domjsdom.browserAugmentationjsdom.windowAugmentationjsdom.jsdom no longer takes a level as its second argument.jsdom.jQueryify now requires a jQuery URL, since always picking the latest was a bad idea.document.createWindow: use document.parentWindowdocument.innerHTML and document.outerHTML: use the new jsdom.serializeDocument to include the DOCTYPE, or use document.documentElement.outerHTML to omit it.jsdom.env. (@michaelmior)EventTarget.prototype.dispatchEvent. (@Joris-van-der-Wel)eventPhase and currentTarget on events, before and after a dispatch. (@Joris-van-der-Wel)document.cookie = null to not throw, but instead just do nothing. (@kapouer)Add: Node.prototype.parentElement. (@lukasbuenger)
Node.prototype.parentElement. (@lukasbuenger)'' when not present, instead of null. (Note that getAttribute still returns null for them). (@thejameskyle)textContent now works for nodes that do not have children, like text nodes for example. (@hayes)jsdom.jQueryify was using the wrong URL for jQuery by default. (@lukasbuenger)Add: new default level, living, reflecting our focus on the DOM Living Standard and the HTML Living Standard, which are what browsers actually impleme
living, reflecting our focus on the DOM Living Standard and the HTML Living Standard, which are what browsers actually implement. This should open the door for more features of the modern DOM and HTML specs to be implemented in jsdom. (@robotlovesyou)Node.prototype.contains now implemented. (@robotlovesyou)navigator.cookieEnabled now implemented; it always returns true. (@Sebmaster)name property uppercased during parsing, and appear in the output of document.innerHTML.Node.prototype.compareDocumentPosition implemented correctly; various document position constants added to the Node constructor. (@robotlovesyou)DocumentType.prototype.parentNode now returns the document node, not null. (@robotlovesyou)navigator properties are now getters, not data properties. (@Sebmaster)jsdom.jQueryify. (@Sebmaster)Add: remaining URL properties to window.location and HTMLAnchorElement.
window.location and HTMLAnchorElement.String.prototype.normalize, which is available by default in Node 0.11.13 onwards, caused reflected attributes to break. (@brock8503)about:blank when the src attribute is empty or missing. (@mcmathja)Fix: the list of void elements has been updated to match the latest HTML spec.
/: i.e. the result is now <br> instead of <br />.Fix: another case was found where jQuery 1.11's show() method would cause errors.
show() method would cause errors.querySelector and querySelectorAll methods to DocumentFragments. (@Joris-van-der-Wel)Fix: various defaults on HTMLAnchorElement and window.location should not be null; they should usually be the empty string.
HTMLAnchorElement and window.location should not be null; they should usually be the empty string.Fix: Using jQuery 1.11's show() method would cause an error to be thrown.
show() method would cause an error to be thrown.window.location properties were not updating correctly after using pushState or replaceState. (@toomanydaves)Fix: window.location.port should default to "", not null. (@bpeacock)
window.location.port should default to "", not null. (@bpeacock)Add: a more complete document.cookie implementation, that supports multiple cookies. Note that options like path, max-age, etc. are still ignored. (@d
document.cookie implementation, that supports multiple cookies. Note that options like path, max-age, etc. are still ignored. (@dai-shi)Add: implement attribute ordering semantics from WHATWG DOM spec, and in general overhaul attribute storage implementation to be much more awesome and
port and protocol to HTMLAnchorElement. (@sporchia)HTMLInputElement not have a type attribute by default. It still has a default value for the type property, viz. "text". (@aredridel)getAttributeNS, hasAttributeNS, and setAttributeNS functions. (@lddubeau)Add: store and use cookies between requests; customizable cookie jars also possible. (@stockholmux)
NamedNodeMap no longer break jsdom. (@papandreou)removeAttributeNS should not throw on missing attributes. (@lddubeau)__proto__, __defineGetter__, and __defineSetter__ usage, as part of a project to make jsdom work better across multiple environments. (@lawnsea)Add: hash property to HTMLAnchorElement. (@fr0z3nk0)
hash property to HTMLAnchorElement. (@fr0z3nk0)Upgrade: cssom to 0.3.0, adding support for @-moz-document and fixing a few other issues.
cssom to 0.3.0, adding support for @-moz-document and fixing a few other issues.cssstyle to 0.2.6, adding support for many shorthand properties and better unit handling.Fix: avoid repeated NodeList.prototype.length calculation, for a speed improvement. (@peller)
NodeList.prototype.length calculation, for a speed improvement. (@peller)Add: host property to HTMLAnchorElement. (@sporchia)
host property to HTMLAnchorElement. (@sporchia)Fix: stop accidentally modifying Error.prototype. (@mitar)
Error.prototype. (@mitar)getBoundingClientRect method, that returns 0 for all properties of the rectangle, is now implemented. (@F1LT3R)Add: href property on CSSStyleSheet instances for external CSS files. (@FrozenCow)
href property on CSSStyleSheet instances for external CSS files. (@FrozenCow)Add: typed array constructors on the window. (@nlacasse)
window. (@nlacasse)querySelector and querySelectorAll should be on the prototypes of Element and Document, not own-properties. (@mbostock)Fix: when auto-detecting whether the first parameter to jsdom.env is a HTML string or a filename, deal with long strings correctly instead of erroring
jsdom.env is a HTML string or a filename, deal with long strings correctly instead of erroring. (@baryshev)Add: basic window.history support, including back, forward, go, pushState, and replaceState. (@ralphholzmann)
window.history support, including back, forward, go, pushState, and replaceState. (@ralphholzmann)<?xml?> declaration starts the document, will try to parse as XML, e.g. not lowercasing the tags. (@robdodson)createElement are coerced to strings before evaluating.Fix: a casing issue that prevented jsdom from loading on Unix and Solaris systems. (@dai-shi)
window.location.replace was broken. (@dai-shi)Add: working XMLHttpRequest support, including cookie passing! (@dai-shi)
XMLHttpRequest support, including cookie passing! (@dai-shi)window.navigator.noUI property that evaluates to true, if you want to specifically distinguish jsdom in your tests.…the html, url, or file properties. This is a breaking change in the behavior of html, which used to do the same auto-detection logic as the string-onl…
jsdom.env a string is more accurate, and you can be explicit by using the html, url, or file properties. This is a breaking change in the behavior of html, which used to do the same auto-detection logic as the string-only version.jsdom.env's callback. (@airportyh)window.location.href correctly when using jsdom.env to construct a window from a URL, when that URL causes a redirect. (@fegs)window.location object, which includes firing hashchange events when the hash is changed. (@dai-shi)Fix: custom attributes whose names were the same as properties of Object.prototype, e.g. "constructor", would confuse jsdom massively.
Object.prototype, e.g. "constructor", would confuse jsdom massively.Fix: CSS selectors which contain commas inside quotes are no longer misinterpreted. (@chad3814)
<img> elements now fire load events when their src attributes are changed. (@kapouer)Fix: better automatic detection of URLs vs. HTML fragments when using jsdom.env. (@jden)
jsdom.env. (@jden)Fix: URL resolution to be amazing and extremely browser-compatible, including the interplay between the document's original URL, any tags that were se
<base> tags that were set, and any relative hrefs. This impacts many parts of jsdom having to do with external resources or accurate href and src attributes. (@deitch)Make the code parseable with Esprima. (@squarooticus)
package.json field "repository" instead of "repositories" to prevent npm warnings. (@jonathanong)Integrated a new HTML parser, htmlparser2, from fb55. This is an actively maintained and much less buggy parser, fixing many of our parsing issues, in
Integrated a new HTML parser, htmlparser2, from fb55. This is an actively maintained and much less buggy parser, fixing many of our parsing issues, including:
<p> or <td>.innerHTML of <script> tags no longer cuts off the first character."" as their value instead of the attribute name.^.> and <.Fix: make event handlers attached via on more spec-compatible, supporting return false and passing the event argument. (@adrianlang)
on<event> more spec-compatible, supporting return false and passing the event argument. (@adrianlang)textContent more accurate, e.g. in cases involving comment nodes or processing instruction nodes. (@adrianlang)<canvas> behave like a <div> when the node-canvas package isn't available, instead of crashing. (@stepheneb)Fix: on properties are correctly updated when using setAttributeNode, attributeNode.value =, removeAttribute, and removeAttributeNode; before it only
on<event> properties are correctly updated when using setAttributeNode, attributeNode.value =, removeAttribute, and removeAttributeNode; before it only worked with setAttribute. (@adrianlang)HTMLCollections now have named properties based on their members' id and name attributes, e.g. form.elements.inputId is now present. (@adrianlang)Fix: readOnly and selected properties were not correct when their attribute values were falsy, e.g. . (@adrianlang)
readOnly and selected properties were not correct when their attribute values were falsy, e.g. <option selected="">. (@adrianlang)This release, and all future releases, require at least Node.js 0.8.
This release, and all future releases, require at least Node.js 0.8.
jsdom.env configuration. (@xavi-)rowIndex for table rows that are not part of a table would throw. (@medikoo)<img> elements' src properties now evaluate relative to location.href, just like <a> elements' href properties. (@brianmaissy)This release is compatible with Node.js 0.6, whereas all future releases will require at least Node.js 0.8.
This release is compatible with Node.js 0.6, whereas all future releases will require at least Node.js 0.8.
getAttributeNS now returns null for attributes that are not present, just like getAttribute. (@mbostock)"request" dependency pinned to version 2.14 for Node.js 0.6 compatibility.Fix: stylesheets with @-webkit-keyframes rules were crashing calls to getComputedStyle.
@-webkit-keyframes rules were crashing calls to getComputedStyle.features option to jsdom.env.style attribute until the element's style property is touched. (@papandreou)Fix: selectedIndex now changes correctly in response to elements being selected. This makes elements actually work like you would want, especially wit
selectedIndex now changes correctly in response to <option> elements being selected. This makes <select> elements actually work like you would want, especially with jQuery. (@xcoderzach)checked works correctly on radio buttons, i.e. only one can be checked and clicking on one does not uncheck it. Previously they worked just like checkboxes. (@xcoderzach)click() on <input> elements now fires a click event. (@xcoderzach)Fix: Make contextify a non-optional dependency. jsdom never worked without it, really, so this just caused confusion.
contextify a non-optional dependency. jsdom never worked without it, really, so this just caused confusion.Fix: selected now returns true for the first in a if nothing is explicitly set.
selected now returns true for the first <option> in a <select> if nothing is explicitly set.querySelectorAll implementation.Fix: crashes when loading HTML files with tags with no href attribute. (@eleith)
<a> tags with no href attribute. (@eleith)Your coding agent can read these notes before it upgrades. Set up the MCP server →