NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #2540 most downloaded on crates.io
HTML querying and manipulation with CSS selectors
Last release 4 months ago
18 May 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 46 of 48 stable releases
1 version withdrawn
withdrawn after publishing
3 years old
49 releases · first in 2023
Refactored internal Selection tree access logic to improve maintainability. No public API changes.
html5ever: 0.38.0 -> 0.39.0selectors: 0.36.0 -> 0.38.0cssparser: 0.36.0 -> 0.37.0hashbrown: 0.16.0 -> 0.16.1Selection tree access logic to improve maintainability. No public API changes.pedantic and nursery) suggestions to improve overall code quality.NodeRef::md and Document::md implementations into a dedicated serializing/md submodule for better internal organization. No public API changes.Full Changelog: 0.27.0...0.28.0
html5ever: 0.38.0 -> 0.39.0selectors: 0.36.0 -> 0.38.0cssparser: 0.36.0 -> 0.37.0hashbrown: 0.16.0 -> 0.16.1Selection tree access logic. No public API changes.NodeRef::md and Document::md implementations to a dedicated serializing/md
submodule to improve code organization. No public API changes.One column per month.
Introduced Tree::new_element_qualname , allowing creation of elements with a specific html5ever::QualName .
Tree::new_element_qualname, allowing creation of elements with a specific html5ever::QualName.Element::add_class for both empty and existing class attributes.Element::remove_class using a Vec-based approach, preserving the original class order while improving performance.Tree::new_element. Previously, manually created void elements could serialize with closing tags due to the wrong namespace. Elements created during HTML parsing were not affected.Full Changelog: 0.26.0...0.27.0
Tree::new_element_qualname, which allows to create a new element with specific html5ever::QualName.Element::add_class for both empty and pre-existing class attributes.Element::remove_class now uses a Vec-based approach to remove classes, preserving the original order and improving performance.Tree::new_element that caused manually created void elements
to serialize with closing tags (elements created during parsing were not affected).Refactored internal TreeNodeOps methods; no functional or API changes.
html5ever: 0.36.1 → 0.38.0tendril: 0.4.3 → 0.5.0selectors: 0.35.0 → 0.36.0TreeNodeOps methods; no functional or API changes.NodeRef::immediate_text now returns text for text nodes, not only the immediate text of child elements.Full Changelog:
0.25.1...0.26.0
Update dependencies:
html5ever: 0.36.1 -> 0.38.0tendril: 0.4.3 -> 0.5.0selectors: 0.35.0 -> 0.36.0Refactor internal TreeNodeOps methods. No functional changes.
NodeRef::immediate_text now returns text for text nodes, not just immediate text of elements.Release Notes for 0.25.1 (2026-01-18)
Rolled back dependencies due to an upstream issue (details in #168):
html5ever: 0.37.1 → 0.36.1tendril: 0.5.0 → 0.4.3Reverted code changes introduced to maintain compatibility with newer versions of html5ever and tendril.
Full Changelog: 0.25.0...0.25.1
html5ever: 0.37.1 -> 0.36.1tendril: 0.5.0 -> 0.4.3html5ever and tendril compatibility.Release Notes for 0.25.0 (2026-01-17)
Updated dependencies:
selectors: 0.33.0 → 0.35.0html5ever: 0.36.1 → 0.37.1tendril: 0.4.3 → 0.5.0Refactored internal code to stay compatible with the latest html5ever and tendril APIs.
Reworked the internal structure of the markdown feature; no public API changes.
ul, ol), resulting in more correct and predictable Markdown output.Full Changelog: 0.24.0...0.25.0
Update dependencies:
selectors: 0.33.0 -> 0.35.0html5ever: 0.36.1 -> 0.37.1tendril: 0.4.3 -> 0.5.0Refactored code to be compatible with the latest changes in html5ever and tendril.
Change internal code structure for markdown feature.
Release Notes for 0.24.0 (2025-11-21) 🚀
Updated internal implementation of NodeRef::find for cleaner logic and improved maintainability.
Exposed TreeNode to the public API.
Dependency updates:
selectors: 0.31.1 -> 0.33.0cssparser: 0.35.0 -> 0.36.0html5ever: 0.35.0 -> 0.36.1Selection.NodeRef::normalized_char_count.Document::from.Document::html.Examples
Changelog
Full Changelog: 0.23.1...0.24.0
Selection.NodeRef::normalized_char_count.Document::from.Document::html.NodeRef::find method.TreeNode.selectors: 0.31.1 -> 0.33.0cssparser: 0.35.0 -> 0.36.0html5ever: 0.35.0 -> 0.36.1Release Notes for 0.23.1 (2025-10-12) 🚀
MDSerializer::find_code_language now uses MDSerializer::find_code_language_css_class as a fallback when it fails to detect the code language from ancestor elements. (by @justahero)title attributes of <a> elements. (by @justahero)Full Changelog: 0.23.0...0.23.1
MDSerializer::find_code_language now uses MDSerializer::find_code_language_css_class as a fallback when it fails to detect the code language from the ancestors (by @justahero).title attributes of <a> elements (by @justahero).markdown is a default crate feature.Release Notes for 0.23.0 (2025-09-28) 🚀
Element::attr_ref method, which returns an &str reference to the attribute value by html5ever::LocalName.html5ever::LocalName and html5ever::local_name for easier access.<pre>-block parsing by checking data-lang and data-language attributes. (by @justahero)<code> blocks are now parsed as <pre> blocks. (by @justahero)NodeRef::find_descendants (requires mini_selector feature). This method now supports the Adjacent (+) and Sibling (~) combinators.Full Changelog: 0.22.0...0.23.0
Element::attr_ref method which returns an &str reference to the attribute value by html5ever::LocalName.html5ever::LocalName and html5ever::local_name.<pre>-block parsing by checking its associated data-lang and data-language attributes (by @justahero)<code> blocks are now parsed as <pre> blocks (by @justahero).NodeRef::find_descendants (requires mini_selector feature). This method now supports Adjacent (+) and Sibling (~) combinators.Release Notes for 0.22.0 (2025-09-03) 🚀
Tree::is_mathml_annotation_xml_integration_point method to check whether a node is a MathML annotation XML integration point.Updated dependencies:
foldhash: 0.1.5 → 0.2.0hashbrown: 0.15.3 → 0.16.0Refactored dom_tree::helpers::normalized_char_count for cleaner implementation.
Set MSRV (Minimum Supported Rust Version) to 1.75.
Full Changelog: 0.21.0...0.22.0
Tree::is_mathml_annotation_xml_integration_point method, which checks whether a node is a MathML annotation XML integration point.foldhash: 0.1.5 -> 0.2.0hashbrown: 0.15.3 -> 0.16.0 (features unchanged)dom_tree::helpers::normalized_char_count.Release Notes for 0.21.0 (2025-08-20) 🚀
Tree::head and Tree::body methods, which return None if the corresponding element is absent (e.g., fragments typically lack <head>/<body>). Added equivalent Document::head and Document::body methods.TreeNode::adjust method; no functional or API changes.Document::create_element. Now the template element precedes its Fragment, allowing HTML trees with templates to be merged more predictably.Document::default()).Full Changelog: 0.20.0...0.21.0
Tree::head and Tree::body methods, which return None if the corresponding element is absent (e.g., fragments typically lack <head>/<body>). Added equivalent Document::head and Document::body methods.Document::create_element. Now the template element precedes its Fragment, allowing HTML trees with templates to be merged more predictably.Document::default()).TreeNode::adjust method; no functional or API changes.Fixed TreeNode::adjust behavior, now considering that another tree may contain template elements.
TreeNode::adjust behavior, now considering that another tree may contain template elements.Refactored TreeNodeOps::normalized_char_count, TreeNodeOps::text_of and NodeRef::has_text methods to use iterator-based traversal.
TreeNodeOps::normalized_char_count, TreeNodeOps::text_of and NodeRef::has_text methods to use iterator-based traversal.NodeRef::is_nonempty_text.Introduced the Selection::select_matcher_iter method, which returns an iterator over all nodes matching the given matcher, without collecting them int
Selection::select_matcher_iter method, which returns an iterator over all nodes matching the given matcher, without collecting them into a result vector. Useful for read-only operations.NodeRef implements Copy trait.selectors from 0.27.0 to 0.30.0
selectors from 0.27.0 to 0.30.0html5ever from 0.31.0 to 0.35.0Fixed the behavior of NodeRef::to_fragment when the node is an element or the root itself.
NodeRef::to_fragment when the node is an <html> element or the root itself.Deprecated methods removed for clarity and maintenance: Tree::append_prev_sibling_of, NodeRef::append_prev_sibling, NodeRef::append_prev_siblings, Sel…
Tree::html_root and Document::html_root methods to get the root element (<html>) node of a document.NodeRef::to_fragment method to create a full copy of a node's contents as a Document fragment.Tree::append_prev_sibling_of, NodeRef::append_prev_sibling, NodeRef::append_prev_siblings, Selection::next.Introduced NodeRef::wrap_node, NodeRef::wrap_html, and NodeRef::unwrap_node methods, allowing a node to be wrapped with another node or HTML fragment,
NodeRef::wrap_node, NodeRef::wrap_html, and NodeRef::unwrap_node methods, allowing a node to be wrapped with another node or HTML fragment, and unwrapped (by @phayes).Tree::validate, a method for performing comprehensive integrity checks on node relationships, links, and cycles within the DOM tree (by @phayes).selectors dependency to version 0.27.0.cssparser dependency to version 0.35.0.html5ever dependency to version 0.31.0.mini_selector::Attribute: attribute values can now be enclosed in either double or single quotes, or left unquoted.entities::Attr visibility to pub.TreeNodeOps::append_child_of and TreeNodeOps::prepend_child_of now internally call TreeNodeOps::remove_from_parent on the new child to ensure it is safely detached from the tree before being reattached. This guarantees that the node has no lingering references (parent or siblings).template serialization in NodeRef::html and NodeRef::inner_html methods.Introduced the NodeRef::strip_elements(&[&str]) method, which removes matched elements while retaining their children in the document tree.
NodeRef::strip_elements(&[&str]) method, which removes matched elements while retaining their children in the document tree.Selection::strip_elements(&[&str]) method, which performs the same operation as NodeRef::strip_elements(&[&str]) but for every node in the Selection.NodeRef::retain_attrs method, which allows retaining only the specified attributes of a node.Selection::retain_attrs method, which performs the same operation as NodeRef::retain_attrs but for every node in the Selection.NodeRef::element_ref method, which returns a reference to the underlying Element if the node is an element node.
NodeRef::element_ref method, which returns a reference to the underlying Element if the node is an element node.NodeRef::qual_name_ref method, which returns a reference to the qualified name of the node.NodeRef::has_name method, which checks if the node is an element with the given local name.NodeRef::is_nonempty_text method, which checks if the node is a non-empty text node.DescendantMatches (based on DescendantNodes) will be used as the internal iterator, which provides a faster approach and doesn't require an additional check for result duplicates. In the other case, Matches will be used, which, as previously, performs a check for duplicates.<NodeRef as selectors::Element>::is_link, which now always returns false since its effect on matching elements is unclear and it adds some overhead.Fixed another issue where DescendantNodes could traverse beyond the initial node when iterating over descendants, affecting NodeRef::descendants and N
DescendantNodes could traverse beyond the initial node when iterating over descendants, affecting NodeRef::descendants and NodeRef::descendants_it, e.g., when the tree had been modified.Improved markdown serialization for NodeRef:
markdown serialization for NodeRef:
\n\n\ after elements that require a newline at the end if \n\n is already present.code elements, except for the ` character.Implemented the markdown feature, which allows serializing a Document or NodeRef into Markdown text using the md() method.
markdown feature, which allows serializing a Document or NodeRef into Markdown text using the md() method.mini_selector feature, providing a lightweight and faster alternative for element matching with limited CSS selector support.
This includes NodeRef additional methods: find_descendants, try_find_descendants, mini_is, and mini_match.Selection::select now returns nodes in ascending order if there were multiple underlying root nodes. If there was only one root node, it still returns nodes in ascending order, just as before.Implemented the Node::id_attr and Node::class methods, which return the id and class attributes of the node, respectively. The Selection::id and Selec
Node::id_attr and Node::class methods, which return the id and class attributes of the node, respectively. The Selection::id and Selection::class methods do the same for the first node in the selection.bit_set::BitSet instead of foldhash::HashSet for the Matches::next method. Since it is necessary to ensure there are no duplicates in the Matches result, and this check needs to be as cheap as possible, bit-set was chosen.NodeRef::formatted_text implementation: moved related code to a separate module, extended the formatting logic, and added more test cases.DescendantNodes could traverse beyond the initial node when iterating over descendants. This affected NodeRef::descendants and NodeRef::descendants_it.Nothing published for this version
Updated html5ever dependency to version 0.29.1.
html5ever dependency to version 0.29.1.NodeRef::find to correctly collect nodes when there is only one item in the path slice.Corrected NodeRef::normalized_char_count behavior for various cases.
NodeRef::normalized_char_count behavior for various cases.Implemented NodeRef::normalized_char_count which estimates the number of characters in the text of descendant nodes as if the total string were normal
NodeRef::normalized_char_count which estimates the number of characters in the text of descendant nodes as if the total string were normalized.Document::formatted_text, Selection::formatted_text, and NodeRef::formatted_text, which return formatted text of the document, selection, or node respectively.Implemented NodeRef::is_match and NodeRef::is methods, which allow checking if a node matches a given matcher (&Matcher) or selector (&str) without cr
NodeRef::is_match and NodeRef::is methods, which allow checking if a node matches
a given matcher (&Matcher) or selector (&str) without creating a Selection object.Tree::base_uri, a quick method that returns the base URI of the document based on the href attribute of the <base> element. Document::base_uri and NodeRef::base_uri provide the same functionality. Inspired by Node: baseURI property.NodeRef::find an experimental method to find all descendant elements of a node that match a given path. It is much faster than Selection::select method.Selection's internal code changes aimed at reducing calls to RefCell::borrow and RefCell::borrow_mut.Matches aimed at increasing selection performance.Implemented the atomic feature which switches NodeData from using StrTendril to Tendril . This allows NodeData and all ascending structures, including
atomic feature which switches NodeData from using StrTendril to Tendril<tendril::fmt::UTF8, tendril::Atomic>.
This allows NodeData and all ascending structures, including Document, to implement the Send trait.Selection::set_text method, which sets the content of each node in the selection to specified content.NodeRef::insert_siblings_after method, which allows inserting a node and its siblings after the selected node.NodeRef::before_html method, which allows inserting contents of an HTML fragment before the selected node.
Selection::before_html does the same thing for the every node inside selection.NodeRef::after_html method, which allows inserting contents of an HTML fragment after the selected node.
Selection::after_html does the same thing for the every node inside selection.Selection::prepend_selection method, which prepends nodes from another selection to the nodes in the current selection.RefCell::borrow and RefCell::borrow_mut.NodeRef::append_prev_sibling is deprecated, please use NodeRef::insert_before instead.
NodeRef::append_prev_sibling is deprecated, please use NodeRef::insert_before instead.NodeRef::append_prev_siblings is deprecated, please use NodeRef::insert_siblings_before instead.Tree::append_prev_sibling_of is deprecated, please use Tree::insert_before_of instead.Document::from and Document::fragment now call html5ever::parse_document with the tree_builder option scripting_enabled set to false.
This allows querying into the noscript element.Ord trait for NodeIdNodeRef::insert_after method, which allows to insert a node after the selected node.NodeRef::descendants_it method, which allows iterating over all descendants of a node.NodeRef::descendants method, which returns a vector of all descendants of a node.NodeRef::normalize method, which merges adjacent text nodes and removes empty text nodes.
Document::normalize does the same thing, but across all the document.Document::text method now returns the text content, whereas previously it returned an empty string.Hide visibility of Tree::nodes, which was accidentally exposed in the previous version.
Tree::nodes, which was accidentally exposed in the previous version.Using Tree::merge_with_fn instead of Tree::merge to reduce code duplication.
Tree::merge_with_fn instead of Tree::merge to reduce code duplication.Tree::child_ids_of_it now require rev argument. Set true to iterate children in reverse order.NodeRef::children_it now require rev argument. Set true to iterate children in reverse order.Selection::append_selection and Selection::replace_with_selection.NodeRef::prepend_child method, that inserts a child at the beginning of node content.NodeRef::prepend_children method, that inserts a child and its siblings at the beginning of the node content.NodeRef::prepend_html method, that parses html string and inserts its parsed nodes at the beginning of the node content.Selection::prepend_html method, which parses an HTML string and inserts its parsed nodes at the beginning of the content of all matched nodes.Selection::add_selection, Selection:add_matcher, Selection::add and Selection::try_add to extend current selection with other selections.Selection::append_selection to work with selections with multiple nodes and selections from another tree.Selection::replace_with_selection to work with selections with multiple nodes and selections from another tree.Node::append_child, Node::append_children, Node::prepend_child, and Node::prepend_children: these methods now internally remove the child/children from their previous parent node before attachment.NodeRef::first_element_child: Previously, due to a logic error, the method checked the node itself instead of its child nodes. This could have caused:
Replaced generic types with the concrete type NodeData, simplifying code and improving readability without affecting the public API.
Node::has_text.NodeData, simplifying code and improving readability without affecting the public API.Node with implementations for NodeRef. Node is just an alias for NodeRef.Selection::replace_with_html, Selection::set_html,
Selection::append_html, Node::set_html, Node::append_html, and Node::replace_with_html by using Tree::merge.Selection::filter , Selection::filter_matcher and Selection::try_filter methods that filter a current selection.Selection::filter_selection method that filters a current selection with another selection.NodeRef::replace_with method that allows to replace a node with another one.NodeRef::replace_with_html method that allows to replace a node with a new node created from the given HTML.NodeIdProver trait and implementations for NodeRef and Node. Which allows to call some node functions with a &NodeRef and &NodeId.
Previously these functions required NodeId as a parameter.:only-text that allows selecting a node with no child elements except a single text child node.NodeRef::set_text method, which sets the text content of a node, replacing any existing content.NodeRef::append_prev_siblings method, which allows to prepend other nodes and their siblings before the selected node.<NodeRef<'a> as selectors::Element>::is_empty to correctly handle line breaks, whitespace, and ensure only elements pass the check.Tree::append_children_from_another_tree method.Tree::append_prev_siblings_from_another_tree method.Node::append_children_from_another_tree method.Node::append_prev_siblings_from_another_tree method.Exposed Matcher::match_element since it can be useful outside the crate.
Matcher::match_element since it can be useful outside the crate.impl<'a> selectors::Element for Node<'a>::opaque to work with :has pseudo-element from selectors crate.:has implementation from selectors crate.selectors v0.26.0 switch.Selection methods that required &mut now doesn't require &mut, finally.Document::from, Selection::select and others.rustc-hash to foldhash.Node::ancestors method, that allows to get all or limited number of ancestors of a node.From<Vec<NodeRef<'a, NodeData>>> for Selection<'a>:is() and :where() pseudo-classes.Node::element_children method that returns children nodes, that are node_data::Elements.Node::children_it method that returns an iterator over children nodes.Node::ancestors_it method that returns an iterator over ancestors nodes.Tree:child_ids_of and Tree:child_ids_of_it methods that returns ids of the child nodes as vec and as iterator respectively.Tree:ancestor_ids_of and Tree:ancestor_ids_of_it methods that returns ids of the ancestor nodes as vec and as iterator respectively.Node::immediate_text method returns text of the node without it's descendants.
Selection::immediate_text does the same thing for the every node inside selection.Selection methods that required &mut now doesn't require &mut.
Document::tree.Selection methods that required &mut now doesn't require &mut.struct implementations.Node::append_html and Node::set_html methods for creating children nodes of a single selected node.Tree<NodeData>::new_element, an easy way to create an empty element with a given name.NodeRef::last_child.Node::has_attr method, which returns true if an attribute exists on the node element.
Selection::has_attr does the same thing for the first node inside selection.Node::remove_all_attrs method for removing all attributes of a node.
Selection::remove_all_attrs does the same thing for the every node inside selection.Node::remove_attrs method, a convenient way to remove multiple attributes from the node element.
Selection::remove_attrs does the same thing for the every node inside selection.Node::rename method, which allows to change node's name.
Selection::rename does the same thing for the every node inside selection.*A small breaking change*: From implementation for Document, now it is based on Into and because of that, previous From<&String> implementation will n…
select_single_matcher and select_single methods for Document and Selection.Document::fragment which allows to create a document fragment.From implementation for Document, now it is based on Into<StrTendril> and because of that, previous From<&String> implementation will not work anymore (they are in config). If your code consumes &String, you should use String::as_str() instead.NodeData::Element).Removed a readability examples and related dev-dependencies.
readability examples and related dev-dependencies.Selection::inner_html, Selection::try_html, and Selection::try_inner methods.Fixed Iterator::next for Matches
Iterator::next for MatchesRefactor code due to major changes in html5ever 0.29.0
### Changed - Update dependencies.
### Changed - Update dependencies.
Add support for :has-text and :contains pseudo-classes, which allow to search elements by their text contents. Some example are here.
:has-text and :contains pseudo-classes, which allow to search elements by their text contents. Some example are here.Fix :has selector name comparison. Previously :has behavior worked, even if pseudo-class just started from :has.
:has selector name comparison. Previously :has behavior worked, even if pseudo-class just started from :has.revise matcher::Matcher usage, now selection::Selection's underlying select methods uses matcher::Matcher reference if it possible.
InnerNode<NodeData>.is_comment.dom_tree::NodeData.matcher::Matcher usage, now selection::Selection's underlying select methods uses matcher::Matcher reference if it possible.css::CssString now wraps String instead of StrTendril. Because StrTendril can't be shared between multiple threads without mutex.### Changed - Minor refactoring. ### Fixed - Fix spelling.
Refactor dom_tree.rs -- remove internal macro, revise some functions for better performance.
hashbrown -- which replace standard HashSet and HashMap with it's own implementation.CssString now wraps a StrTendril instead of a String.
CssString now wraps a StrTendril instead of a String.rustc_hash::FxHashSet instead of std::collections::HashSet.rustc_hash::FxHashMap instead of std::collections::HashMap.Replace unsafe code with safe code.
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →