Anatomy of an app
Anatomy of an app
A pekoui app is one native binary hosting the platform's webview, plus an ordinary npm web app. macOS uses WKWebView, Linux WebKitGTK, Windows WebView2, and there are iOS and Android backends. The two halves talk over a bridge.
pekoui is a normal dependency and is not auto-imported:
import pekoui as ui;Its modules are app, webview, bridge, assets, storage, keychain,
menu, dialog, env, and paths.
The smallest complete app
import pekoui as ui;
fn on_start() {
ui::app::from_bundle().run()
}That serves the bundled web UI over a loopback server, starts the bridge, and
runs the event loop. The entry function is on_start, the same as every other
Peko program.
from_bundle() reads the window title and size from the manifest, defaulting to
500 by 500.
The App surface
[public] fn from_bundle() => App
[mutates] fn allow_multiple_instances()
[public] fn webview() => webview::WebView
[mutates] fn on(method: string, handler: closure(string) => string)
[public] fn emit(name: string, data: string)
[public] fn route() => string
[public] fn navigate(path: string)
[mutates] fn enable_deeplinks()
[mutates] fn use_html_menu()
[mutates] fn set_menu(bar: menu::Menu)
[public] fn run()What run() does
In order: check whether this process is a pop-up child and take that path if so; decide between the local loopback bridge and the hosted one; start the asset server unless running against a dev server; register the window handlers; inject the boot configuration into the page; enable deep links; navigate; then enter the native event loop.
run() blocks until the window closes, so anything after it is your shutdown
hook:
fn on_start() {
let application = ui::app::from_bundle();
let child: process::Process? = spawn_helper();
register_handlers(application);
application.run();
if child.is_value() { child.unwrap().kill(); }
}Ordering that matters
Do process work that forks before the GUI toolkit initializes. A language server
or helper process should be spawned at the top of on_start, before
from_bundle(), so the fork happens in a clean process state.
Window chrome is set on the webview before run():
let view: ui::webview::WebView = application.webview();
view.set_decorations(false);
view.set_transparent(true);
view.set_custom_controls(true);