Skip to main content

Hiccl Reactive Web Framework — Hiccup DSL + Python Pickle-like State

Project description

Hiccl — Full-Stack Reactive Web Framework for Python 🧪🥒

简体中文English

zread

Modern Web Framework Combining Clojure's Hiccup DSL with Pythonic Reactive State Serialization

PhilosophyKey FeaturesQuick StartArchitectureOffline ReadinessDevelopment & Contribution

[!TIP] Read this repository with Zread AI Assistant: Readers can click the Ask Zread badge above to ask any questions about the hiccl architecture or implementation details directly. It helps onboard contributors faster, answers reader queries, and keeps issues clean!


🎨 Philosophy & Naming

Hiccl (pronounced /ˈhɪk.l̩/ or "Hick-le") is the harmonic crystallization of Hiccup and Pickle:

  • Hiccup: Drawing pure lineage from Clojure. In Hiccl, you completely bypass writing boilerplate HTML strings. Your entire DOM structure is expressively built using elegant, nested Python data structures and lists.
  • Pickle: Exuding deep Pythonic roots. Represents automatic component state (State/Signal) tracking and session-based lifecycle serialization. States flow automatically through WebSockets or SSE via minimal reactive virtual-DOM diff patches.

Hiccl bridges the declarative simplicity of Clojure's UI design with Pythonic full-stack reactivity atop a high-performance FastAPI/Starlette server!


⚡️ Key Features

  • ⚡️ 100% Declarative Components: Describe your UI using only nested Python lists. The framework auto-binds events (like on_click) into seamless server-side methods with zero boilerplate AJAX or fetch glue code.
  • 🔌 Reactive State & Elegant Factories: Powered by native Signal (signal), ComputedSignal (computed), and Effect (effect) primitives, as well as batch transaction support. State mutations trigger automatic virtual-DOM diffing, pushing minimal HTML patches via WebSockets/SSE to the client instantly.
  • 🛡️ Runtime hiccl.spec Contract Security: Implements Clojure-like declarative data contracts to guard @server method boundaries. Provides structured explain_data errors, enabling AI agents to engage in excellent error introspection and self-healing.
  • 🔐 Production Redis Store & Locks: RedisSessionStore supports ConnectionPool and exponential-backoff retries. Serializes data using Base64+Msgpack with elegant fallback; integrates a pessimistic distributed lock mechanism to avoid concurrent state overwrites.
  • 🔀 MQTT Wildcard EventBus: EventBus natively supports hierarchical wildcard subscriptions (* for single level, # for zero or more levels) matching with high-performance regex compilation cache routing.
  • 🎨 Built-in DaisyUI & TailwindCSS: Ships with integrated premium dark-mode glassmorphic components (DaisyUI) and utility-first styling (TailwindCSS) to build stunning user interfaces out-of-the-box.
  • 🌿 Client-Side Acceleration with Alpine.js: Bypasses verbose custom scripts in favor of Alpine.js, permitting high-frequency client-side interactions (like 60fps local ticking clocks and real-time clock skew calculation) defined as native attributes.
  • 📦 100% Offline & Air-Gapped Ready: All critical static assets (tailwind.js, daisyui.css, alpine.js, htmx.js) are fully hosted locally in the static/ folder. Build and deploy fast reactive applications in completely disconnected physical networks.
  • 🔀 Elegant Auto-Menu Component Routing: Declare routes effortlessly using pages=menu(Counter, TwoClocks, ChatRoom). Hiccl automatically generates kebab-case path endpoints and a premium glassmorphic navigation header.

🚀 Quick Start

1. Minimal Counter Component (examples/counter/app.py)

Hiccl components are clean, structural, and free of clutter:

from hiccl import (
    Component,
    ComponentRegistry,
    HicclConfig,  # Config remains clean and generic
    create_hiccl_app,
    menu,
    server,
    signal,
)
from hiccl.hiccup import button, div, h2

registry = ComponentRegistry()


class Counter(Component):
    """A minimal reactive counter."""

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.count = signal(0)

    @server
    def increment(self, step: int = 1):
        if isinstance(step, str):
            step = int(step)
        self.count.set(self.count.get() + step)

    @server
    def decrement(self, step: int = 1):
        if isinstance(step, str):
            step = int(step)
        self.count.set(self.count.get() - step)

    @server
    def reset(self):
        self.count.set(0)

    def render(self):
        count = self.count.get()
        return div(
            {"class": "card w-96 bg-base-200 shadow-xl border border-base-300 mx-auto"},
            div(
                {"class": "card-body items-center text-center"},
                h2(
                    {"class": "card-title text-3xl font-extrabold mb-4"},
                    f"Count: {count}",
                ),
                div(
                    {"class": "card-actions justify-center gap-2"},
                    button(
                        {
                            "class": "btn btn-outline btn-error",
                            "on_click": self.decrement(5),
                        },
                        "-5",
                    ),
                    button(
                        {"class": "btn btn-error", "on_click": self.decrement(1)}, "-1"
                    ),
                    button(
                        {"class": "btn btn-neutral", "on_click": self.reset}, "Reset"
                    ),
                    button(
                        {"class": "btn btn-success", "on_click": self.increment(1)},
                        "+1",
                    ),
                    button(
                        {
                            "class": "btn btn-outline btn-success",
                            "on_click": self.increment(5),
                        },
                        "+5",
                    ),
                ),
            ),
        )


# Route and mount the component instantly!
app = create_hiccl_app(HicclConfig(component_registry=registry, pages=menu(Counter)))

if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="127.0.0.1", port=8000)

2. ⚡️ Instant Development Mode (HMR & hREPL)

Hiccl offers a powerful Developer Mode Twin Engine engineered specifically for the AI era and maximum DX: state-preserving DOM-level HMR (Hot Module Replacement) and a non-blocking hREPL network socket server.

🚀 Launching the Dev Server

Use the new hiccl CLI tool to spin up your local app instantly with hot-reloading and REPL support:

uv run hiccl dev examples.combined_app:app --live-reload --hrepl
  • --live-reload: Activates state-preserving DOM-level Hot Module Replacement (HMR). Whenever you modify and save any .py component code, Hiccl reloads the module, updates the ComponentRegistry, and calculates the minimal DOM patches via the DiffEngine — 100% preserving all in-memory live Signal values in active sessions, and updating the browser in less than a second without page refreshes.
  • --hrepl: Launches the interactive network REPL server on 127.0.0.1:8998 (default).
    • Security Architecture: Bound to localhost by default, generating a random 32-character authentication Token on start (overridable via HREPL_TOKEN env var). All transactions are written securely to .hrepl_audit.log in the workspace.
    • Remote Surgery Evaluation: Operates over standard JSON-RPC. Developers or AI Agents can open TCP socket connections to evaluate complex multi-line and async statements containing await, allowing them to inspect live Session instances, probe Signals, and live-patch class methods on a hot, active server.

🛠 Architecture

Hiccl separates concerns cleanly to maintain high-throughput bidirectional reactive sync:

graph TD
    Client[Browser / Client] -->|htmx / WebSockets| Server[FastAPI / Starlette Backend]
    Server -->|Session Management| SessionStore[State Serialization / Persistence]
    SessionStore -->|Mount & Render| VDOM[Hiccup VDOM Tree]
    VDOM -->|Signal Trigger| DiffEngine[Minimal Diff Engine]
    DiffEngine -->|HTML Patches| WSChannel[WebSocket Push Channel]
    WSChannel -->|OuterHTML DOM Swap| Client
  1. Hiccup UI Engine: Translates nested Python arrays into HTML. Server actions annotated with @server are captured and serialized as network actions.
  2. Diff Engine: Any state mutation triggers localized dirty-checking and re-renders only the changed node, calculating the minimum HTML delta to push to the client.
  3. Local State Transportation Layer: Orchestrates low-latency updates via WebSockets and Server-Sent Events (SSE).

🤖 Why Hiccl is Natural-Born for the AI Era?

With AI Agents (like Antigravity) and Copilots becoming core drivers of development velocity, the traditional decoupled frontend/backend (React/Vue + REST API + Backend) paradigm has become a heavy cognitive tax for LLMs. Hiccl bypasses this entirely:

  1. 🧩 Single-Language & Unified Mental Model:

    • Eliminates constant context-switching between TypeScript (client) and Python (server).
    • The entire application (UI layout, reactive state, server-side events) is written 100% in declarative Python. AI only needs to reason in one programming language and one paradigm.
  2. 🔌 Zero API Glue Code, Eliminating Integration Hallucinations:

    • Bypasses writing REST/GraphQL endpoints, Pydantic schemas, Axios hooks, or client-side Redux/Pinia stores.
    • The AI simply mutates state via self.count.set(...) — synchronization is handled transparently. This completely eradicates integration bugs and AI schema mismatch failures.
  3. 🌿 UI as Pure Python Data Structures (Hiccup):

    • Defining DOM using native nested lists and tag functions prevents malformed, unclosed tags typical in raw HTML/JSX generation.
    • LLMs excel at generating structured nested arrays. Combined with mypy / pyright, the entire UI is type-safe and statically verifiable in milliseconds, allowing rapid AI self-correction.
  4. ⚡ Blazing Fast Testing & Self-Healing Loops:

    • Zero Webpack/Vite build steps to wait for.
    • Hiccl components can run end-to-end assertions in pure Python memory (over 140 tests in just 0.3 seconds!). This sub-second feedback loop enables AI agents to execute dozens of test-and-repair iterations in seconds.

📦 Offline Readiness

Hiccl is designed for secure, air-gapped internal networks. Run our combined 3-in-1 application to test the full potential of offline menu routing:

# Launch the air-gapped demo combining Counter, TwoClocks and ChatRoom
python3 examples/combined_app.py

Try These Highlights:

  1. DaisyUI Chat Bubbles: Navigate to /chat-room to test a beautiful multi-user chat room synchronized in real-time across browser tabs.
  2. DaisyUI Stats: Navigate to /two-clocks to view Alpine-powered ticking clocks with live server-client time skew metrics.
  3. Physical Disconnection: Disconnect your internet connection completely. The application remains fully functional, navigating and rendering flawlessly with locally-hosted scripts.

🛠️ Development & Contribution Guide

We warmly welcome and appreciate contributions from the community! To maintain pristine code quality, consistency, and velocity, please install our modern toolchain and adhere to the guidelines below before creating a Pull Request.

📦 1. Toolchain Management with mise

This project leverages mise for polyglot environment management and tasks automation. It is a modern, faster, and more robust alternative to traditional environment and script tools.

Why mise?

  • Unified Environments: It automatically pins and installs the precise versions of Python, Ruff, and uv configured in mise.toml and pyproject.toml when you enter the project directory.
  • Declarative Task Runner: Bypasses typing out lengthy terminal scripts by providing simple alias commands under mise run <task>.

Quick Installation & Setup

  1. Install mise:
    • macOS (Homebrew): brew install mise
    • Universal Script: curl https://mise.jdx.dev/install.sh | sh
  2. Trust & Activate the Project: In the root directory of the project, run:
    mise trust
    
    (Alternatively, you can activate mise in your terminal shell with eval "$(mise activate bash)" or your respective shell configuration for automatic activation.)

🚀 2. Everyday Development Tasks

Once mise is activated, you can execute these highly optimized tasks from your terminal:

Command Task Description Underlying Process
mise run lint Run Static Linter. Inspects the codebase using Ruff check for potential errors. ruff check
mise run format Code Formatter. Automatically formats code style, indentation, and structure. ruff format
mise run test Run Unit Tests. Runs 140+ highly optimized unit tests in milliseconds using Pytest. uv run -m pytest
mise run build Build Packages. Builds the source and wheel distribution artifacts. uv run -m build
mise run check Pre-publish Validation. Validates distribution metadata for PyPI using Twine. uv run -m twine check dist/*

[!TIP] You can run mise tasks to list all available tasks and their descriptions at any time.


🤝 3. Contribution Rules (Golden Rules)

Before submitting any Pull Request (PR), please verify that your changes adhere to these strict quality standards:

  1. Linter Passes Cleanly: Run mise run lint. There must be zero linting violations or warnings.
  2. Formatter Adheres Completely: Run mise run format to automatically format all files. No code modifications should deviate from the configured Ruff format settings.
  3. 100% Unit Test Pass Rate: Run mise run test. Every single test case must pass without exceptions or failures. Thanks to the high-efficiency architecture, all 140+ tests execute in less than 0.5s!

[!IMPORTANT] The project CI executes strict formatting, linting, and pytest suites on every PR. Any failure in these stages will block merging. Please run these check tasks locally before committing and pushing.


📝 License

This project is licensed under the MIT License.

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

hiccl-0.4.0.tar.gz (430.1 kB view details)

Uploaded Source

Built Distribution

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

hiccl-0.4.0-py3-none-any.whl (432.0 kB view details)

Uploaded Python 3

File details

Details for the file hiccl-0.4.0.tar.gz.

File metadata

  • Download URL: hiccl-0.4.0.tar.gz
  • Upload date:
  • Size: 430.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for hiccl-0.4.0.tar.gz
Algorithm Hash digest
SHA256 f5928f9f123c1e0ab3703af07e4a5322578174bdc48bdcb65f83f91d603c6514
MD5 464e1702adfe31cdfeab412ba4612c94
BLAKE2b-256 d421402a0fb0620633e5ad72b9713dd6dc23094937b836902707a253c18ff947

See more details on using hashes here.

File details

Details for the file hiccl-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: hiccl-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 432.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for hiccl-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b3647353d7c8dfbb7f37281ae9123ef225496b8075c1ed2412ce277eb3d17e6c
MD5 bd3a72dff0c0d0b2745e440230dcfa08
BLAKE2b-256 ff325b7285961f1efb9428ffbba1aab86ed8520e9a5bae7e346b3679b468b396

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