Skip to main content

pgwidgets logo

A native JavaScript widget toolkit with Qt/GTK-style layout and controls.
No frameworks. No build step. No dependencies.


What is PGWidgets?

pgwidgets is a pure JavaScript widget library that brings desktop-style UI controls to the browser. If you've used Qt, GTK, or Tkinter, the API will feel familiar: create widgets, pack them into layout containers, and wire up callbacks.

import { Widgets } from "./Widgets.js";

let top = new Widgets.TopLevel({title: "Hello", resizable: true});
top.resize(400, 300);

let vbox = new Widgets.VBox();
vbox.set_spacing(8);
vbox.set_padding(10);

let label = new Widgets.Label("Click the button!");
let button = new Widgets.Button("Click me");
button.add_callback('activated', () => label.set_text("Clicked!"));

vbox.add_widget(button, 0);
vbox.add_widget(label, 1);
top.set_widget(vbox);
top.show();

Features

  • Zero dependencies -- pure JavaScript ES modules, works directly in the browser
  • No build step -- just include Widgets.js and Widgets.css
  • Desktop-style layouts -- VBox, HBox, GridBox, Splitter, TabWidget, ScrollArea
  • MDI workspace -- multiple draggable, resizable sub-windows with cascade/tile
  • Remote interface -- drive the UI over WebSocket from Python or any language
  • Familiar API -- callbacks, containers, and widget hierarchy inspired by Qt/GTK

Widgets

Layout & Containers

Widget Description
TopLevel Top-level window with optional title bar, dragging, and resize grips
VBox / HBox Vertical and horizontal box layouts with spacing and stretch factors
GridBox Grid layout with row/column placement
Splitter Resizable split pane (horizontal or vertical)
TabWidget Tabbed container with switchable pages
StackWidget Stacked pages without tab headers
ScrollArea Scrollable viewport with custom scrollbars
Frame Titled border container
Expander Collapsible section with a clickable header
MDIWidget Multiple Document Interface workspace with sub-windows
ButtonBox Box layout for buttons with uniform sizing and alignment
AbstractScrollArea Low-level scrollable viewport with custom scrollbars

Controls

Widget Description
Button Push button with optional icon
ToggleButton Two-state button, supports exclusive groups
CheckBox Checkbox with label
RadioButton Radio button with exclusive group support
ComboBox Dropdown with optional editable text, filtering, and scroll limit
Slider Range slider (integer or float)
SpinBox Numeric input with increment/decrement buttons
Dial Rotary knob control
ScrollBar Standalone scrollbar with draggable thumb
ProgressBar Determinate progress indicator
StatusBar Horizontal status bar with message sections

Text & Display

Widget Description
Label Static text with alignment, color, and font options
TextEntry Single-line text input with line history
TextEntrySet Text entry with a submit button
TextArea Multi-line text editor
Image Image display widget
Canvas HTML5 canvas for custom drawing
TreeView Hierarchical tree/table with columns, sorting, icons, and multi-selection
HtmlView Rich HTML content display
TableView Flat table with columns, sorting, and multi-selection
VideoWidget Video playback with controls
ExternalWidget Embed third-party content (Plotly, Bokeh, etc.) in layout containers

Menus & Toolbars

Widget Description
MenuBar Horizontal menu bar
Menu Dropdown menu with actions
ToolBar Toolbar with buttons, toggles, and separators
ToolBarAction Individual toolbar button/toggle with icon support

Dialogs

Widget Description
Dialog Modal or non-modal dialog with configurable buttons
ColorDialog Color picker with SV plane, hue strip, and RGB/HSV/hex inputs
FileDialog Browser file open/save dialog

Non-Visual

Widget Description
Timer Non-visual timer for delayed and periodic actions

Documentation

Full documentation is available at pgwidgets-js.readthedocs.io.

Installation

Standalone (no tooling)

Copy the repository and include it directly:

<link rel="stylesheet" href="path/to/Widgets.css" />
<script type="module">
  import { Widgets } from "path/to/Widgets.js";
  // ...
</script>

npm

npm install pgwidgets          # once published
# or install directly from GitHub:
npm install github:naojsoft/pgwidgets-js

Then in your bundled app:

import { Widgets } from "pgwidgets";
import "pgwidgets/Widgets.css";

Using from Python (Pyodide / PyScript)

pgwidgets can be used directly from Python in the browser via Pyodide or PyScript. The pgwidgets_js.pyodide module provides Pythonic wrappers with normal construction syntax, automatic type conversion, and callback management.

from pgwidgets_js.pyodide import Widgets

top = Widgets.TopLevel(title="Hello", resizable=True)
top.resize(400, 300)

vbox = Widgets.VBox(spacing=8, padding=10)

label = Widgets.Label("Click the button!")
button = Widgets.Button("Click me")
button.on("activated", lambda: label.set_text("Clicked!"))

vbox.add_widget(button, 0)
vbox.add_widget(label, 1)
top.set_widget(vbox)
top.show()

No WebSocket server needed -- everything runs in the browser. The same Python code works with both Pyodide and PyScript; only the HTML loader differs. See examples/pyodide_demo.html for a minimal Pyodide example, examples/all_widgets_pyodide.html for a full demo via Pyodide, and examples/all_widgets_pyscript.html for the same demo via PyScript.

Remote Interface (WebSocket)

pgwidgets can also be controlled from a Python server over WebSocket using the pgwidgets-python package. The browser page connects to the server, which sends JSON messages to create widgets, call methods, and receive callbacks.

from pgwidgets.sync import Application

app = Application()

@app.on_connect
def setup(session):
    W = session.get_widgets()

    top = W.TopLevel(title="Remote App", resizable=True)
    top.resize(400, 300)

    vbox = W.VBox(spacing=8)
    btn = W.Button("Click me")
    status = W.Label("Ready")

    btn.on("activated", lambda: status.set_text("Clicked!"))

    vbox.add_widget(btn, 0)
    vbox.add_widget(status, 1)
    top.set_widget(vbox)
    top.show()

app.run()

Sessions persist independently of browser connections. Refresh the page and the UI is automatically reconstructed. Open the same session URL in multiple browser tabs and they stay synchronized in real time -- slider moves, tab switches, tree expand/collapse, and more are pushed to all connected browsers.

See examples/remote_demo.py and examples/remote_demo_async.py for complete working examples.

Building Desktop Apps with Electron

Because pgwidgets is just a browser library with no dependencies, it runs unchanged inside an Electron renderer process. This lets you ship pgwidgets UIs as native desktop apps with their own window chrome, system menus, and access to the file system.

A minimal example lives in examples/electron/:

cd examples/electron
npm install     # one-time, installs Electron locally
npm start       # launches the all_widgets demo in an Electron window

The Electron entry point (main.js) is about 20 lines and simply creates a BrowserWindow that loads an HTML file -- no Electron-specific changes are needed in pgwidgets itself. To use your own UI, edit main.js to point at a different HTML file.

Embedding Third-Party Libraries

The ExternalWidget class lets you embed content from third-party JavaScript libraries -- Plotly charts, Bokeh plots, Leaflet maps, D3 visualizations, and more -- into pgwidgets layout containers. The widget participates in pgwidgets layout (stretch factors, splitters, tabs) while its content area is managed by the external library.

let chart = new Widgets.ExternalWidget();
vbox.add_widget(chart, 1);  // stretch=1 fills available space

Plotly.newPlot(chart.get_content_element(), data, layout,
               {responsive: true});

See the documentation for full examples with Plotly, Bokeh, and other libraries.

Running the Examples

Start a local web server from the repository root:

python -m http.server --bind localhost 8000

Then open any example in your browser:

And many more in the examples/ directory.

License

BSD 3-Clause

Metadata

Release files for pgwidgets-js 0.4.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pgwidgets-js 0.4.2
File Size Uploaded
pgwidgets_js-0.4.2.tar.gz 2.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pgwidgets-js 0.4.2
File Interpreter ABI Platform
pgwidgets_js-0.4.2-py3-none-any.whl Python 3 none any Details

Total release size: 5.2 MB

Release files / pgwidgets_js-0.4.2.tar.gz

Download URL pgwidgets_js-0.4.2.tar.gz
Size 2.6 MB
Tags Source
SHA-256 checksum
How to use checksums
9e4691e4e0cd14da51ed7f3a814d8711f0787337355b406a719261df67f135aa
BLAKE2b-256 checksum
How to use checksums
4827350a9f951341f4e0a96709236193ecb863145b3c356a86736b90117818b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

Release files / pgwidgets_js-0.4.2-py3-none-any.whl

Download URL pgwidgets_js-0.4.2-py3-none-any.whl
Size 2.5 MB
Tags Python 3
SHA-256 checksum
How to use checksums
748fd9954c78e271771c3e08db3ed6b6bec8c0866eefde518245076dc80cb5a2
BLAKE2b-256 checksum
How to use checksums
f5806d0179d2cef656fa9abd9475d0388ea4fb12f4bcd8d11a9db729e0c0124b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

Release history Release notifications | RSS feed

This release

0.4.2 This release

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.3

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

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