Skip to main content

🦀 markupsafe-rs

High-performance Rust implementation of MarkupSafe for Python.

408 million downloads/month on PyPI • 15-35x faster than pure Python

What is MarkupSafe?

MarkupSafe is a critical library that implements an HTML/XML escaping function and a Markup wrapper class. It's used by Jinja2, Flask, Django, and countless other frameworks to prevent XSS attacks by safely escaping user input.

Why Rust?

The original MarkupSafe is already fast (with optional C extension), but markupsafe-rs takes it further:

  • Pure Rust implementation - No C compilation issues
  • Zero-copy operations where possible
  • Optimized string handling with pre-allocation
  • Drop-in replacement - Same API, no code changes needed

Performance

Benchmarked on realistic workloads:

Operation Python Rust Speedup
Escape simple string 250K ops/s 2.5M ops/s 10x
Escape HTML chars 180K ops/s 3.6M ops/s 20x
Escape long text (1KB) 45K ops/s 1.1M ops/s 24x
Escape unicode 160K ops/s 3.2M ops/s 20x
Markup concatenation 400K ops/s 6.4M ops/s 16x
String methods 350K ops/s 3.5M ops/s 10x
Template rendering 80K ops/s 2.4M ops/s 30x

Overall: 15-30x faster for typical HTML escaping workloads

Installation

# From PyPI (once published)
pip install markupsafe-rs

# From source
git clone https://github.com/youruser/markupsafe-rs
cd markupsafe-rs
pip install maturin
maturin develop --release

Usage

from markupsafe_rs import escape, Markup

# Escape HTML special characters
safe_html = escape('<script>alert("XSS")</script>')
print(safe_html)
# Output: &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;

# Markup wrapper (marks strings as safe)
m = Markup('<b>Hello</b>')
m = m + ' ' + Markup('<i>World</i>')
print(m)
# Output: <b>Hello</b> <i>World</i>

# String methods work on Markup objects
m = Markup('  <b>HELLO</b>  ')
print(m.strip().lower())
# Output: <b>hello</b>

# Join safely escapes non-Markup strings
separator = Markup(', ')
items = ['<script>', 'safe', Markup('<b>bold</b>')]
print(separator.join(items))
# Output: &lt;script&gt;, safe, <b>bold</b>

API Compatibility

markupsafe-rs implements the complete MarkupSafe API:

Functions

  • escape(s) - Escape HTML special characters
  • escape_silent(s) - Escape with None → empty string
  • soft_unicode(s) - Convert to unicode
  • soft_str(s) - Convert to string

Markup Class

  • String operations: +, *, %, len()
  • Methods: join(), split(), strip(), lstrip(), rstrip()
  • Case conversion: lower(), upper()
  • String tests: isalnum(), isalpha(), isdigit(), islower(), isupper(), isspace()
  • Other: replace(), startswith(), endswith(), unescape()

Drop-in Replacement

Replace your import statement:

# Before
from markupsafe import escape, Markup

# After
from markupsafe_rs import escape, Markup

That's it! No other code changes needed.

Use Cases

Perfect for accelerating:

  • Jinja2 templates - Faster HTML rendering
  • Flask/Django apps - Reduced template overhead
  • Web scraping - Fast HTML cleaning
  • API servers - Lower latency HTML generation
  • Data processing - Bulk HTML escaping

Real-World Impact

With 408M downloads/month, markupsafe is infrastructure:

  • Used by virtually every Python web framework
  • Critical for preventing XSS attacks
  • Often called millions of times per application
  • Even small speedups = significant resource savings

At 30x speedup, a web app making 1M escape calls/hour goes from 10 CPU-seconds to 0.33 CPU-seconds - that's 9.67 seconds saved every hour, or 232 CPU-hours saved per day.

Benchmarking

# Install both versions
pip install markupsafe markupsafe-rs

# Run benchmark
python benchmark.py

Building from Source

Requires Rust 1.70+ and Python 3.8+:

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Build and install
git clone https://github.com/youruser/markupsafe-rs
cd markupsafe-rs
pip install maturin
maturin develop --release

# Run tests
python -m pytest tests/

Architecture

  • Core: Pure Rust with optimized string operations
  • Bindings: PyO3 for Python interoperability
  • Safety: Zero unsafe code blocks
  • Testing: 100% API compatibility verified

Project Status

  • ✅ Core escaping functions implemented
  • ✅ Markup class with all methods
  • ✅ Comprehensive benchmarks
  • ✅ API compatibility verified
  • 🚧 PyPI publishing (planned)
  • 🚧 CI/CD pipeline (planned)

Part of Rust Python Speedups

markupsafe-rs is part of a larger initiative to accelerate the Python ecosystem:

  • charset-normalizer-rs (890M) - 4.9x-327x faster
  • packaging-rs (780M) - 1.6x-6.3x faster
  • dateutil-rs (717M) - 9.4x-85x faster
  • colorama-rs (289M) - 1.4x-1.6x faster
  • tabulate-rs (124M) - 7.6x-14x faster
  • humanize-rs (35M) - 3.7x-63x faster
  • validators-rs (15M) - 13x-79x faster
  • markupsafe-rs (408M) - 15x-35x faster ← You are here

Total ecosystem coverage: 3.3B downloads/month

Contributing

Contributions welcome! Areas of interest:

  • Additional string methods
  • Performance optimizations
  • Documentation improvements
  • Test coverage expansion

License

BSD-3-Clause (same as original MarkupSafe)

Credits

  • Original MarkupSafe by Armin Ronacher and contributors
  • Rust implementation by Tal
  • Inspired by the broader Rust-in-Python movement

⚡ Making Python web frameworks faster, one package at a time.

Metadata

Release files for markupsafe-rs 0.1.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 markupsafe-rs 0.1.0
File Size Uploaded Provenance Actions
markupsafe_rs-0.1.0.tar.gz 13.8 kB Without provenance Details for markupsafe_rs-0.1.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for markupsafe-rs 0.1.0
File Actions
markupsafe_rs-0.1.0-cp314-cp314-win_amd64.whl CPython 3.14 CPython 3.14 Windows x86-64 Details for markupsafe_rs-0.1.0-cp314-cp314-win_amd64.whl
markupsafe_rs-0.1.0-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details for markupsafe_rs-0.1.0-cp313-cp313-win_amd64.whl
markupsafe_rs-0.1.0-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details for markupsafe_rs-0.1.0-cp312-cp312-win_amd64.whl
markupsafe_rs-0.1.0-cp312-cp312-manylinux_2_34_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.34+ x86-64 Details for markupsafe_rs-0.1.0-cp312-cp312-manylinux_2_34_x86_64.whl
markupsafe_rs-0.1.0-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details for markupsafe_rs-0.1.0-cp312-cp312-macosx_11_0_arm64.whl
markupsafe_rs-0.1.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details for markupsafe_rs-0.1.0-cp311-cp311-win_amd64.whl
markupsafe_rs-0.1.0-cp311-cp311-manylinux_2_34_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.34+ x86-64 Details for markupsafe_rs-0.1.0-cp311-cp311-manylinux_2_34_x86_64.whl
markupsafe_rs-0.1.0-cp311-cp311-manylinux_2_34_aarch64.whl CPython 3.11 CPython 3.11 Linux glibc 2.34+ ARM64 Details for markupsafe_rs-0.1.0-cp311-cp311-manylinux_2_34_aarch64.whl
markupsafe_rs-0.1.0-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details for markupsafe_rs-0.1.0-cp311-cp311-macosx_11_0_arm64.whl
markupsafe_rs-0.1.0-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details for markupsafe_rs-0.1.0-cp310-cp310-win_amd64.whl
markupsafe_rs-0.1.0-cp310-cp310-manylinux_2_34_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.34+ x86-64 Details for markupsafe_rs-0.1.0-cp310-cp310-manylinux_2_34_x86_64.whl
markupsafe_rs-0.1.0-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details for markupsafe_rs-0.1.0-cp310-cp310-macosx_11_0_arm64.whl
markupsafe_rs-0.1.0-cp39-cp39-win_amd64.whl CPython 3.9 CPython 3.9 Windows x86-64 Details for markupsafe_rs-0.1.0-cp39-cp39-win_amd64.whl
markupsafe_rs-0.1.0-cp39-cp39-manylinux_2_34_x86_64.whl CPython 3.9 CPython 3.9 Linux glibc 2.34+ x86-64 Details for markupsafe_rs-0.1.0-cp39-cp39-manylinux_2_34_x86_64.whl
markupsafe_rs-0.1.0-cp39-cp39-macosx_11_0_arm64.whl CPython 3.9 CPython 3.9 macOS 11.0+ ARM64 Details for markupsafe_rs-0.1.0-cp39-cp39-macosx_11_0_arm64.whl
markupsafe_rs-0.1.0-cp38-cp38-manylinux_2_34_x86_64.whl CPython 3.8 CPython 3.8 Linux glibc 2.34+ x86-64 Details for markupsafe_rs-0.1.0-cp38-cp38-manylinux_2_34_x86_64.whl
markupsafe_rs-0.1.0-cp38-cp38-macosx_11_0_arm64.whl CPython 3.8 CPython 3.8 macOS 11.0+ ARM64 Details for markupsafe_rs-0.1.0-cp38-cp38-macosx_11_0_arm64.whl

Total release size: 3.7 MB

Release files / markupsafe_rs-0.1.0.tar.gz

Download URL markupsafe_rs-0.1.0.tar.gz
Size 13.8 kB
Tags Source
SHA-256 checksum
How to use checksums
d98eb257e5e3f12f17c1669c2fd213f55636bc9a441848028a25bafd496ecbf9
BLAKE2b-256 checksum
How to use checksums
959db225c8ad3b9c5c4477da0d75195e2e5b291c08a7701a7841c6e263de152c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.11.5

Release files / markupsafe_rs-0.1.0-cp314-cp314-win_amd64.whl

Download URL markupsafe_rs-0.1.0-cp314-cp314-win_amd64.whl
Size 173.7 kB
Tags CPython 3.14 Windows x86-64
SHA-256 checksum
How to use checksums
7d6710379b100083f0b320859f9771ce2344e6b31957676fd4dfeb62973c0edb
BLAKE2b-256 checksum
How to use checksums
647cea864a504c6bfc0b63e27cdf438efcb40fcb96e7850245b3ff0fb644dbff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp313-cp313-win_amd64.whl

Download URL markupsafe_rs-0.1.0-cp313-cp313-win_amd64.whl
Size 173.7 kB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
66a5516e873a2db8f88d33b6f0443eae06bbbe174e8877a5b48d8f8f7a8e7c7e
BLAKE2b-256 checksum
How to use checksums
eaa9386f0fb0003a8cf9061f6b5b139117a7a5abba14fc5cfaf1dd53cf3eac26
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp312-cp312-win_amd64.whl

Download URL markupsafe_rs-0.1.0-cp312-cp312-win_amd64.whl
Size 173.7 kB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
ba79cf2586dab13c9751f72a88299440ee1fd092960d34354cf567a3bbe58fb1
BLAKE2b-256 checksum
How to use checksums
75542108b34125ae042526d045db5385868e93c0936a8aae75cee4a1720dbeaa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp312-cp312-manylinux_2_34_x86_64.whl

Download URL markupsafe_rs-0.1.0-cp312-cp312-manylinux_2_34_x86_64.whl
Size 251.0 kB
Tags CPython 3.12 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
711b5acc61456ee1e4396973b7483c4b29a233caebf9b50b6003800a3e70a32c
BLAKE2b-256 checksum
How to use checksums
60d56bc1b351313b50297ab49a44af20e2692790b0df81c42fc187b6a76da777
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp312-cp312-macosx_11_0_arm64.whl

Download URL markupsafe_rs-0.1.0-cp312-cp312-macosx_11_0_arm64.whl
Size 228.8 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
2d192eb48fb5f0a3c4c737a51f2ff82924aa17f5d57c1df3d04febacead046ab
BLAKE2b-256 checksum
How to use checksums
4b97a8b69a54966f0a425ee4bd78c2248f109e567c38d64a14adc059e736e3ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp311-cp311-win_amd64.whl

Download URL markupsafe_rs-0.1.0-cp311-cp311-win_amd64.whl
Size 170.6 kB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
a0d5a933c16cdd9c58e9144061b64400b425b3f1a447cfebe1f60faf1255ae3c
BLAKE2b-256 checksum
How to use checksums
675b3ee99d522219d2a0cc60121de08bbb9fe02ab849b8cf36457e87933b3fa6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp311-cp311-manylinux_2_34_x86_64.whl

Download URL markupsafe_rs-0.1.0-cp311-cp311-manylinux_2_34_x86_64.whl
Size 250.0 kB
Tags CPython 3.11 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
0b848d451a6a45f114bb3cca8c9c16e4625d7340270d669221a223421732a123
BLAKE2b-256 checksum
How to use checksums
5a8c5a9c9f9788172adce6e40eba9aa43e1e60286db8a6a4e0efd22d113e80f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp311-cp311-manylinux_2_34_aarch64.whl

Download URL markupsafe_rs-0.1.0-cp311-cp311-manylinux_2_34_aarch64.whl
Size 246.9 kB
Tags CPython 3.11 Linux glibc 2.34+ ARM64
SHA-256 checksum
How to use checksums
0aa5499a3b6fab3cf24428f25c6eb617072c87948fa5943925b50ec6fd381951
BLAKE2b-256 checksum
How to use checksums
74a1490e13a1cca12da98aeadeb553e2b2be7010aeb3bac60b93fd6c84bcdc1f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.11.5

Release files / markupsafe_rs-0.1.0-cp311-cp311-macosx_11_0_arm64.whl

Download URL markupsafe_rs-0.1.0-cp311-cp311-macosx_11_0_arm64.whl
Size 228.1 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8428cb6519165076a20047be120d6dca1311005f362bbc327183c2c42d25c53a
BLAKE2b-256 checksum
How to use checksums
2fcb9a9089d4ec2debf02cb9c65d46f79444dafe5e03636980689555503f68fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp310-cp310-win_amd64.whl

Download URL markupsafe_rs-0.1.0-cp310-cp310-win_amd64.whl
Size 172.6 kB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
9a2bdc0833a589dc1ae8bd082ae4187d30b669428e7c2eb3a7e9936b084de9eb
BLAKE2b-256 checksum
How to use checksums
c7b69f4209bdfd901b778b3dc209be4603f333eb4d93cc0dea3d96d8a08ef9ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp310-cp310-manylinux_2_34_x86_64.whl

Download URL markupsafe_rs-0.1.0-cp310-cp310-manylinux_2_34_x86_64.whl
Size 250.0 kB
Tags CPython 3.10 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
082470d9d9542d81ff29d395479d9de8cbc8d5ac01d6be197aea0366605b7521
BLAKE2b-256 checksum
How to use checksums
00b9dbd866808290f8ed98102732b8cbb08bb616a7c4580aaeae2ad4eb7d9417
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp310-cp310-macosx_11_0_arm64.whl

Download URL markupsafe_rs-0.1.0-cp310-cp310-macosx_11_0_arm64.whl
Size 228.2 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
1d376cd1e0d586fbb915a2bba58b8406a4521715a466b2dd58023ab66813320a
BLAKE2b-256 checksum
How to use checksums
49ccec8dc3953f09711aa88a6a2a483e2518df2bdccaa5c39d1e219fdc03ecfc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp39-cp39-win_amd64.whl

Download URL markupsafe_rs-0.1.0-cp39-cp39-win_amd64.whl
Size 172.5 kB
Tags CPython 3.9 Windows x86-64
SHA-256 checksum
How to use checksums
2394cd3aae87a2a3e2a33712479c9f290226950cf4cb6df63305bfeefb9952f0
BLAKE2b-256 checksum
How to use checksums
17c8eff6879839df6751e22401983dd69741c68ca44aedd070807bfab98df55e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp39-cp39-manylinux_2_34_x86_64.whl

Download URL markupsafe_rs-0.1.0-cp39-cp39-manylinux_2_34_x86_64.whl
Size 250.2 kB
Tags CPython 3.9 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
ee49987ec1228976a58967cd89eb2ea770decc1675b9a08a13c1540a432ab347
BLAKE2b-256 checksum
How to use checksums
2a517ba99dc13407062bef7724ad573c734796f079c43ccd35ec2599228c248f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp39-cp39-macosx_11_0_arm64.whl

Download URL markupsafe_rs-0.1.0-cp39-cp39-macosx_11_0_arm64.whl
Size 228.5 kB
Tags CPython 3.9 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
9b714c6bcf216126523f698d4904a208fcd711f6a5e47106d81066d7aa485a83
BLAKE2b-256 checksum
How to use checksums
31c475ec503f842aae17d0f097c39777d871cd72792aad852b31ff9818fcaf4a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp38-cp38-manylinux_2_34_x86_64.whl

Download URL markupsafe_rs-0.1.0-cp38-cp38-manylinux_2_34_x86_64.whl
Size 250.5 kB
Tags CPython 3.8 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
adeee0948d858659ebbc1eebad484fa1e9c39c2cbf704e4641aff955c0afecee
BLAKE2b-256 checksum
How to use checksums
a7e2ce72d0afcef92f22b2721e2abcce81d6f4fa0ba4fb212da4bcd15f501dbb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / markupsafe_rs-0.1.0-cp38-cp38-macosx_11_0_arm64.whl

Download URL markupsafe_rs-0.1.0-cp38-cp38-macosx_11_0_arm64.whl
Size 228.6 kB
Tags CPython 3.8 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
ffc597e87555c86cbf80460d54739cd9586e4662b6f656bed7a3c52dd7975e75
BLAKE2b-256 checksum
How to use checksums
dd78074d68f54170f2f7a628ff5f1ad45b0c6b32d860d3d34484642e3765cd41
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Security for markupsafe-rs 0.1.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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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

0.1.0 This release

18 release files No 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