This repository provides a solid, modern, and reusable boilerplate for building Inkscape extensions with advanced HTML/CSS/JavaScript User Interfaces (UI).
By utilizing GTK+ 3 and WebKit2, this boilerplate embeds a native web browser engine directly within your Inkscape extension, allowing you to build beautiful, responsive, and complex interfaces that circumvent Inkscape's limited native inkex parameters dialogs.
- Modern UI Stack: Write your extension interface in pure HTML, CSS, and JS.
- Native Window Feeling: Renders a fixed-size, system-native GTK window that feels like a standalone desktop app.
- Asynchronous Communication: Implements a local HTTP Server inside Python that communicates with the JS frontend via the
Fetch API. - Dynamic UI State: The included example (Basic Shape Inserter) showcases responsive UI updates (e.g., hiding/showing inputs dynamically without page reloads).
- Background Processing: SVG generation is offloaded to a background thread, while the UI displays a realtime responsive loading bar via polling (
/status). - Auto-Cleanup: The built-in HTTP server and GTK loops tear down cleanly upon UI closure.
ink_web_ui_boilerplate/
├── ink_web_ui.inx # Inkscape Extension Definition file (XML)
├── ink_web_ui.py # Main Python Backend (inkex logic + HTTP Server)
└── ui/ # Frontend Web Assets
├── index.html # Main UI layout
├── style.css # Premium Dark Mode CSS (Flexbox, custom native selects)
└── app.js # Client-side API fetch logic and status polling
- Initialization: When the extension is invoked from Inkscape (via
ink_web_ui.inx), Inkscape launchesink_web_ui.py. - Server Spin-up: The
WebUIExtensionclass (inheriting frominkex.EffectExtension) dynamically finds an open TCP port and starts Python'shttp.server.SimpleHTTPRequestHandlerin a daemon background thread. - GTK WebKit Rendering: The script invokes a native GTK Window and loads a
WebKit2.WebViewbound tohttp://localhost:<port>/index.html. - UI Interaction (Frontend): The user interacts with the UI. Upon clicking "Submit",
app.jsbundles the form values into a JSON object and POSTs it to the/submitendpoint. - Processing (Backend):
- The Python backend accepts the POST request, replies with HTTP 200
{"status": "started"}, and spawns a backgroundthreading.Threadtargetingprocess_background(). process_background()holds the actualinkexdrawing logic. It can safely modify the SVG document. It updatesself.status_datawith progress percentages and messages.
- Polling: Meanwhile,
app.jsruns asetIntervalloop polling the/statusGET endpoint every 500ms to update the HTML Progress Bar.
- The Python backend accepts the POST request, replies with HTTP 200
- Termination: Once
process_background()finishes producing the SVG output, it sends a command to terminate the GTK Main loop, closes the server, and returns control to Inkscape to apply the SVG modifications.
To use this boilerplate for your own Inkscape tools:
- Rename the ID/Name: Edit
ink_web_ui.inxto give your extension a unique<id>and<name>. - Update the UI: Modify
ui/index.htmlto include the form inputs you need. Adjust the styling instyle.cssif desired. - Process Output: In
ink_web_ui.py, navigate to theprocess_background(self, data)method.- The
datavariable is a Python dictionary containing all the form fields passed from JavaScript. - Delete the boilerplate "Basic Shape Inserter" logic inside this function.
- Retrieve your current layer with
layer = self.svg.get_current_layer(). - Construct your new SVG objects (e.g.,
inkex.PathElement(), Text, etc.) and append them to the layer. - Update
self.status_datathroughout your long-running loops for a great user experience.
- The
- Inkscape 1.2+ (Uses the modern
inkexAPI extension classes). - OS with GTK+ 3 and WebKit2Gtk installed (Standard on almost all modern Linux distributions. On Windows/macOS, it automatically falls back to opening the system's default web browser).
We don't guarantee anything about this tool/extension, so please use it at your own risk. We can't give 24/7 support if you have a problem when using this boilerplate.
If you feel that this tool has helped you to create, feel free to donate a cup of coffee on the Support Dev :")
This project is licensed under the GNU General Public License v3.0 (GPLv3). See the LICENSE file for details.