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.

Release files for justhtml 3.11.3

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.11.3
File Size Uploaded
justhtml-3.11.3.tar.gz 956.7 kB Details

Built distribution (wheel)

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

Total release size: 1.1 MB

Release files / justhtml-3.11.3.tar.gz

Download URL justhtml-3.11.3.tar.gz
Size 956.7 kB
Tags Source
SHA-256 checksum
How to use checksums
aa94c025eef889aeb48a1a99f9feecbdaeaf5ea2ea03678569e6d219b9699f4a
BLAKE2b-256 checksum
How to use checksums
a743c7793f025c5ec9d9bebc95e00e81c93b24c7a01293563ece160a074e3a53
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 27, 2026.

Transparency log

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

Download URL justhtml-3.11.3-py3-none-any.whl
Size 171.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dc6ef547733a19838246bd25d2e6f5f518dc67c21442f77c43f94364c93476db
BLAKE2b-256 checksum
How to use checksums
08c7fdac03312902b5f9528e4b9bc1dbce25ec4a79e3b7d06c417e41711eab9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 27, 2026.

Transparency log

Release history Release notifications | RSS feed

3.12.0

2 release files

This release

3.11.3 This release

2 release files

3.11.2

2 release files

3.11.1

2 release files

3.10.1

2 release files

3.10.0

2 release files

3.9.0

2 release files

3.8.0

2 release files

3.7.0

2 release files

3.6.1

2 release files

3.6.0

2 release files

3.5.0

2 release files

3.4.0

2 release files

3.3.0

2 release files

3.2.0

2 release files

3.1.0

2 release files

3.0.0

2 release files

2.4.1

2 release files

2.4.0

2 release files

2.3.0

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.23.0

2 release files

1.22.0

2 release files

1.21.0

2 release files

1.20.0

2 release files

1.17.0

2 release files

1.16.0

2 release files

1.13.0

2 release files

1.12.0

2 release files

1.11.0

2 release files

1.10.0

2 release files

1.9.1

2 release files

1.9.0

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.0

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.40.0

2 release files

0.39.0

2 release files

0.38.0

2 release files

0.37.0

2 release files

0.36.0

2 release files

0.35.0

2 release files

0.34.0

2 release files

0.33.0

2 release files

0.32.0

2 release files

0.23.0

2 release files

0.22.0

2 release files

0.21.0

2 release files

0.20.0

2 release files

0.19.0

2 release files

0.18.0

2 release files

0.17.0

2 release files

0.16.0

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.13.1

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

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