pywebview 2.0 released

Pywebview, an Electron like library for Python, has reached version 2.0. Pywebview lets you create GUI applications with a combination of web technologies and Python. You would use Python for your application logic and Javascript and CSS for GUI. Pywebview is freeze friendly and aims to provide frozen executable support out of the box.

The biggest change in 2.0 is a two-way communication between Python and Javascript, which eliminates the need of a Python web server altogether. Consider a simple Hello World example.


import webview
from threading import Thread

class Api():
    def helloWorld(self, param):
        return 'Hello Python!'

def load_html():
  webview.load_html('<p>Hello World</p>')
  webview.evaluate_js("""
    pywebview.api.helloWorld().then(function(response) {
      alert(response)
    })
  """)


if __name__ == '__main__':
    api = Api()
    t = Thread(target=load_html)
    t.start()

    webview.create_window('Hello world', js_api=api)

There are two communication devices. From Python you use evaluate_js, which executes arbitrary Javascript code and returns the result. To run your Python code from Javascript, you define a custom class and pass its instance to the API parameter of create_window. All the public methods of the class will be exposed in Javascript via the pywebview.api object. Note that custom methods must always define a single parameter, even if you don’t need one. If you wish to pass multiple parameters, you can put them in a dict. Return and parameter types are converted between Javascript and Python.

For a more real world example, see our very own TODO app

The other big feature for this support is multi-window support. To create a second window, you could something like this.


import webview
import threading

def create_new_window():
    child_window = webview.create_window('Window #2', width=800, height=400)

    webview.load_html('<h1>Master Window</h1>')
    webview.load_html('<h1>Child Window</h1>', uid=child_window)

if __name__ == '__main__':
    t = threading.Thread(target=create_new_window)
    t.start()

    # Master window
    webview.create_window('Window #1', width=800, height=600)


After the master window is created, subsequent create_window calls are non blocking and return a unique id that can be passed to other functions.

Other new features include

  • When creating a window, you can now specify a relative path to a html file (that is without a file:// or any other protocol). This way relatively linked resources will be resolved correctly. This will work when application is frozen too.
  • target='_blank' links are opened in an external browser
  • Text selection on non input elements is disabled by default
  • new load_css function for ahem loading custom css

The complete changelog can be found here

Future plans

The biggest challenge at the moment is the rapidly dating Internet Explorer engine on Windows, which remains the only native web renderer available to developers. Edge support has never arrived and by the current prospects never will. In other words, IE11 is the best you can get at the moment on Windows. The semi quick solution would be to introduce QT support with its WebKit engine and also CEF support is planned. Both these solutions would considerably increase the application distribution size, but at the moment there is no other way to keep the pace of the ever-evolving web standards.

Get involved

Pywebview is a small project with limited resources, so any help is more than welcome. PRs, documentation, research, anything goes. Having said that commits are preferred over comments. Check out the contributing guide to get started.

If you think that pywebview is cool and wish to support it financially, check way to donate in the contributing guide. Or maybe if you wish to become a sponsor, then drop me a line.