Skip to main content

Modern Python desktop framework – lightweight, secure, beautiful

Project description

PyPulsar

PyPI License: MIT Python Versions Stars PyPI Downloads

Modern Python desktop framework – fast, light, secure.
Build native-feeling desktop apps with HTML/CSS/JS frontend and full Python backend. No Electron bloat, no Rust required.

  • 🚀 Lightning Fast: ~5–15 MB bundles, <100 MB RAM
  • 🔒 Secure by Default: Built-in ACL (Access Control List)
  • 🛠️ Easy CLI: pypulsar create my-app && pypulsar dev
  • 🎨 Native WebView: Cocoa (macOS), Edge (Windows), GTK (Linux)

Why PyPulsar?

Tired of Electron's massive RAM usage? Not interested in learning Rust for Tauri?
PyPulsar is Python-first – leverage NumPy, Pandas, ML models, and all your favorite Python libraries while building rich desktop apps with modern web technologies.

  • Minimal dependencies (pywebview + aiohttp)
  • Hot reload for HTML/CSS/JS during development
  • Plugin system (system tray, notifications, auto-updates, etc.)
  • Full cross-platform support (Windows, macOS, Linux)

Note: Basic internal plugins are supported today; external plugin distribution via CLI is under development.

Quick Comparison

Feature PyPulsar Electron Tauri
Backend Python Node.js Rust
UI HTML/CSS/JS HTML/CSS/JS HTML/CSS/JS
Bundle Size 5–15 MB 100–300 MB 0.6–3 MB
RAM Usage 50–100 MB 200+ MB <80 MB
Security ACL + validation CSP (manual) Dynamic ACL
Mobile No(Work in progress) Partial Yes
Learning Curve Low (Python + web) Low (JS) Medium (Rust)

Perfect for data dashboards, internal tools, ML interfaces, and utilities.

Installation

pip install PyPulsar

Getting Started

Use the CLI to create a new project:

pypulsar create my-app --template basic
cd my-app
pypulsar dev  # Development with hot reload
pypulsar build  # For production bundles

This generates: main.py (entry point), web/index.html (frontend).

Tip: Run pypulsar --help for more CLI options.

Basic Example

PyPulsar uses the Engine class to manage the app, serve static files, and create windows.

from pypulsar.engine import Engine

engine = Engine(serve=True, webroot="web", debug=True)
engine.create_window("/index.html", "PyPulsar App", 900, 700)
engine.run()

Frontend files go in the web/ folder (e.g., web/index.html). web/index.html example:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PyPulsar App</title>
</head>
<body>
    <h1>Hello from PyPulsar!</h1>
    <p>This is a full HTML/CSS/JS frontend with live DOM manipulation.</p>
</body>
</html>
  • Live DOM manipulation: Full and direct in JavaScript – just like a regular web app.
  • Python → JS: Use engine.window.evaluate_js("your JS code") to push updates (e.g., background tasks, ML results).
  • JS → Python: Expose Python functions via pywebview's js_api (enhanced with ACL for security).

Simple Counter with Bidirectional Communication and ACL

from pypulsar.engine import Engine, Hooks
from pypulsar.acl import acl

# Allow the event in ACL
acl.allow("increment_counter")

engine = Engine(serve=True, webroot="web", debug=False)

counter = 0

def handle_event(event_name, data):
    global counter
    if event_name == "increment_counter":
        counter += 1
        window.evaluate_js(
            f"document.getElementById('counter').innerText = '{counter}';"
        )

engine.register_hook(Hooks.ON_EVENT, handle_event)

window = engine.create_window(
    path="/index.html",
    title="Counter App",
    width=800,
    height=600
)
engine.run()

web/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Counter App</title>
</head>
<body>
    <h1>Counter: <span id="counter">0</span></h1>
    <button onclick="increment()">Increment</button>
    <script>
        function increment() {
            // Send event to Python (validated by ACL)
            window.pywebview.api.pywebview_message('increment_counter', {});
        }
    </script>
</body>
</html>

Note: Avoid calling evaluate_js before engine.run(). Use window.events.loaded for initial UI setup.

Security: Built-in ACL

PyPulsar's ACL is default-deny: JS events are blocked unless whitelisted.

from pypulsar.acl import acl

acl.allow("event_name")  # Simple whitelist

# Optional validator
@acl.validator("event_name")
def validate_payload(payload):
    return 'key' in payload and payload['key'] == 'secret'  # Return bool
  • Deny with acl.deny("pattern").
  • Protects against unauthorized frontend access.

Project Status

PyPulsar is currently in beta.

The framework is under active development and new features, APIs, and improvements are delivered on a regular basis. Breaking changes may occur as the architecture is refined, so early adopters should expect some evolution in interfaces and behavior.

Despite the beta status, the core concepts (plugin system, backend–frontend bridge, application lifecycle) are already usable and stable enough for experimentation, prototypes, and internal tools.

Mobile Support (Work in progress)

Support for mobile platforms is actively being explored.

At the moment, development is focused on Android as the first supported mobile target. The goal is to enable PyPulsar applications to run using the same core architecture, plugin system, and API surface across desktop and mobile environments.

Mobile support is still work in progress and not yet considered production-ready. Updates related to Android integration will be introduced incrementally as the framework evolves.

Plugin Ecosystem (Work in progress)

Work is currently underway on expanding the plugin ecosystem and improving plugin distribution.

One of the key goals is to introduce first-class CLI support for plugins, allowing developers to:

  • easily install external plugins via the PyPulsar CLI,
  • manage plugin versions (install, update, downgrade),
  • enable or disable plugins per application,
  • ensure compatibility between the framework version and installed plugins.

This will make PyPulsar’s plugin system more modular, discoverable, and suitable for building reusable extensions maintained independently from the core framework.

The plugin manager and CLI workflow are still under active development and will be introduced incrementally in upcoming releases.

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

pypulsar-0.1.3.tar.gz (42.0 kB view details)

Uploaded Source

Built Distribution

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

pypulsar-0.1.3-py3-none-any.whl (49.7 kB view details)

Uploaded Python 3

File details

Details for the file pypulsar-0.1.3.tar.gz.

File metadata

  • Download URL: pypulsar-0.1.3.tar.gz
  • Upload date:
  • Size: 42.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for pypulsar-0.1.3.tar.gz
Algorithm Hash digest
SHA256 cb4039996769e31fd333fb675fb5f48d422aa875d01e0064effe5b254a3eee67
MD5 2dc6cb845e3335009f5a5b51f1c24b19
BLAKE2b-256 8592d2de0fe1d16b71b970486d85d77c463e812e7db83e809a3fe19b69c46aa1

See more details on using hashes here.

File details

Details for the file pypulsar-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: pypulsar-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 49.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for pypulsar-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 96cfba0e11851e621256d7a2f93b097c6d8cbbba1825ac66e8c09008380acdb8
MD5 c764900eabee258a68d105245033511d
BLAKE2b-256 a1c7868a98d77b2565175fea4566e9979eedb5d3c9b18f273ffb558e5c13a26e

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