|
| 1 | +--- |
| 2 | +description: 'Pick a rendering backend for a Deserve desktop app, build platform bundles like app, dmg, msi, and AppImage, cross-compile to other targets from one host, and code-sign the macOS bundle.' |
| 3 | +--- |
| 4 | + |
| 5 | +# Backends and Distribution |
| 6 | + |
| 7 | +> **Reference**: [Deno Desktop Backends](https://docs.deno.com/runtime/desktop/backends/) |
| 8 | +
|
| 9 | +The final step turns the project into shippable bundles. A backend choice decides how the page renders and whether DevTools is available, the output extension decides the package format, and one host can cross-compile for every target. The Deserve server stays the same across all of it, since distribution is a packaging concern. |
| 10 | + |
| 11 | +## Choosing a Backend |
| 12 | + |
| 13 | +The `backend` field, or the `--backend` flag, selects the rendering engine baked into the bundle. Three options exist, and only two suit a Deserve app: |
| 14 | + |
| 15 | +| Backend | Rendering | Size | DevTools | Fits Deserve | |
| 16 | +| --------- | ---------------------------------- | --------------- | -------- | ------------ | |
| 17 | +| `webview` | The OS webview, default | Small | No | Yes | |
| 18 | +| `cef` | Bundled Chromium | Large, ~150 MB | Yes | Yes | |
| 19 | +| `raw` | No web engine | Smallest | No | No | |
| 20 | + |
| 21 | +The `webview` backend uses the OS engine, WKWebView on macOS, WebView2 on Windows, WebKitGTK on Linux. It keeps the bundle small and renders the Deserve page well, at the cost of per-platform rendering differences. |
| 22 | + |
| 23 | +The `cef` backend bundles Chromium for identical rendering everywhere and full DevTools, in exchange for a much larger download. The framework binary downloads once and caches. |
| 24 | + |
| 25 | +The `raw` backend has no webview at all, so a Deserve UI served over HTTP has nothing to render it. A build succeeds and the server still runs, but no page appears. Reserve `raw` for apps that draw their own surface, not for a web UI. |
| 26 | + |
| 27 | +```json |
| 28 | +{ |
| 29 | + "desktop": { |
| 30 | + "backend": "webview" |
| 31 | + } |
| 32 | +} |
| 33 | +``` |
| 34 | + |
| 35 | +The `--backend` flag overrides the field for one build and accepts only `cef` and `webview`. Selecting `raw` happens through the field. Switching between `cef` and `webview` needs no code change, since the same window, menu, and event APIs work on both. |
| 36 | + |
| 37 | +## DevTools |
| 38 | + |
| 39 | +DevTools attaches to the page for inspecting elements, the console, and the network panel. It is available on the `cef` backend only. The default `webview` backend speaks a different inspector protocol that the unified DevTools does not target yet, so [`win.openDevtools()`](https://docs.deno.com/api/deno/~/Deno.BrowserWindow.openDevtools) is a no-op there. |
| 40 | + |
| 41 | +A build that needs DevTools switches to `cef` for development, then ships on whichever backend suits the release: |
| 42 | + |
| 43 | +```bash |
| 44 | +# Run with Chromium for DevTools |
| 45 | +deno desktop --backend cef --include routes --include views main.ts |
| 46 | +``` |
| 47 | + |
| 48 | +The Deno side runs an inspector under `--inspect` regardless of backend, so server-side debugging stays available even on `webview`. The full inspector flow is in the [DevTools reference](https://docs.deno.com/runtime/desktop/devtools/). |
| 49 | + |
| 50 | +## Output Formats |
| 51 | + |
| 52 | +The output extension decides the package the build produces. The `output` block sets a path per platform, and the [`--output`](https://docs.deno.com/runtime/desktop/distribution/) flag overrides it for one build: |
| 53 | + |
| 54 | +```json |
| 55 | +{ |
| 56 | + "desktop": { |
| 57 | + "output": { |
| 58 | + "macos": "./dist/DeserveDesktop.app", |
| 59 | + "windows": "./dist/DeserveDesktop", |
| 60 | + "linux": "./dist/deserve-desktop" |
| 61 | + } |
| 62 | + } |
| 63 | +} |
| 64 | +``` |
| 65 | + |
| 66 | +Each platform accepts several extensions: |
| 67 | + |
| 68 | +| Platform | Extension | Produces | |
| 69 | +| -------- | ------------- | ------------------------------ | |
| 70 | +| macOS | `.app` | Application bundle, the default | |
| 71 | +| macOS | `.dmg` | Drag-to-Applications disk image | |
| 72 | +| Windows | directory | App folder with a launcher | |
| 73 | +| Windows | `.msi` | Windows Installer package | |
| 74 | +| Linux | directory | App folder with a launcher | |
| 75 | +| Linux | `.AppImage` | Single-file portable bundle | |
| 76 | +| Linux | `.deb` | Debian or Ubuntu package | |
| 77 | +| Linux | `.rpm` | Fedora or RHEL package | |
| 78 | + |
| 79 | +A `.dmg` shells out to `hdiutil`, so it has to build on a macOS host. The rest assemble in pure Rust and build from any host: |
| 80 | + |
| 81 | +```bash |
| 82 | +# Build a drag-to-Applications disk image |
| 83 | +deno desktop --include routes --include views --output ./dist/DeserveDesktop.dmg main.ts |
| 84 | +``` |
| 85 | + |
| 86 | +## Cross-Compilation |
| 87 | + |
| 88 | +One host builds for every supported target. `--target` names a single triple, and `--all-targets` covers them all. The CLI downloads the matching runtime and backend archive for the target, with no platform toolchain on the host: |
| 89 | + |
| 90 | +```bash |
| 91 | +# Build for macOS Intel from any host |
| 92 | +deno desktop --target x86_64-apple-darwin --include routes --include views main.ts |
| 93 | +``` |
| 94 | + |
| 95 | +The supported triples are `aarch64-apple-darwin`, `x86_64-apple-darwin`, `x86_64-pc-windows-msvc`, `aarch64-unknown-linux-gnu`, and `x86_64-unknown-linux-gnu`. The lone exception to host-free cross-building is the macOS `.dmg`, which needs `hdiutil` and therefore a macOS host. The full matrix and a CI example are in the [distribution reference](https://docs.deno.com/runtime/desktop/distribution/). |
| 96 | + |
| 97 | +## Compressing the Bundle |
| 98 | + |
| 99 | +`--compress` ships a self-extracting bundle. The heavy runtime payload is compressed in the distributed app and unpacked to a per-user folder on first launch, which shrinks the download in exchange for a one-time decompression: |
| 100 | + |
| 101 | +```bash |
| 102 | +# Smaller download, unpacks on first launch |
| 103 | +deno desktop --compress --include routes --include views main.ts |
| 104 | +``` |
| 105 | + |
| 106 | +The codec defaults to a smaller-artifact setting and can be chosen with `--compress=xz` or `--compress=zstd`, where `zstd` trades some size for a faster first launch. |
| 107 | + |
| 108 | +## Code Signing |
| 109 | + |
| 110 | +On macOS, `deno desktop` signs the bundle on its own. The default is an ad-hoc signature, written as `-`, which gives the app a stable code identity, enough for the OS to grant [notification permission](/recipes/desktop/notifications-updates#conditions-on-macos), but not enough to distribute without Gatekeeper warnings: |
| 111 | + |
| 112 | +```json |
| 113 | +{ |
| 114 | + "desktop": { |
| 115 | + "macos": { |
| 116 | + "codesignIdentity": "-" |
| 117 | + } |
| 118 | + } |
| 119 | +} |
| 120 | +``` |
| 121 | + |
| 122 | +A real Developer ID identity replaces the `-` and produces a notarizable bundle signed with Hardened Runtime. Notarization stays a separate step run with `xcrun notarytool`. Signing runs on a macOS host, since it shells out to `codesign`. The signing and notarization detail is in the [distribution reference](https://docs.deno.com/runtime/desktop/distribution/#code-signing). |
| 123 | + |
| 124 | +## Back to the Map |
| 125 | + |
| 126 | +That closes the loop from a first build to a shipped bundle. The [overview](/recipes/desktop/overview#feature-compatibility) holds the compatibility map for the whole surface, and a production Deserve server outside the desktop context is covered in [Production Deploy](/recipes/production-deploy). |
0 commit comments