Skip to main content

JustHTML

HTML from the real web is messy. It is often malformed, user supplied, scraped from unknown pages, or headed for a browser where small parsing differences can become security bugs.

JustHTML gives Python projects one small dependency for the common HTML jobs:

  • parse HTML like a browser, including broken markup
  • sanitize untrusted HTML by default
  • query with CSS selectors
  • transform, serialize, extract text, or convert to Markdown
  • run anywhere Python runs, with no C extension and no system package to install
pip install justhtml

Requires Python 3.10 or later.

Documentation | Comparison | Playground | Security policy

JustHTML turns messy unsafe HTML into a sanitized, queryable DOM, then serializes it to text, Markdown, or HTML.

Why Use It?

Most Python HTML libraries optimize for one part of the problem.

html.parser is built in, but not HTML5-correct. BeautifulSoup is convenient, but depends heavily on the parser underneath. lxml and C/Rust-backed parsers are fast, but usually leave sanitization as a separate concern. html5lib and Bleach shaped the Python ecosystem, but both are no longer the obvious foundation for new projects.

JustHTML is for applications that want a boring, inspectable, pure-Python default:

  • Correct parsing: browser-style HTML5 recovery, tested against the web platform html5 treebuilder tests.
  • Safe by default: JustHTML(html) sanitizes before you query or serialize.
  • One DOM: parse once, then sanitize, query, transform, serialize, extract text, or produce Markdown.
  • Easy deployment: zero runtime dependencies, no compiler, works on PyPy and Pyodide.
  • Honest tradeoff: if you are parsing terabytes of trusted HTML, use a C/Rust parser. If you need reliable handling of untrusted or malformed HTML inside a Python app, use JustHTML.

Real-world signal: Mozilla Support migrated from Bleach to JustHTML in Kitsune, the Django application behind support.mozilla.org.

Quick Start

from justhtml import JustHTML

doc = JustHTML(
    "<p>Hello<script>alert(1)</script> "
    "<a href='javascript:alert(1)'>bad</a> "
    "<a href='https://example.com'>ok</a></p>",
    fragment=True,
)

print(doc.to_html(pretty=False))
# => <p>Hello <a>bad</a> <a href="https://example.com">ok</a></p>

Sanitization is enabled by default. Disable it only for trusted input:

doc = JustHTML("<main><p class='intro'>Hello</p></main>", sanitize=False)
intro = doc.query_one("p.intro")

print(intro.to_text())
# => Hello

What You Can Do

from justhtml import JustHTML, Linkify, SetAttrs, Unwrap

doc = JustHTML(
    "<p>Hello <span>world</span> example.com</p>",
    fragment=True,
    sanitize=False,
    transforms=[
        Unwrap("span"),
        Linkify(),
        SetAttrs("a", rel="nofollow"),
    ],
)

print(doc.to_html(pretty=False))
# => <p>Hello world <a href="http://example.com" rel="nofollow">example.com</a></p>

JustHTML includes:

Command Line

# Pretty-print an HTML file
justhtml index.html

# Parse from stdin
curl -s https://example.com | justhtml -

# Extract text from selected nodes
justhtml index.html --selector "main p" --format text

# Convert selected HTML to Markdown
justhtml index.html --selector "article" --format markdown

Correctness

JustHTML is tested against the web platform html5 treebuilder tests, plus html5lib serializer/encoding fixtures and project-specific sanitizer, selector, transform, CLI, and regression tests.

The current test suite enforces 100% combined line and branch coverage, including the parser engine. The parser engine additionally requires exact agreement with the reference path across the web platform html5 treebuilder suite. See Correctness Testing for details.

Documentation

Security

JustHTML sanitizes by default, but output safety still depends on where you put it. HTML body output is not automatically safe inside JavaScript, CSS, URL attributes, or other contexts.

For the supported-version policy and vulnerability reporting, see SECURITY.md.

License

MIT. Free to use for commercial and non-commercial projects.

Metadata

Release files for justhtml 3.14.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for justhtml 3.14.0
File Size Uploaded Provenance
justhtml-3.14.0.tar.gz 970.4 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for justhtml 3.14.0
File Interpreter ABI Platform
justhtml-3.14.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.1 MB

Release files / justhtml-3.14.0.tar.gz

Download URL justhtml-3.14.0.tar.gz
Size 970.4 kB
Tags Source
SHA-256 checksum
How to use checksums
a6c545dd53fdecabb6ae1d665294110991a564b494e4834861273507447ee49d
BLAKE2b-256 checksum
How to use checksums
3fabb29cc584b0fc0a9b8d618f5e2305c2208ce537d52edfd68181802f929b1d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / justhtml-3.14.0-py3-none-any.whl

Download URL justhtml-3.14.0-py3-none-any.whl
Size 174.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c870fd5ee8069f3325735803018f5d8d68ae988201c9204fef6497f36f9473c2
BLAKE2b-256 checksum
How to use checksums
032b9afff9276bee071cab1d7541508230c6a6f0299a1854d597aaf2ffafc3ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Security for justhtml 3.14.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for justhtml-3.14.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

3.14.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page