Turn your web apps into native desktop applications
Features • Quick Start • Frameworks • Bridge API • Examples • Contributing
English | Turkce
Pulpy is a lightweight, cross-platform desktop application packager for web apps. It wraps your web application (React, Vue, Angular, or vanilla HTML/CSS/JS) in a native WebView window and provides a JavaScript bridge for accessing OS-level features like file system, clipboard, notifications, and more.
Pulpy supports two packaging modes:
- Static Mode — for SPAs built with Vite, Webpack, etc.
- Server Mode (SSR) — for server-rendered apps like Next.js SSR and Nuxt SSR, with an embedded Node.js runtime.
Beta Notice: Pulpy is currently in beta (v0.1.0). macOS is fully supported. Windows and Linux support is planned.
- Interactive Wizard — Step-by-step CLI wizard that guides you through packaging
- Auto-Detection — Automatically detects your framework, bundler, app name, version, and icon
- Static & SSR Support — Package both static SPAs and server-rendered apps
- Native Bridge API — Access file system, clipboard, notifications, window controls, and dialogs from JavaScript
- Environment Variables —
.envfile support with build-time injection (static) and runtime loading (SSR) - DevKit — Built-in development console for debugging (Cmd+Shift+L)
- CORS Proxy — Built-in cross-origin request handling
- DMG Installer — Generates ready-to-distribute
.appbundles and.dmginstallers on macOS - Build History — Tracks all your builds in
~/.pulpy/builds/
- macOS 12+ (for now)
- Xcode Command Line Tools
- CMake 3.16+
git clone https://github.com/enesgkky/Pulpy.git
cd Pulpy
mkdir -p build && cd build
cmake ..
makeThe pulpy binary will be in the build/ directory.
# Interactive wizard
./build/pulpy pack
# Or with flags
./build/pulpy pack \
--input ./my-app/dist \
--framework react \
--bundler vite \
--platform macos./build/pulpy dev --input ./my-app/distpulpy Open Pulpy desktop UI
pulpy pack Interactive packaging wizard
pulpy pack [flags] Package with explicit configuration
pulpy dev --input <path> Preview app in dev mode
pulpy history View build history
pulpy --version Show version
pulpy --help Show help
| Flag | Description |
|---|---|
--input, -i <path> |
Build output directory |
--framework <name> |
react, vue, angular, vanilla |
--bundler <name> |
vite, next-static, next-ssr, nuxt-static, nuxt-ssr, angular-cli, angular-universal, tanstack-start, webpack, none |
--platform <name> |
macos, windows, linux (comma-separated) |
--output, -o <path> |
Output directory |
--icon <path> |
Path to app icon (PNG) |
--fullscreen |
Open app in fullscreen mode |
--devkit |
Enable Development Kit (Log Console) |
| Framework | Bundlers |
|---|---|
| React | Vite, Next.js (Static/SSR), Webpack |
| Vue | Vite, Nuxt (Static/SSR), Webpack |
| Angular | Angular CLI, Angular Universal |
| Vanilla | Vite, Webpack, None |
Pulpy injects a global pulpy object into your web app's JavaScript context, giving you access to native OS features.
await pulpy.fs.readFile("/path/to/file")
await pulpy.fs.writeFile("/path/to/file", "content")
await pulpy.fs.exists("/path/to/file")
await pulpy.fs.readDir("/path/to/directory")await pulpy.window.setTitle("My App")
await pulpy.window.setSize(1024, 768)
await pulpy.window.minimize()
await pulpy.window.toggleFullscreen()await pulpy.clipboard.read()
await pulpy.clipboard.write("Hello from Pulpy!")await pulpy.notification.send("Title", "Body text")await pulpy.system.platform() // "macos", "windows", "linux"
await pulpy.system.version() // Pulpy version stringawait pulpy.dialog.openFolder()
await pulpy.dialog.openFile()Check the examples/ directory for sample applications.
A simple demo showcasing the Bridge API:
./build/pulpy dev --input ./examples/hello-worldPulpy/
├── CMakeLists.txt # Build configuration
├── include/pulpy/ # Public headers
│ ├── app.h
│ ├── bridge.h
│ ├── config.h
│ ├── packager.h
│ ├── version.h.in
│ └── window.h
├── src/
│ ├── cli/ # CLI entry point & wizard
│ ├── core/ # App logic, config, detection
│ ├── bridge/ # JS ↔ Native bridge
│ ├── platform/ # Platform-specific implementations
│ │ ├── macos/ # macOS (Cocoa + WebKit)
│ │ ├── windows/ # Windows (WebView2) — planned
│ │ └── linux/ # Linux (GTK3 + WebKit2) — planned
│ └── runtime/ # Embedded runtime binary
├── assets/ # Default app icons
└── examples/ # Example applications
| Platform | Window | Bridge | Packaging | Status |
|---|---|---|---|---|
| macOS | Full | Full | .app, .dmg | Ready |
| Windows | Stub | — | — | Planned |
| Linux | Stub | — | — | Planned |
mkdir -p build && cd build
cmake ..
makeRequires WebView2 SDK via NuGet or vcpkg.
Requires GTK3 and WebKit2GTK-4.0:
sudo apt install libgtk-3-dev libwebkit2gtk-4.0-devThis project includes an llms.txt file — a comprehensive reference designed for LLM-based coding assistants (Claude, Copilot, Cursor, etc.). It contains the full architecture map, class relationships, bridge module specs, file descriptions, design patterns, and important caveats needed to work effectively on this codebase.
If you're using an AI assistant to contribute, point it to llms.txt for context.
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Windows platform implementation (WebView2)
- Linux platform implementation (GTK3 + WebKit2)
- Additional framework/bundler support
- Tests and documentation
This project is licensed under the Apache License 2.0 — see the LICENSE file for details.
Copyright 2026 Enes Gökkaya and Pulpy Contributors
