Skip to main content

Core HTML generation library with Rust-based Python extension - high performance, minimal dependencies

Project description

RustyTags Core

🚀 High-performance HTML generation library - Rust-powered Python extension for blazing-fast HTML and SVG creation.

3-10x faster than pure Python implementations with minimal dependencies and maximum performance.

⚛️ Datastar-Ready - Built-in reactive component support with intelligent JavaScript expression detection.

🚨 Breaking Changes in v0.6.0: Advanced features moved to Nitro. See Migration Guide below.

Looking for web framework features? Check out the Nitro package which builds on RustyTags with advanced templates, UI components, SSE, and framework integrations.

What RustyTags Core Does

RustyTags Core is a minimal, high-performance HTML generation library that focuses on one thing: generating HTML and SVG content fast.

  • 🏷️ Complete HTML5/SVG Tags: All standard HTML5 and SVG elements with optimized Rust implementations
  • ⚡ Blazing Performance: 3-10x faster than pure Python with memory optimization and intelligent caching
  • ⚛️ Datastar Integration: Built-in reactive components with $signals, @actions, and intelligent JavaScript detection
  • 🪶 Lightweight: Minimal dependencies - works with any Python web framework
  • 🧠 Smart Processing: Automatic attribute handling and intelligent type conversion
  • 🔧 Framework Ready: Drop-in replacement for any HTML generation needs

Quick Start

Installation

pip install rusty-tags

Basic HTML Generation

from rusty_tags import Div, P, H1, A, Button, Input

# Simple HTML elements
content = Div(
    H1("Welcome to RustyTags Core"),
    P("High-performance HTML generation with Rust + Python"),
    A("Learn More", href="https://github.com/ndendic/RustyTags"),
    cls="container"
)
print(content)
# Output:
# <div class="container">
#   <h1>Welcome to RustyTags Core</h1>
#   <p>High-performance HTML generation with Rust + Python</p>
#   <a href="https://github.com/ndendic/RustyTags">Learn More</a>
# </div>

Complete Page Generation

from rusty_tags import Html, Head, Title, Body, Meta, Link
from rusty_tags import Page  # Simple page helper

# Manual HTML structure
page = Html(
    Head(
        Title("My Site"),
        Meta(charset="utf-8"),
        Link(rel="stylesheet", href="/app.css")
    ),
    Body(
        H1("Hello World"),
        P("Built with RustyTags Core")
    )
)

# Or use the simple Page helper
page = Page(
    H1("Hello World"),
    P("Built with RustyTags Core"),
    title="My Site",
    hdrs=(Meta(charset="utf-8"), Link(rel="stylesheet", href="/app.css"))
)

Reactive Components with Built-in Datastar

RustyTags Core includes intelligent Datastar processing at the Rust level for high-performance reactive components:

from rusty_tags import Div, Button, P, Input, Page

# Reactive counter with built-in Datastar processing
counter = Div(
    P(text="Count: $count", cls="display"),               # → data-text="$count"
    Button("+1", on_click="$count++", cls="btn"),         # → data-on-click="$count++"
    Button("-1", on_click="$count--", cls="btn"),         # → data-on-click="$count--"
    Button("Reset", on_click="$count = 0", cls="btn"),    # → data-on-click="$count = 0"
    signals={"count": 0},                                 # → data-signals='{"count": 0}'
    cls="counter-widget"
)

# Reactive form with conditional display
form = Div(
    Input(bind="$name", placeholder="Enter name"),         # → data-bind="$name"
    Input(bind="$email", placeholder="Enter email"),       # → data-bind="$email"
    P(
        text="Hello $name! Email: $email",
        show="$name && $email"                            # → data-show="$name && $email"
    ),
    Button(
        "Submit",
        on_click="alert('Submitted: ' + $name)",          # → data-on-click="alert('Submitted: ' + $name)"
        cls={"disabled": "$name === '' || $email === ''"}  # → data-cls='{"disabled": "$name === \"\" || $email === \"\""}'
    ),
    signals={"name": "", "email": ""}                     # → data-signals='{"name": "", "email": ""}'
)

# Create a complete page with Datastar CDN
page = Page(
    counter, form,
    title="Reactive App",
    datastar=True  # Automatically includes Datastar CDN
)

Built-in Datastar Features:

  • Shorthand Attributes: signals, bind, show, text, on_click → automatically converted to data-*
  • Smart Expression Detection: $signals and @actions automatically recognized as JavaScript
  • Reactive Classes: cls={"active": "$isActive"} for conditional styling
  • Event Handlers: on_click, on_submit, etc. → data-on-* attributes
  • Type Safety: Intelligent conversion of Python types to JavaScript equivalents

SVG Generation

from rusty_tags import Svg, Circle, Rect, Line, Path

# Create SVG graphics
chart = Svg(
    Circle(cx="50", cy="50", r="40", fill="blue"),
    Rect(x="10", y="10", width="30", height="30", fill="red"),
    Line(x1="0", y1="0", x2="100", y2="100", stroke="black"),
    width="200", height="200", viewBox="0 0 200 200"
)

Core Features

🏷️ Complete HTML5/SVG Tag System

All standard HTML5 and SVG elements are available as Python functions:

# HTML elements
Html, Head, Body, Title, Meta, Link, Script
H1, H2, H3, H4, H5, H6, P, Div, Span, A
Form, Input, Button, Select, Textarea, Label
Table, Tr, Td, Th, Tbody, Thead, Tfoot
Nav, Main, Section, Article, Header, Footer
Img, Video, Audio, Canvas, Iframe
# ... and many more

# SVG elements
Svg, Circle, Rect, Line, Path, Polygon
G, Defs, Use, Symbol, LinearGradient
Text, Image, ForeignObject
# ... complete SVG support

⚡ Performance Optimizations

  • Memory Pooling: Thread-local string pools and arena allocators minimize allocations
  • Intelligent Caching: Lock-free attribute processing with smart cache invalidation
  • String Interning: Common HTML strings pre-allocated for maximum efficiency
  • Type Optimization: Fast paths for common Python types and HTML patterns

🔧 Smart Type System

Intelligent handling of Python types:

# Automatic type conversion
Div(
    42,           # Numbers → strings
    True,         # Booleans → "true"/"false"
    None,         # None → empty string
    [1, 2, 3],    # Lists → joined strings
    custom_obj,   # Objects with __html__(), render(), or _repr_html_()
)

# Dictionary attributes automatically expand
Div("Content", {"id": "main", "class": "container", "hidden": False})
# Renders: <div id="main" class="container">Content</div>

# Framework integration - automatic recognition
class MyComponent:
    def __html__(self):
        return "<div>Custom HTML</div>"

Div(MyComponent())  # Automatically calls __html__()

🪶 Framework Agnostic

Works with any Python web framework:

# FastAPI
from fastapi import FastAPI
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/")
def home():
    return HTMLResponse(str(Page(H1("FastAPI + RustyTags"), title="Home")))

# Flask
from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return str(Page(H1("Flask + RustyTags"), title="Home"))

# Django
from django.http import HttpResponse

def home(request):
    return HttpResponse(str(Page(H1("Django + RustyTags"), title="Home")))

📓 Jupyter Integration

from rusty_tags import show

# Display directly in Jupyter notebooks
content = Div(H1("Notebook Content"), style="color: blue;")
show(content)  # Renders directly in Jupyter cells

Performance

RustyTags Core delivers significant performance improvements over pure Python:

  • 3-10x faster HTML generation
  • Sub-microsecond rendering for simple elements
  • Memory efficient with intelligent pooling
  • Scalable with lock-free concurrent data structures
# Benchmark example
import timeit
from rusty_tags import Div, P

def generate_content():
    return Div(
        *[P(f"Paragraph {i}") for i in range(1000)],
        cls="container"
    )

# Time the generation
time = timeit.timeit(generate_content, number=1000)
print(f"Generated 1000 pages with 1000 paragraphs each in {time:.3f}s")

Architecture

🦀 Rust Core (src/lib.rs):

  • High-performance HTML/SVG generation with PyO3 bindings
  • Advanced memory management with pooling and interning
  • Complete tag system with macro-generated optimizations
  • ~2000+ lines of optimized Rust code

🐍 Python Layer (rusty_tags/):

  • Core Module (__init__.py): All HTML/SVG tags and core types
  • Utilities (utils.py): Essential helpers (Page, create_template, page_template, show, AttrDict)
  • Rust Extension: Pre-compiled high-performance core with Datastar processing

Migration from Pre-0.6.x

🚨 Breaking Changes in v0.6.0

RustyTags v0.6.0 represents a major architectural shift to focus on core HTML generation performance. Advanced web framework features have been moved to the separate Nitro package.

What's Removed from RustyTags Core:

Feature Status New Location
DS class & Datastar utilities ❌ Removed Nitro
Event system (events.py) ❌ Removed Nitro
Client management (client.py) ❌ Removed Nitro
UI components (xtras/) ❌ Removed Nitro
Example applications (lab/) ❌ Removed Nitro
Framework dependencies ❌ Removed Nitro

What's Kept in RustyTags Core:

Feature Status Notes
All HTML/SVG tags Kept Complete tag system with Rust performance
Basic Datastar support Kept Built-in $signals, @actions, shorthand attributes
Page() function Enhanced Simple templating with optional Datastar CDN
create_template(), page_template() Kept Essential templating functions
show() Jupyter integration Kept Perfect for notebooks
AttrDict utility Kept Flexible attribute access

Migration Guide:

Before v0.6.0 (Monolithic):

# Old import style - no longer works
from rusty_tags import Div, DS, Client, Accordion
from rusty_tags.events import emit

After v0.6.0 (Decoupled):

# Core HTML generation (RustyTags)
from rusty_tags import Div, Page, create_template
from rusty_tags import Button, Input  # All HTML tags still here

# Advanced features (Nitro - separate install)
from nitro import DS, Client, Accordion
from nitro.events import emit

Installation Changes:

# Before v0.6.0
pip install rusty-tags  # Included everything

# After v0.6.0
pip install rusty-tags        # Core HTML generation only
pip install nitro             # For web framework features

Code Migration Examples:

  1. Basic HTML Generation (No changes needed):
# ✅ Works exactly the same
from rusty_tags import Div, H1, P
content = Div(H1("Hello"), P("World"))
  1. Basic Datastar (No changes needed):
# ✅ Works exactly the same - built into Rust core
from rusty_tags import Div, Button
counter = Div(
    Button("+1", on_click="$count++"),
    signals={"count": 0}
)
  1. Advanced Datastar (Needs Nitro):
# ❌ Old way
from rusty_tags import DS
action = DS.post("/api/submit", data={"name": "$name"})

# ✅ New way
from nitro import DS  # Install nitro package
action = DS.post("/api/submit", data={"name": "$name"})
  1. Page Templates (Minor changes):
# ✅ Still works in RustyTags Core
from rusty_tags import Page, create_template

# Basic templating stays the same
page = Page(content, title="My App", datastar=True)
template = create_template("My App", datastar=True)

# ❌ Advanced CDN features moved to Nitro
# highlightjs=True, lucide=True parameters now in Nitro

Why This Change?

  • Performance: Core package is now 10x smaller and has zero dependencies
  • Flexibility: Choose your complexity level - core HTML or full framework
  • Maintenance: Clear separation of concerns between HTML generation and web framework
  • Adoption: Lower barrier to entry for simple HTML generation needs

The built-in Datastar support in RustyTags Core provides excellent reactive capabilities without requiring the full Nitro framework.

Why RustyTags Core?

Choose RustyTags Core when:

  • ✅ You need maximum performance for HTML generation
  • ✅ You want minimal dependencies in your project
  • ✅ You're building your own templating system
  • ✅ You need framework-agnostic HTML generation
  • ✅ You want drop-in compatibility with any Python web framework

Consider Nitro when:

  • 🚀 You want a full web framework with reactive components
  • 🎨 You need advanced templating and UI component libraries
  • 📡 You want real-time features (SSE, WebSocket management)
  • ⚛️ You need Datastar integration for reactive UIs

System Requirements

  • Python 3.8+ (broad compatibility across versions)
  • Runtime Dependencies: None (zero dependencies for maximum compatibility)
  • Optional: IPython for show() function in Jupyter notebooks
  • Build Requirements (development only): Rust 1.70+, Maturin ≥1.9

Development

# Clone and build from source
git clone https://github.com/ndendic/RustyTags
cd RustyTags
maturin develop  # Development build
maturin build --release  # Production build

License

MIT License - See LICENSE file for details.

Related Projects

  • Nitro - Full-stack web framework built on RustyTags
  • FastHTML - Inspiration for the Python API design
  • Datastar - Reactive component framework (used in Nitro)

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rusty_tags-0.6.0.tar.gz (32.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rusty_tags-0.6.0-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file rusty_tags-0.6.0.tar.gz.

File metadata

  • Download URL: rusty_tags-0.6.0.tar.gz
  • Upload date:
  • Size: 32.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.8

File hashes

Hashes for rusty_tags-0.6.0.tar.gz
Algorithm Hash digest
SHA256 4b0df57bfe2ba8951b2bdd7620830e32786fd14ecf64e3f727ae5b18862a6836
MD5 ba7a53449fb1c20db92d3e3db580f153
BLAKE2b-256 71650c26fa9e117beef6d7d0567180fd420652d12f040077c0f61bebafebee37

See more details on using hashes here.

File details

Details for the file rusty_tags-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: rusty_tags-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 13.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.8

File hashes

Hashes for rusty_tags-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 25275b9fb561d40898467f3f455ece28e95eb62dfc10b6d498972eac2b699bdd
MD5 3859b35d71e7ac34cc9e1d777f4fc2fd
BLAKE2b-256 3322bb9d8c347c6d0ee420275b5164450687bcb7f2d301aa66433e947f886be2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page