name: pake-native-app
description: Package any web URL into a lightweight native desktop app (~4MB) using Pake (Rust/Tauri). Use when user wants to turn a website into a desktop app, create a native wrapper, convert web to native, make a desktop client for a SaaS. Trigger: "native app", "desktop app", "wrap website", "Pake", "web to app", "Electron alternative". NOT for: full Tauri framework projects, mobile apps, or offline-first apps needing custom Rust backends.
metadata:
tags: pake, tauri, native-app, desktop, packaging, electron-alternative
source: https://github.com/tw93/Pake
verified: 2026-03-25
Pake -- Web URL to Native Desktop App
Turn any website into a ~4MB native desktop app with one command.
Built on Rust + Tauri v2. 30x smaller than Electron.
Prerequisites
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
npm install -g pake-cli
pake --version
rustc --version
Quick Start
pake https://example.com --name "MyApp"
CLI Options (v3.10.1 verified)
pake <url> [options]
--name <string> App name (default: inferred from domain)
--icon <string> App icon path or URL (auto-converts format)
--width <number> Window width in pixels (default: 1200)
--height <number> Window height in pixels (default: 780)
--hide-title-bar Hide native title bar (macOS frameless look)
--fullscreen Launch in fullscreen mode
--use-local-file Package a local HTML file instead of URL
--multi-arch Build universal binary on macOS (arm64 + x86_64)
--inject <files> Inject local CSS/JS files into the page
--targets <string> Build target format (see Targets section)
--debug Debug build with verbose output
--install Auto-install to /Applications after build (macOS)
Options that do NOT exist as CLI flags (internal config only):
--safe-domain, --transparent, --user-agent, --show-system-tray,
--system-tray-icon, --disabled-web-shortcuts, --always-on-top, --dark-mode.
These are configurable only by editing src-tauri/.pake/tauri.conf.json after
the first pake run creates the build scaffold.
Build Targets
| Platform | Default | Valid values |
|---|
| macOS | dmg | dmg, app |
| Linux | deb,appimage | deb, appimage, rpm, deb-arm64, appimage-arm64, rpm-arm64 |
| Windows | msi | msi |
pake https://example.com --name "MyApp" --targets app --install
pake https://example.com --name "MyApp" --multi-arch
Recipes
ChatGPT Desktop
pake https://chat.openai.com --name "ChatGPT" --hide-title-bar
Claude Desktop
pake https://claude.ai --name "Claude" --hide-title-bar --width 1100 --height 750
Custom CSS Injection
echo 'body { font-family: "PingFang SC", sans-serif !important; }' > /tmp/inject.css
pake https://example.com --name "StyledApp" --inject /tmp/inject.css
Local HTML File
pake /path/to/index.html --name "LocalApp" --use-local-file
Gotchas
-
Claude Code cc wrapper breaks Rust builds: Claude Code installs a cc wrapper at ~/.local/bin/cc that intercepts the Rust linker. Build will fail with error: unknown option '-lSystem'. Fix: strip Claude Code from PATH before building:
export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v '.local/bin' | tr '\n' ':')
unset CLAUDECODE
pake https://example.com --name "MyApp"
Or run pake in a separate terminal without Claude Code active.
-
Must use npm, not pnpm for global install: Pake's package.json declares packageManager: "pnpm@10.26.2". When you run pake, it invokes pnpm internally to install build dependencies. If pake-cli itself was installed via npm, pnpm will move all npm-installed packages to node_modules/.ignored and reinstall them -- this corrupts the installation. Workaround: Install with npm install -g pake-cli and accept the pnpm reinstall on first run (adds ~15s). After first successful build, subsequent runs reuse pnpm cache.
-
First build takes ~2 minutes: Rust compiles ~230 crates from source on first run (tested: 1m38s on M-series Mac). Cache is reused for subsequent builds (~30s). Do not kill the process during compilation.
-
No URL validation: Pake does NOT validate the URL before starting the build process. An invalid URL like not-a-url will trigger the full dependency installation, download a default icon, then fail deep in the Tauri build. Always verify your URL is valid and accessible before running pake.
-
macOS WebKit, not Chrome: Pake uses WKWebView (Safari engine), not Chromium. Sites relying on Chrome-only APIs (WebUSB, WebNFC, some WebGL extensions) will break. Test your target URL in Safari first.
-
Windows needs WebView2 Runtime: Most Win10/11 machines have it pre-installed. Win7/8 users must install manually from Microsoft.
-
Login state is persistent: Cookies and localStorage persist in the app sandbox (~/Library/WebKit/ on macOS). User logs in once, stays logged in across restarts.
-
No offline capability: The app loads the URL live every time. No service worker or cache-first behavior unless the website itself implements it.
-
Notarization for macOS distribution: Without Apple Developer ID + notarization, users get "unidentified developer" warning. For personal use: right-click > Open bypasses this. Build log will show Warn skipping app notarization -- this is expected.
-
China network issues: Pake auto-detects China locale and switches to npmmirror.com registry, but some packages may timeout. If build fails with ECONNRESET, retry or use a proxy.
Decision Tree
Just wrap a URL as desktop app?
-> Pake (this skill, 1 command, ~4MB output)
Need custom backend logic (DB, file I/O, system calls)?
-> Tauri v2 (npm create tauri-app@latest)
Need mobile (iOS/Android)?
-> Tauri v2 (has mobile support in v2)
Already have working Electron app?
-> Keep Electron unless bundle size / memory is critical
-> Full migration to Tauri takes 2-4 weeks
Comparison (verified)
| Metric | Pake | Electron | Tauri v2 |
|---|
| Bundle size | ~4 MB | ~150 MB | ~10-50 MB |
| Memory (idle) | ~20 MB | ~120 MB | ~35 MB |
| Startup | <500ms | 1-2s | <500ms |
| Backend | None (URL only) | Node.js | Rust |
| Mobile | No | No | Yes |
| Effort | 1 command | Full app | Full app |
| First build | ~2 min | ~1 min | ~3-5 min |
Source