| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
A webview CLI. It opens a native window, renders the HTML you give it, gives the page one channel to send a result back, prints that result, and exits. That's the whole tool.
Any caller — a shell, an agent, Python, Node — integrates the same way: spawn the process, write HTML, read the result off stdout.
The page does JSON.stringify; the binary prints that string verbatim. The Rust side never parses or validates the result — its shape is entirely the caller's concern.
Install script (macOS / Linux) — grabs the right prebuilt binary for your platform from the latest GitHub release:
curl -fsSL https://raw.githubusercontent.com/just-be-dev/webview-cli/main/install.sh | shPrebuilt binaries — download from the Releases page. Each release ships webview-<platform> for macos-arm64, linux-x64, linux-arm64, and windows-x64, alongside SHA256SUMS.
Cargo — if you have a Rust toolchain:
cargo install webview-cli # installs the `webview` binaryFrom source:
mise run build # -> target/release/webview
# or
cargo build --releaseOn Linux you need the WebKitGTK headers to build (or to run the binary): libwebkit2gtk-4.1-dev libgtk-3-dev.
echo '<html>…</html>' | webview # HTML piped on stdin
webview ./page.html # or a file path
webview https://example.com # or an http(s) URL
webview ./page.html --title T --width 900 --height 700 --devtools --icon ./icon.png --timeout-ms 60000Input precedence: non-empty piped stdin wins; otherwise the positional argument (an http:///https:// URL is loaded remotely, anything else is treated as a file); otherwise it's a usage error. File pages are served over a custom origin so relative CSS/JS/images and fetch resolve (and so they load at all under WKWebView).
| Flag | Default | Meaning |
|---|---|---|
| --title | webview | Window title. |
| --width | 800 | Window width (logical px). |
| --height | 600 | Window height (logical px). |
| --devtools | off | Open dev tools on launch. |
| --icon | none | Image to show as the Dock icon (macOS only). |
| --timeout-ms | none | Exit 3 if the page hasn't settled in time. |
Everything else lives in the HTML — there are no other flags by design.
The page talks back through one injected object:
window.webview.version; // the webview-cli version string, e.g. "0.2.0"
window.webview.resolve(value); // any JSON-serializable value
window.webview.reject(error); // string or ErrorThe first resolve/reject wins; the process exits immediately after.
A page — especially one loaded from a URL — can tell it's running inside webview two ways:
| Outcome | stdout | stderr | exit |
|---|---|---|---|
| page called resolve(v) | JSON.stringify(v) | — | 0 |
| page called reject(e) | — | message | 1 |
| user closed window first | (empty) | — | 2 |
| --timeout-ms elapsed | (empty) | — | 3 |
| bad usage (no input, etc.) | (empty) | usage | 64 |
A tiny confirmation prompt that returns true/false:
cat <<'HTML' | webview --title "Confirm" --width 360 --height 160
<!doctype html>
<body style="font:14px system-ui;display:grid;place-content:center;gap:12px">
<p>Delete everything?</p>
<div>
<button onclick="webview.resolve(true)">Yes</button>
<button onclick="webview.resolve(false)">No</button>
</div>
</body>
HTML
# prints `true` or `false`; exit 0No SDK: spawn the binary, write HTML to stdin, read stdout.
Shell
result=$(echo "$html" | webview --timeout-ms 60000)Python
import subprocess
out = subprocess.run(["webview", "--timeout-ms", "60000"],
input=html, capture_output=True, text=True)
result = out.stdout # JSON string; parse if you wantNode
import { spawnSync } from "node:child_process";
const out = spawnSync("webview", ["--timeout-ms", "60000"], { input: html });
const result = out.stdout.toString(); // JSON stringwebview does "show something, get one answer back" — it isn't a live, two-way session. When you need multiple steps, put them all in one page (a wizard, several screens in one document) and only call resolve at the very end. Keep the interaction in the HTML.
mise run test # cargo test (window-launch tests skip without a display)
mise run lint # cargo clippy -D warnings
mise run format # cargo fmt
mise run typecheck # cargo check --all-targets
mise run check # all of the aboveSource layout:
| File | Concern |
|---|---|
| main.rs | orchestration: parse args, resolve input, run |
| cli.rs | clap arg struct + usage |
| input.rs | stdin / URL / path resolution → a Load enum |
| bridge.rs | the BRIDGE JS + AppEvent + message parsing |
| assets.rs | custom-protocol file server (MIME, path-traversal safety) |
| icon.rs | runtime Dock-icon swap for --icon (macOS; no-op else) |
| run.rs | window + webview build, event loop, exit codes |
Pushing a v* tag (e.g. v0.1.0) triggers the release workflow, which builds all four platform binaries, attaches them plus SHA256SUMS to a GitHub Release, and publishes the crate to crates.io. See .github/workflows/release.yml.
MIT © Justin Bennett
| Back | FazBrowse Home | New Git URL |