# Pake: Package Any Website as a Desktop App with Tauri and Rust


[Pake](https://github.com/tw93/Pake) is a **command-line tool that takes a URL and produces a standalone desktop application** for macOS, Windows, and Linux. It uses the [Tauri](https://tauri.app/) framework, which interfaces with the OS's built-in web renderer (WebKit on macOS, WebView2 on Windows, WebKitGTK on Linux) rather than bundling a full browser engine. The resulting applications are typically 5–10MB compared to 100–300MB for Electron-based apps.

<iframe width="100%" height="315" src="https://www.youtube.com/embed/6bu8zc6lsHQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


## How it differs from Electron

Electron bundles a complete copy of Chromium and Node.js into every application. This produces a consistent rendering environment but at the cost of large binaries and high memory usage.

Tauri delegates rendering to the webview that already exists on the user's system. The application logic is written in Rust, which is small, fast, and memory-efficient. Pake wraps this architecture behind a simple CLI so no Rust or Tauri knowledge is required.

## Installation

Pake requires Node.js 18+ and pnpm (or npm).

```command
pnpm install -g pake-cli
```

```command
pake --help
```

![Terminal output of pake --help listing all available arguments and options](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/05ea5191-7aa0-4ec9-c4c7-ace78ca84e00/md2x =1920x1080)

If the Rust toolchain is not already installed, the build process will prompt for it and handle installation automatically.

## Building an app

The only required arguments are the URL and a name:

```command
pake https://music.youtube.com/ --name "Youtube Music"
```

![Terminal showing the exact command used to build the YouTube Music application](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/cebd8479-3a86-4263-981d-ec1ae4ab5700/md2x =1920x1080)

The build process:

1. Downloads the site's favicon for use as the default app icon
2. Installs Tauri dependencies via pnpm
3. Compiles the Rust backend with `cargo` (slow on first run, fast on subsequent runs due to caching)
4. Bundles the output as a platform-specific installer (`.dmg` on macOS, `.msi` on Windows, `.AppImage` or `.deb` on Linux)

The first build takes 5–10 minutes depending on hardware and connection speed.

![Terminal output after a successful build showing "Build success!" and the path to the installer file](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/4df276ce-4bcc-41f6-7ba5-582fd1467600/lg1x =1920x1080)

## Performance comparison

![File explorer comparing the size of an Electron app (Slack at 310.8 MB) with a Pake-generated app](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/00c58ef4-d816-4c70-e09b-16a063c9f700/orig =1920x1080)

An Electron app (Slack) installs at 310.8MB. A comparable Pake app installs at 55.6MB. RAM usage during operation: a Pake app uses around 61MB; a browser running a few tabs uses 386MB or more. The difference is the absence of a bundled browser engine.

## CLI flags

### `--debug`

Enables developer tools in the packaged app. Right-click → Inspect Element opens a familiar devtools panel.

```command
pake <URL> --name <AppName> --debug
```

### `--hide-title-bar`

Removes the OS window frame for a frameless, modern UI. Most effective on macOS. If the site's content overlaps the removed title bar area, use `--inject` to push content down with CSS.

```command
pake <URL> --name <AppName> --hide-title-bar
```

### `--inject`

Injects local CSS and/or JavaScript files into the page on every load. Useful for fixing layout issues caused by `--hide-title-bar`, applying custom themes, or modifying site behavior.

Create a CSS file:

```css
[label custom-style.css]
body {
  padding-top: 2.5rem !important;
}
```

Pass it to the build:

```command
pake <URL> --name <AppName> --hide-title-bar --inject ./custom-style.css
```

### `--show-system-tray`

Adds a system tray icon (macOS menu bar or Windows taskbar). The tray menu provides Show, Hide, and Quit options. Useful for music players, chat clients, or any app intended to run in the background.

```command
pake <URL> --name <AppName> --show-system-tray
```

![macOS menu bar showing the application's system tray icon and context menu with Show and Quit options](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/c4c80b43-52db-4674-113d-3f243bbe5c00/orig =1920x1080)

### `--use-local-file`

By default, Pake connects to a live URL at runtime. If the server is not running, the app shows a blank screen. For static local projects (HTML/CSS/JS), `--use-local-file` copies the entire project directory into the app bundle, making it self-contained and offline-capable.

```command
pake ./my-app/index.html --name "My App" --use-local-file
```

## Limitations

**Build dependency fragility.** Pake depends on Node.js tooling for its build process. Version mismatches between the system's pnpm version and the one specified in Pake's internal `package.json` can cause build failures that require manually editing Pake's configuration files. A self-contained pre-compiled binary distribution would eliminate this class of issue.

**Live URL dependency.** Without `--use-local-file`, the app requires the URL to be reachable. Packaging a local development server URL produces an app that shows a blank screen when the server is not running.

**No backend logic.** Pake is a webview wrapper with no backend runtime. For applications that need server-side logic, file system access, or a local database, alternatives are more appropriate. [Electrobun](https://electrobun.dev/) bundles the Bun runtime as a backend; [Zero-Native](https://zero-native.dev/) provides a Zig shell for deep system integration.

## Final thoughts

Pake is the right tool when the goal is giving an existing web app a standalone desktop presence with minimal effort. **The single-command workflow, system tray support, and CSS/JS injection cover most personal and simple distribution** use cases without requiring any knowledge of Rust, Tauri, or native app development.

For more complex requirements, such as persistent local storage, background processing, or native system API access, a more capable framework is needed. But for its stated purpose, Pake produces remarkably small and efficient results.

Source code and documentation are at [github.com/tw93/Pake](https://github.com/tw93/Pake).