# turbohtml

> turbohtml is a fast, fully typed HTML toolkit for Python built on a C-accelerated core. It parses WHATWG-conformant HTML into a navigable tree you query with CSS selectors and XPath, edit in place, build from scratch, sanitize, minify, and serialize back to HTML, Markdown, or plain text — each several times faster than its pure-Python counterpart, with a free-threaded build.

The documentation follows the Diátaxis framework: tutorials to learn, how-to guides for tasks, a reference for the API, and explanation for the design. It is organized around eight namespaces — parse/DOM, detect, query, clean, convert, extract, build, serialize — which also group the reference, how-to, and migration indexes.

## Start here

- [turbohtml overview](https://turbohtml.readthedocs.io/en/latest/index.html): what turbohtml is, the design principles, and a runnable example.
- [Tutorials](https://turbohtml.readthedocs.io/en/latest/tutorials/index.html): learning-oriented walkthroughs, read in order.
- [How-to guides](https://turbohtml.readthedocs.io/en/latest/how-to/index.html): task-focused recipes, one job each.
- [Reference](https://turbohtml.readthedocs.io/en/latest/reference.html): the complete public API, grouped by namespace.
- [Explanation](https://turbohtml.readthedocs.io/en/latest/explanation/index.html): how turbohtml is built and why.
- [Migration guides](https://turbohtml.readthedocs.io/en/latest/migration/index.html): port from 57 HTML libraries, mapped to the namespace that replaces each.

## Tutorials

- [Getting started](https://turbohtml.readthedocs.io/en/latest/tutorials/getting-started.html): Go from an empty environment to escaping and unescaping your first HTML.
- [Tokenizing a document](https://turbohtml.readthedocs.io/en/latest/tutorials/tokenizing.html): Go from a string of HTML to a stream of tokens you can inspect.
- [Parsing a document into a tree](https://turbohtml.readthedocs.io/en/latest/tutorials/navigating.html): A token stream is flat.
- [Building and editing a tree](https://turbohtml.readthedocs.io/en/latest/tutorials/editing.html): Everything so far read a document that already existed.
- [Exporting to text](https://turbohtml.readthedocs.io/en/latest/tutorials/exporting.html): Once you have the node you want, `turbohtml.Node.to_markdown` turns it into GitHub-Flavored Markdown in one call, so a scraping script ends with Markdown instead of a tag soup:

## How-to guides

- [Parse HTML into a tree](https://turbohtml.readthedocs.io/en/latest/how-to/parsing.html): Turn markup into a navigable tree with `turbohtml.parse`:
- [Tokenize HTML](https://turbohtml.readthedocs.io/en/latest/how-to/tokenizing.html): Run the WHATWG tokenizer over HTML:
- [Work with forms](https://turbohtml.readthedocs.io/en/latest/how-to/forms.html): Read and set form-control values with form semantics, and collect a form's data the way a browser submit would, through `turbohtml.Element.field_value` and the form helpers.
- [Edit the tree](https://turbohtml.readthedocs.io/en/latest/how-to/editing.html): Change a parsed tree in place:
- [Handle character encodings](https://turbohtml.readthedocs.io/en/latest/how-to/encoding.html): Decode bytes of unknown or declared encoding the way a browser would, and inspect what the sniffer chose, with `turbohtml.parse` and `turbohtml.detect.detect`.
- [Select elements with a CSS selector](https://turbohtml.readthedocs.io/en/latest/how-to/selecting.html): Match descendants against a CSS selector and test a node you already hold.
- [Find elements with the find filter](https://turbohtml.readthedocs.io/en/latest/how-to/finding.html): Search a tree with `turbohtml.Node.find` and `turbohtml.Node.find_all` and the filter grammar they take — strings, regexes, callables, booleans, and lists — applied to the tag, an attribute, the class list, or the collected text.
- [Extract strings and attributes](https://turbohtml.readthedocs.io/en/latest/how-to/extracting.html): Pull plain strings out of a page the way Scrapy's parsel does, with `turbohtml.Element.attr`, `turbohtml.Node.re`, and `turbohtml.Node.re_first`, so scraping code ends with the values it wants rather than nodes.
- [Query a tree with XPath](https://turbohtml.readthedocs.io/en/latest/how-to/xpath.html): Evaluate XPath 1.0 against a node with `turbohtml.Node.xpath`, `turbohtml.Node.xpath_one`, and `turbohtml.Node.xpath_iter`:
- [Inspect a node you already hold](https://turbohtml.readthedocs.io/en/latest/how-to/inspecting.html): Work with a node in hand rather than search beneath it:
- [Trim a document to a selector](https://turbohtml.readthedocs.io/en/latest/how-to/pruning.html): Keep only the part of a parsed document you care about with `turbohtml.Node.prune`, the parse-then-keep pattern BeautifulSoup spelled with a `SoupStrainer`.
- [Chain queries like pyquery](https://turbohtml.readthedocs.io/en/latest/how-to/chaining.html): Wrap a set of elements in `turbohtml.query.Query` and compose traversals and edits, for code migrating off pyquery's jQuery-style chaining.
- [Match elements the soupsieve way](https://turbohtml.readthedocs.io/en/latest/how-to/matching.html): compile and reuse CSS selectors the soupsieve way, with one-shot match helpers and selectors built from data.
- [Sanitize untrusted HTML](https://turbohtml.readthedocs.io/en/latest/how-to/sanitizing.html): Clean untrusted HTML against an allowlist with `turbohtml.clean.sanitize`, the `bleach.clean` successor, keeping only a safe subset of tags, attributes, and URL schemes.
- [Find and rewrite links](https://turbohtml.readthedocs.io/en/latest/how-to/links.html): Work with the URLs in a page:
- [Minify HTML and JavaScript](https://turbohtml.readthedocs.io/en/latest/how-to/minifying.html): Shrink a document with the round-trip-safe `turbohtml.Minify` layout, and minify the inline `<script>` content it carries with `turbohtml.clean.minify_js`.
- [Translate a CSS selector to XPath](https://turbohtml.readthedocs.io/en/latest/how-to/css-to-xpath.html): Emit an XPath 1.0 expression that selects the same nodes as a CSS selector with `turbohtml.convert.css_to_xpath`, for systems that speak only XPath.
- [Read tables into rows and records](https://turbohtml.readthedocs.io/en/latest/how-to/tables.html): Turn an HTML `<table>` into Python data with `turbohtml.Element.rows`, `turbohtml.Element.records`, and `turbohtml.Node.tables`, with `rowspan` and `colspan` resolved so the result is rectangular — no pandas dependency.
- [Extract the main article](https://turbohtml.readthedocs.io/en/latest/how-to/main-content.html): Isolate the article from the navigation, sidebars, and boilerplate with `turbohtml.Node.main_content`, pull it with its metadata, and classify paragraphs one at a time.
- [Extract structured data](https://turbohtml.readthedocs.io/en/latest/how-to/structured-data.html): Pull the machine-readable metadata a page embeds — JSON-LD, Microdata, OpenGraph and Twitter cards, RDFa — with `turbohtml.Document.structured_data`, the `extruct` successor.
- [Build HTML with E](https://turbohtml.readthedocs.io/en/latest/how-to/building.html): Generate HTML in code with `turbohtml.build.E`, then fold the result into a parsed tree you can keep editing or serializing — no parse step required.
- [Serialize a tree to HTML](https://turbohtml.readthedocs.io/en/latest/how-to/serializing.html): Render a tree back to conformant HTML and control the result:
- [Export a tree to Markdown](https://turbohtml.readthedocs.io/en/latest/how-to/markdown.html): Turn a node into GitHub-Flavored Markdown with `turbohtml.Node.to_markdown`, so a scraping script ends with Markdown instead of tag soup.
- [Export a tree to plain text](https://turbohtml.readthedocs.io/en/latest/how-to/plain-text.html): Extract rendered text with `turbohtml.Node.to_text`, and get the same text with span labels attached through `turbohtml.Node.to_annotated_text`.
- [Escape and unescape text](https://turbohtml.readthedocs.io/en/latest/how-to/escaping.html): Escape text for HTML output and reverse it with `turbohtml.escape` and `turbohtml.unescape` — the standard library's behavior, byte for byte, several times faster.
- [Run turbohtml from a shell](https://turbohtml.readthedocs.io/en/latest/how-to/cli.html): Drive turbohtml from a shell.

## Reference

- [Parsing](https://turbohtml.readthedocs.io/en/latest/reference/parsing.html): Turn markup into a navigable `Document`.
- [Nodes](https://turbohtml.readthedocs.io/en/latest/reference/nodes.html): A parsed tree is made of nodes.
- [Tokenizer](https://turbohtml.readthedocs.io/en/latest/reference/tokenizer.html): The low-level WHATWG tokenization surface, below tree construction.
- [Detect](https://turbohtml.readthedocs.io/en/latest/reference/detect.html): Detect the character encoding of bytes without parsing them, a successor to `chardet.detect`, `cchardet.detect`, and `charset_normalizer.from_bytes`.
- [Query](https://turbohtml.readthedocs.io/en/latest/reference/query.html): Search a tree with the node methods, the pyquery-style `Query`, and a soupsieve-shaped matching surface.
- [Clean](https://turbohtml.readthedocs.io/en/latest/reference/clean.html): Clean untrusted or raw HTML:
- [Convert](https://turbohtml.readthedocs.io/en/latest/reference/convert.html): Translate between the query languages turbohtml speaks.
- [Extract](https://turbohtml.readthedocs.io/en/latest/reference/extract.html): Pull content and data out of HTML.
- [Structured data](https://turbohtml.readthedocs.io/en/latest/reference/structured-data.html): per-format helpers `Document.json_ld`, `Document.opengraph`, `Document.microdata`,
- [Build](https://turbohtml.readthedocs.io/en/latest/reference/build.html): Construct HTML trees in code, the way `lxml.builder.E` does.
- [Serialize](https://turbohtml.readthedocs.io/en/latest/reference/serialize.html): Turn a tree back into markup or text.

## Explanation

- [Why a C core](https://turbohtml.readthedocs.io/en/latest/explanation/c-core.html): Escaping and unescaping sit on hot paths:
- [Matching the standard library](https://turbohtml.readthedocs.io/en/latest/explanation/stdlib-parity.html): `turbohtml` reproduces the exact behavior of `python:html.escape` and `python:html.unescape`.
- [Parsing: from bytes to a navigable tree](https://turbohtml.readthedocs.io/en/latest/explanation/parsing.html): A parse runs as a pipeline.
- [The node and tree model](https://turbohtml.readthedocs.io/en/latest/explanation/tree-model.html): Every node in a parsed document is one of a small sealed set of types, all sharing the navigation defined on
- [Querying the tree](https://turbohtml.readthedocs.io/en/latest/explanation/queries.html): Three engines branch off any node, each answering the same question (which nodes do I want?) in a different language:
- [Structured-data extraction](https://turbohtml.readthedocs.io/en/latest/explanation/structured-data.html): what machine-readable metadata does this page embed? It pulls JSON-LD, Microdata, OpenGraph/Twitter card metadata, RDFa, and Dublin Core in one walk, with the per-format helpers `turbohtml.Document.json_ld`,
- [Serialization and export](https://turbohtml.readthedocs.io/en/latest/explanation/serialization.html): One parsed tree fans out into several output forms.
- [Finding the main content](https://turbohtml.readthedocs.io/en/latest/explanation/main-content.html): but *which part of it is the article*.
- [Mutating the tree](https://turbohtml.readthedocs.io/en/latest/explanation/mutation.html): The arena that makes reading cheap is built for append-only construction, not random edits, so making the tree mutable took a deliberate rule rather than a writable wrapper over the read path:
- [Free-threading](https://turbohtml.readthedocs.io/en/latest/explanation/free-threading.html): The extension holds no shared mutable state:

## Optional

- [Migration guides](https://turbohtml.readthedocs.io/en/latest/migration/index.html): one guide per replaced library; see llms-full.txt for the full list.
- [Performance](https://turbohtml.readthedocs.io/en/latest/development/performance.html): benchmark tables against the libraries turbohtml replaces.
- [Changelog](https://turbohtml.readthedocs.io/en/latest/changelog.html): release notes.
