Skip to main content

Dars is a Python UI framework for building modern, interactive web apps with only Python code. Write your interface in Python, export it to static HTML/CSS/JS, and deploy anywhere.

Project description

Dars Framework

Dars Framework Logo

Dars is a multiplatform Python UI framework for building modern, interactive web and desktop apps with Python code. Write your interface in Python, export it to web technologies and deploy anywhere.

Official Website | Documentation Docs | DeepWiki here |

pip install dars-framework

Try dars without installing nothing(single page mode) just visit the Dars Playground

How It Works

  • Build your UI using Python classes and components (like Text, Button, Container, Page, etc).
  • Preview instantly with hot-reload using app.rTimeCompile().
  • Export your app to static web files with a single CLI command.
  • Export to native desktop apps (BETA) using project config format: "desktop" and dars build.
  • Use multipage, layouts, scripts, and more—see docs for advanced features.
  • For more information visit the Documentation

Quick Example: Your First App

from dars.all import *

app = App(title="Hello World", theme="dark")

index = Page(
     Text(
        text="Hello World",
        style={
            'font-size': '48px',
            'color': '#2c3e50',
            'margin-bottom': '20px',
            'font-weight': 'bold',
            'text-align': 'center'
        }
    ),
    Text(
        text="Hello World",
        style={
            'font-size': '20px',
            'color': '#7f8c8d',
            'margin-bottom': '40px',
            'text-align': 'center'
        }
    ),

    Button(
        text="Click Me!",
        on_click= alert('Hello from DARS!'),
        style={
            'background-color': '#3498db',
            'color': 'white',
            'padding': '15px 30px',
            'border': 'none',
            'border-radius': '8px',
            'font-size': '18px',
            'cursor': 'pointer',
            'transition': 'background-color 0.3s'
        }
    ),
    style={
        'display': 'flex',
        'flex-direction': 'column',
        'align-items': 'center',
        'justify-content': 'center',
        'min-height': '100vh',
        'background-color': '#f0f2f5',
        'font-family': 'Arial, sans-serif'
    }
) 

app.add_page("index", index, title="Hello World", index=True)

if __name__ == "__main__":
    app.rTimeCompile()

Backend HTTP Utilities & API Communication

Dars provides a system for HTTP requests and API communication without writing JavaScript. Use useData() for clean data binding:

from dars.all import *
from dars.backend import get, useData

# Create components
user_display = Text("", id="user-name")
user_state = State(user_display, text="")

# Fetch and bind data - pure Python!
fetch_btn = Button(
    "Fetch User",
    on_click=get(
        id="userData",
        url="https://api.example.com/users/1",
        # Access nested data with dot notation
        callback=user_state.text.set(useData('userData').name)
    )
)

Chain Multiple Updates

Use .then() to chain state updates sequentially:

# Update multiple components from API response
callback=(
    name_state.text.set(useData('userData').name)
    .then(email_state.text.set(useData('userData').email))
    .then(website_state.text.set(useData('userData').website))
)

Available HTTP Methods

  • get(id, url, **options) - GET request
  • post(id, url, body, **options) - POST request
  • put(id, url, body, **options) - PUT request
  • delete(id, url, **options) - DELETE request

For complete documentation, see the Backend API Guide.


State Management System

Dars Framework features two powerful state management systems, each designed for different use cases:

1. State V2 (Dynamic)

Modern, Pythonic state management for simple reactive updates. Best for counters, timers, and single-component interactions.

from dars.all import *

# Create state with component
counter = State(Text("0", id="counter"), text=0)

# Or use string ID for dynamic components
dynamic_state = State("dynamic-counter", text=0)

# Reactive operations
inc_btn = Button("+1", on_click=counter.text.increment(by=1))
set_btn = Button("Reset", on_click=counter.reset())

# Auto-increment
start_btn = Button("Start", on_click=counter.text.auto_increment(by=1, interval=1000))

String ID Support: State() can accept either a component object or a string ID, perfect for components created dynamically with createComp().

2. dState & cState (Indexed)

Powerful indexed state system for complex state machines, multi-step workflows, and cross-component coordination.

from dars.core.state import dState, Mod

# Define state with indices [0, 1, 2]
toggle = dState("toggle", component=btn, states=[0, 1, 2])

# Define rules for state 1
toggle.cState(1, mods=[
    Mod.set(btn, text="Active", style={'background': 'green'}),
    Mod.set(status_text, text="System Online")
])

# Navigate by index
btn.on_click = toggle.state(1)

Comparison

Feature State V2 (Dynamic) dState/cState (Indexed)
Best For Simple updates, counters, timers Complex workflows, state machines
API Style Clean, Pythonic Explicit, Indexed
State Tracking Dynamic values Fixed Indices (0, 1, 2...)
Auto Ops Built-in (auto_increment) Manual via Mod
Cross-State No Mod.call() supported
Dynamic Components String ID support Component required

For detailed documentation, visit the State Management Guide.


Animation System

Dars includes 15+ built-in animations that work seamlessly with state management:

from dars.all import fadeIn, fadeOut, pulse, shake, sequence

# Single animation
button.on_click = fadeIn(id="modal", duration=500)

# Chain multiple animations
button.on_click = sequence(
    fadeIn(id="box"),
    pulse(id="box", scale=1.2, iterations=2),
    shake(id="box", intensity=5)
)

# Combine with state updates
button.on_click = sequence(
    counter.text.increment(by=1),
    pulse(id="counter", scale=1.2)
)

Available Animations:

  • Opacity: fadeIn, fadeOut
  • Movement: slideIn, slideOut (up, down, left, right)
  • Scaling: scaleIn, scaleOut, pulse
  • Interactive: shake, bounce, rotate, flip
  • Effects: colorChange, morphSize

For complete animation documentation, visit the Animation Guide.


Dynamic Updates with this()

Update components directly without pre-defining states:

from dars.all import *

# Self-updating button
btn = Button("Click Me!", on_click=this().state(
    text="Clicked!",
    style={"background-color": "green"}
))

Script Chaining with .then()

Chain asynchronous operations using .then() or sequence():

from dars.all import *

# Chain animation + state update
button.on_click = sequence(
    fadeOut(id="status"),
    state.text.set(value="Loading...")
).then(
    fadeIn(id="status")
)

SPA Routing System

Dars 1.4.6 introduces a powerful client-side routing system for Single Page Applications:

Basic Routing

Use the @route decorator or route parameter to create SPA routes:

from dars.all import *

app = App(title="My SPA")

# Using decorator
@route("/")
def home():
    return Page(Text("Home Page"))

# Using parameter
about_page = Page(Text("About Us"))
app.add_page("about", about_page, route="/about")

app.add_page("home", home())

Nested Routes with Outlet

Create complex layouts with parent-child routes using the Outlet component:

# Parent layout with navigation
@route("/dashboard")
def dashboard():
    return Page(
        Text("Dashboard", style={"fontSize": "24px"}),
        Container(
            Link("Settings", href="/dashboard/settings"),
            Link("Profile", href="/dashboard/profile"),
            id="nav",
            
        ),
        Outlet(),  # Child routes render here
        style={"padding": "20px"}
    )

# Child routes
settings_page = Page(Text("Settings Content"))
profile_page = Page(Text("Profile Content"))

# NOTE if you don't assign index=True to one of the pages when using more than 1 page with SPA route system
# you get a 404 error because the router doesn't knwow the index page and cannot assign it as index.
# this is probably going to be fixed in next updates
app.add_page("dashboard", dashboard(), index=True)
app.add_page("settings", settings_page, route="/dashboard/settings", parent="dashboard")
app.add_page("profile", profile_page, route="/dashboard/profile", parent="dashboard")

404 Error Handling

Dars automatically handles 404 errors with a default page, or you can customize it:

# Custom 404 page
custom_404 = Page(
    Text("Oops! Page not found", style={"fontSize": "32px", "color": "red"}),
    Link("Go Home", href="/")
)

app.set_404_page(custom_404)

Hot Reload for SPAs

The development preview server includes intelligent hot reload:

  • Detects changes and reloads automatically
  • Stops polling after 10 errors to prevent browser lag
  • Clean console output without spam

CLI Usage

Command What it does
dars export my_app.py --format html Export app to HTML/CSS/JS in ./my_app_web
dars init --type desktop Scaffold desktop-capable project (BETA)
dars build (desktop config) Build desktop app artifacts (BETA)
dars preview ./my_app_web Preview exported app locally
dars init my_project Create a new Dars project (also creates dars.config.json)
dars init --update Create/Update dars.config.json in current dir
dars build Build using dars.config.json (entry/outdir/format)
dars config validate Validate dars.config.json and print report
dars info my_app.py Show info about your app
dars formats List supported export formats
dars --help Show help and all CLI options

Tip: use dars doctor to review optional tooling that can enhance bundling/minification.

Desktop Export (BETA)

  • Mark your project for desktop in dars.config.json with "format": "desktop".
  • Initialize backend scaffolding with dars init --type desktop (or --update).
  • Build with dars build to produce desktop artifacts under dist/.
  • This feature is in BETA: usable for testing, not yet recommended for production.

Local Execution and Live Preview

To test your app locally before exporting, use the hot-reload preview from any Python file that defines your app:

if __name__ == "__main__":
    app.rTimeCompile()

Then run your file directly:

python my_app.py

This will start a local server at http://localhost:8000 so you can view your app in the browser—no manual export needed. You can change the port with:

python my_app.py --port 8088

You can also use the CLI preview command on an exported app:

dars preview ./my_exported_app

This will start a local server at http://localhost:8000 to view your exported app in the browser.


Project Configuration (dars.config.json)

Dars can read build/export settings from a dars.config.json at your project root. It is created automatically by dars init, and you can add it to existing projects with dars init --update.

Example default:

{
  "entry": "main.py",
  "format": "html",
  "outdir": "dist",
  "publicDir": null,
  "include": [],
  "exclude": ["**/__pycache__", ".git", ".venv", "node_modules"],
  "bundle": true,
  "defaultMinify": true,
  "viteMinify": true
}
  • entry: Python entry file. Used by dars build and dars export config.
  • format: Export format. Currently only html is supported.
  • outdir: Output directory. Used by dars build and default for dars export when not overridden.
  • publicDir: Folder (e.g., public/ or assets/) copied into the output. If null, it is autodetected.
  • include/exclude: Basic filters for copying from publicDir.
  • bundle: Reserved for future use. CLI exports and build already bundle appropriately.
  • defaultMinify: Toggle the built-in Python minifier (safe, conservatively preserves <pre>, <code>, script, style, textarea). Controls HTML minification and provides JS/CSS fallback when advanced tools are unavailable. Default true.
  • viteMinify: Toggle the Vite/esbuild minifier for JS/CSS. Default true.

Validate your config:

dars config validate

Build using config:

dars build

Export using the config entry and outdir:

dars export config --format html

See LandingPage docs for details: state_management.md, events.md, scripts.md, routing.md.

Project details


Release history Release notifications | RSS feed

Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

dars_framework-1.5.1-py3-none-any.whl (837.0 kB view details)

Uploaded Python 3

File details

Details for the file dars_framework-1.5.1-py3-none-any.whl.

File metadata

  • Download URL: dars_framework-1.5.1-py3-none-any.whl
  • Upload date:
  • Size: 837.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for dars_framework-1.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 669474d217c0b18ab1715431ea7357dbbed8a1a951120ce53840021c8f42cc4d
MD5 0bd1fbb620c52404047a40e38c85603b
BLAKE2b-256 d02a598db37fe3a57a1c195bbb84c1112309037d85bcc49578a8cce225589b8c

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