Pake tutorial: package any website as a desktop app

A practical guide to tw93/Pake: installation, command-line packaging, custom icons and window size, local development, and build commands for wrapping frequently used websites as lightweight desktop apps.

Pake uses Tauri to wrap remote pages, local HTML files, or static site directories as desktop applications for macOS, Windows, and Linux. The real challenge is not remembering a single pake URL command. It is confirming that Node, Rust, and platform build dependencies are ready, then verifying that login, redirects, downloads, and device access still work inside the system WebView.

Project Address:

https://github.com/tw93/Pake

Quick Conclusion

  • Recommended to use Node.js 22, minimum requirement 18; CLI builds also require Rust 1.85+.
  • The first build will download and compile dependencies, which are noticeably slower than subsequent builds. Don’t mistakenly judge the wait as freezing.
  • Automation or Agent calls should be included--json, do not rely on matching natural language logs to judge success.
  • Pake cannot bypass website restrictions on embedded WebViews, third-party cookies, SSO, or browser extensions.

Check the environment and install the Pake CLI

First, check the version:

1
2
3
4
node --version
npm --version
rustc --version
cargo --version

When Node is below 18 or Rust is below 1.85, upgrade your environment first. Recommended installation command:

README provides the command:

1
pnpm install -g pake-cli

You can also use npm directly:

1
npm install -g pake-cli

After installation, you must verify that the current terminal found the intended version:

1
2
pake --version
pake --help

If you encounter permission issues during global installation, you can use it firstnpx pake-cli [url] [options], do not directly use administrator privileges to overwrite the system Node directory.

First time packaging using a public simple page

Package GitHub as a desktop application:

1
pake https://github.com --name "GitHub"

Pake writes the artifact to the current directory by default. The first run may install Rust or platform components. After the command ends, check the exit code and the actual package instead of relying on a success log line.

Automated environments recommend using structured output:

1
pake https://github.com --name "GitHub" --json

The standard output should be a parsable JSON. Non-zero exits, JSON parsing failures, or no product path in the JSON should all be considered build failures.

Custom icons, windows, and target platforms

The README provides a more complete example:

1
pake https://weekly.tw93.fun --name Weekly --icon https://cdn.tw93.fun/pake/weekly.icns --width 1200 --height 800 --hide-title-bar

Pay attention to platform differences:

  1. --hide-title-barOnly available on macOS.
  2. On Windows/Linux, use --hide-window-decorations to hide native window decorations.
  3. --targetsUsed to select DMG, AppImage, DEB, RPM, or target architecture, with specific available values depending on the current system.
  4. The icon can be a local or remote file; Pake will convert it to platform format; If the download fails, use the local file instead to eliminate network issues.

For example, on macOS generate an .app that is easy to test:

1
PAKE_CREATE_APP=1 pake https://example.com --name "Example"

Linux Package AppImage:

1
pake https://example.com --name "Example" --targets appimage

Do not assume that all platform installation packages can be generated on one system without configuration. Cross-architecture builds also require corresponding Rust targets and system toolchains.

Package Local Static Sites

Pake can directly receive inclusionsindex.htmlBuild directory:

1
2
npm run build
pake ./dist --name "MyTool" --json

A directory input packages the full file tree. For a single HTML file that also needs adjacent resources, use --use-local-file:

1
pake ./my-app/index.html --name "MyApp" --use-local-file

Hash routing for local SPAs can work directly; History mode routing is not equivalent to ordinary web servers; deep path refreshing must be tested in practice.

Use a configuration file for reproducible builds

When there are many parameters, using JSON configuration makes auditing easier than repeatedly copying long commands:

1
pake --config app.json --json

Handleapp.jsonInclude version control, but do not write website login cookies, tokens, or internal temporary addresses. Build records should at least retain Pake version, Node version, Rust version, target platform, and product checksum.

Validate desktop applications, not just verify installation packages

After installing or opening the build product, check item by item according to the actual website usage:

  1. The main screen loads properly, and certificates and proxies do not report errors.
  2. After logging in, restart the app and confirm whether the session is retained as expected.
  3. Whether the external link is opened within the application or in the system browser complies with the security boundary.
  4. Whether file upload, download, clipboard, and drag-and-drop work properly.
  5. Shortcuts, window scaling, and system tray do not conflict with the webpage itself.

If it’s a video conferencing site, macOS also requires explicit declaration of permissions:

1
pake https://meet.example.com --name "Meet" --camera --microphone

These parameters do not guarantee that the website will always allow WebView login or device access; they only add appropriate permission declarations for the application.

How to check login, SSO, and redirect failures

Rebuild using debug mode first:

1
pake https://app.example.com --name "ExampleDebug" --debug

Open the developer tools to view Console and Network. Common boundaries include:

  • Identity providers reject embedded WebView.
  • Third-party cookies or cross-origin storage are restricted.
  • OAuth callbacks jump to another domain name, which is given to the system browser by default.
  • Websites rely on browser extensions or multiple tabs.

When trusted SSO domains must remain inside the app, evaluate --safe-domain:

1
pake https://app.example.com --name "Example" --safe-domain app.example.com,login.example.com

Do not use overly broad domain name rules to force all links to remain within the app. When SSO services explicitly reject WebView, further expanding navigation range cannot fix the issue.

Diagnose build failures in order

Stage Typical Phenomenon Handling Method
CLI not found pake: command not found Check whether the npm/pnpm global bin has entered the PATH, or use itnpx pake-cli
Rust Initialization Failure Not foundrustcDownload timeout Install Rust separately, reopen the terminal to verify the version
Platform dependency missing Tauri bundler, WebKitGTK, or packer error Dependencies required for installing the current system; do not repeatedly reinstall pake-cli
Icon processing failure Download failure, format conversion failure Switch to local PNG/ICO/ICNS, then verify the network separately
Website white screen Successfully built but no content at runtime Usage--debugCheck compatibility with CSP, certificates, JS, and WebView
Login loop After successful login, return to the entry Check cookies, callback domain names, and identity provider WebView policies

Return to a minimal working build

When troubleshooting, first keep the failed command and version output, then return to the simplest public URL:

1
2
3
4
pake --version
node --version
rustc --version
pake https://example.com --name "PakeSmokeTest" --json

If the minimum sample succeeds, it means the toolchain is basically normal, and the problem is more likely to be with the target website, icon, or extra parameters. Then add only one option at a time. If the minimum sample also fails, handle Node, Rust, or platform dependencies.

If regression occurs after upgrading the CLI, do not overwrite the old product. Record the current version and rebuild the same smoke test in the isolation directory; Only when differences between new and old versions can be repeated are CLI regressions judged.

Local Development

If you want to modify Pake itself:

1
pnpm i

Local Development:

1
pnpm run dev

Building applications:

1
pnpm run build

Developing Pake itself is not the same path as using the CLI. The official current recommendation is Node.js 22 and requires Rust 1.85+. Regular users who only want to encapsulate web pages do not need to clone the repository to execute these three commands.

Pre-release Acceptance

Before posting to others, the following checks should be completed on a clean account or test machine:

  1. --jsonReturns successfully, and the product path truly exists.
  2. Installation, startup, exit, and uninstallation all work normally.
  3. Login, callbacks, upload/download, and backlink behavior meet expectations.
  4. Internal tokens, cookies, or debugging entry points have not been introduced into the application.
  5. Record Pake, Node, Rust versions, and target architectures.
  6. Keep the previous workable installation package so that it can be restored when a new website or CLI reverts.

Pake is great for document stations, monitoring panels, and fixed web tools, but it’s not the same as a full browser. Use it first--debugand minimal smoke test to prove the target website is suitable for WebView, then customize icons, trays, windows, and permissions to avoid the false completion of “installation package generated successfully, but application unusable.”