pottz
v0.1.4
Published
Ship your SvelteKit app as a native desktop app
Maintainers
Readme
Pottz
Your full-stack SvelteKit app, compiled to a native desktop app
What it is
Pottz takes a SvelteKit app built with adapter-node and compiles it into a standalone native desktop app. The binary includes the Bun runtime, your server, and all client assets.
All SvelteKit features that depend on a server work as expected.
Good for
- Shipping an existing SvelteKit web app as a desktop binary
- Local-first tools that read and write files or call local services
- Internal business tools that don't need to go through an app store
- Devs who know SvelteKit and want a desktop app without learning a new stack
What it isn't
A general-purpose desktop framework. Pottz doesn't expose native OS APIs beyond what Bun already provides. No system tray, no native menus, no native file dialogs. If your app needs those, this probably isn't the right tool for you.
Requirements
To build:
- Bun v1.1.0+
@sveltejs/adapter-nodeconfigured in your SvelteKit project
To run the binary (Linux):
sudo apt install libgtk-4-1 libwebkitgtk-6.0-4 libvulkan1To run the binary (Windows):
- Windows 11 - nothing required, WebView2 ships with the OS
- Windows 10 - WebView2 Runtime required
End users don't need Bun installed
Running the CLI
Pottz can be run with any of the following:
bunx pottz <command>
npx pottz <command>
pnpm dlx pottz <command>
yarn dlx pottz <command>Quick start
# In your existing SvelteKit project
bunx pottz init
# Edit pottz.config.js to set your app name, window size, and build targets
# Dev mode with hot reload
bunx pottz dev
# Build
bunx pottz buildInstallation
Pottz is a CLI tool that runs with Bun, but it is package manager agnostic. It does not require Bun as your package manager.
You can use it in npm, pnpm, yarn, or bun projects.
Recommended usage:
bunx pottz initOr install it as a dev dependency if you prefer:
bun add -d pottzPackage manager support
Pottz does not require your project to use Bun.
It automatically detects your project’s package manager and uses it when:
- installing dependencies (e.g.
webview-bun) - running scripts during development and build
Supported package managers:
- npm
- pnpm
- yarn
- bun
Detection is based on lockfiles (bun.lock, pnpm-lock.yaml, yarn.lock).
This means:
- You can run Pottz in an npm project without changes
- You do not need to migrate to Bun
- Bun is only required to execute the CLI itself
Setup
1. Configure adapter-node
Make sure your svelte.config.js uses adapter-node:
import adapter from '@sveltejs/adapter-node';
export default {
kit: {
adapter: adapter(),
},
};2. Run init
bunx pottz initThis will:
- Patch your
svelte.config.jswith the required CSRF config - Create
pottz.config.js - Install
webview-bun - Update
.gitignore
3. Edit pottz.config.js
/** @type {import('pottz').PottzConfig} */
export default {
window: {
title: 'My App',
width: 1200,
height: 800,
minWidth: 800,
minHeight: 600,
},
build: {
targets: ['linux-x64', 'windows-x64'],
outDir: 'dist',
appName: 'my-app',
windows: {
// Path to your .ico file - only applied when building on Windows
//icon: './src/lib/assets/your-icon.ico',
title: 'My App',
publisher: 'Your Name',
version: '1.0.0',
description: 'My SvelteKit desktop app',
copyright: 'Copyright 2026',
},
},
adapter: {
// Must match the 'out' option in your adapter-node config
// Only change this if you've customised adapter-node's out option
out: 'build',
// Must match the 'envPrefix' option in your adapter-node config
envPrefix: '',
},
};4. Build
bunx pottz buildBinaries are produced in dist/:
dist/
├── linux-x64/my-app
└── windows-x64/my-app.exeCommands
pottz init
Configures an existing SvelteKit project for desktop builds. Safe to re-run - skips anything already configured
pottz build
Runs a full production build:
vite buildwithNODE_ENV=production- Generates a VFS from client assets
- Generates the desktop entry point with correct server chunk imports
- Compiles a binary for each configured target
- Cleans up generated files
pottz dev
Starts the Vite dev server and opens your app in a native desktop window. Hot reload works automatically - save a file and the window updates
What works
Everything you'd use in a standard SvelteKit web app, including:
- [x] SSR and
+page.server.tsload functions - [x]
+server.tsAPI routes - [x] Form actions
- [x] Server-only modules (
$lib/server/) - [x] Remote functions
- [x] Environment variables via
$env/static/private(andpublic) - [x] Filesystem access via
node:fs - [x] Spawning child processes via
Bun.spawn() - [x] HTTP requests from the server
The server runs locally on a dynamic port bound to 127.0.0.1. The webview loads from it. There's no network exposure.
Binary size
Binaries are ~110MB uncompressed. The majority of this is the Bun runtime
Gotchas
macOS - not supported. You can cross-compile for Linux and Windows from a Mac, but you can't run or test the app locally
adapter-static - not supported. Pottz requires adapter-node
Windows icon - the icon option in pottz.config.js only works when building on Windows natively. Cross-compiling from Linux to Windows will produce a working binary but the icon won't be applied
Linux system libraries - end users on Linux need libgtk-4-1, libwebkitgtk-6.0-4, and libvulkan1 installed. These are standard packages available via apt
Adapter-node options
If you've customised adapter-node in your svelte.config.js, mirror those options in pottz.config.js:
// svelte.config.js
adapter({ out: 'my-build', envPrefix: 'APP_' });// pottz.config.js
adapter: {
out: 'my-build',
envPrefix: 'APP_',
}Example
See examples/basic-sveltekit for a working example demonstrating most of the features listed in What works
License
MIT
