Bringing Omarchy's Web App experience to macOS.
Convert any website into a standalone, distraction-free macOS desktop app in seconds — frameless by default, with retina.icnsicons, Spotlight integration, optional Chrome login import, and Hyprland-style active window borders.
- 🚫 True 0-Topbar & 0-Traffic-Light Mode (Native Engine, Default): A compiled native Cocoa/WebKit runner that creates 100% frameless windows with zero title bars and zero traffic lights, surrounded by a customizable Hyprland-style rounded accent border.
- 🍪 Two Engines, One Real Trade-off: macOS draws the traffic lights inside the browser's own process, so frameless and reuses Chrome's live session cannot both be true. Pick per app:
- Native Engine (
--engine nativeor--engine safari, Default): Completely frameless (0 titlebar, 0 traffic lights), native WebKit (Safari's rendering engine), independent Dock icon and name, its own persistent cookie store. Sites start out logged out — see below. - Chrome Engine (
--engine chrome): Direct Chromium--appmode reusing Google Chrome's live profile and cookies, but keeping the standard macOS title bar. Use it for Widevine DRM, Chrome-bound passkeys, or extension-dependent sites.
- Native Engine (
- 🔑 Login Handling for the Native Engine:
sgwebapp import-cookies <app>seeds an app from your Chrome profile, and SSO cookies are synced between sgwebapp apps so you sign in to Google or GitHub once. Both are explained — including their limits and the security trade-off — in docs/cookies.md. - 🎨 Retina macOS Icons (
.icns): Automatically downloads high-resolutionapple-touch-iconfrom target pages and builds native multi-size Apple.icnspackages using macOS built-insipsandiconutil. - 🔍 Full macOS Desktop Integration: Installs to
~/Applications/<Name>.app. Fully indexable and launchable via Spotlight (Cmd + Space), Launchpad, and the Dock. - 🪟 Built-in Native Border Daemon (
sgwebapp-border): A standalone, zero-dependency Swift daemon that draws a customizable rounded border (inspired by Omarchy / Hyprland) around active windows. - ⚡ Ultra Lightweight: Native runner is only ~100 KB! No Electron bloat, no Node.js runtime, instantaneous startup.
- 🧩 Behaves Like a Browser Window:
target="_blank"andwindow.open()open real popup windows (so OAuth sign-in flows complete),mailto:/tel:/app links hand off to the OS,<input type="file">opens a picker, JavaScript dialogs render, and a failed load shows a retryable error page instead of a blank window.
Clone the repository and add bin/ to your $PATH:
git clone https://github.com/wuvist/sgwebapp.git ~/code/sgwebapp
cd ~/code/sgwebapp
# Compile the native runtime & border daemon, then run tests
make build
make testAdd this line to your ~/.zshrc or ~/.bashrc:
export PATH="$HOME/code/sgwebapp/bin:$PATH"Or install system-wide to /usr/local/bin:
sudo make install# Default: Native frameless engine (0 topbar, 0 traffic lights, beautiful border)
sgwebapp install "WhatsApp Web" "https://web.whatsapp.com"
sgwebapp install "Google Maps" "https://www.google.com/maps"
# Customize the accent border color and width:
sgwebapp install "GitHub" "https://github.com" --border-color "3b82f6" --border-width 3.0
# Optional: If you prefer Chrome's engine directly (retaining standard 28px traffic lights):
sgwebapp install "WhatsApp Web" "https://web.whatsapp.com" --engine chromeOnce installed:
- Press Cmd + Space, type
WhatsApp WeborGoogle Maps, and press Enter. - Or launch from the terminal:
sgwebapp launch "WhatsApp Web".
sgwebapp listOutput:
APP NAME URL PATH
-------- --- ----
WhatsApp Web https://web.whatsapp.com /Users/wuvist/Applications/WhatsApp Web.app
Google Maps https://www.google.com/maps /Users/wuvist/Applications/Google Maps.app
sgwebapp launch "WhatsApp Web"
# Or open any URL directly in app mode:
sgwebapp launch "https://news.ycombinator.com"# Non-interactive:
sgwebapp remove "WhatsApp Web"
# Interactive (prompts with a list):
sgwebapp removesgwebapp defaults to native macOS system window aesthetics (matching system apps like Finder, Settings, and Notes 100%):
- macOS continuous squircle corners:
16.0 ptouter corner radius using Apple's unified continuous G2 curvature (.continuous). - Ultra-fine glass stroke:
0.5 pthairline border width (exact 1 physical pixel on Retina display). - Dynamic appearance: Border color
"tahoe"automatically adapts to system appearance: in Light Mode, the window boundary seamlessly blends with the native macOS WindowServer compositor drop shadow for an authentic, clean native edge (eliminating double/heavy strokes on non-Retina and Retina displays alike); in Dark Mode, it renders a subtle translucent luminous outline (alpha 0.18) ensuring clean separation from dark wallpapers. - Native content inset padding:
8.0 ptcontent inset padding revealing the frosted backdrop blur around the web application, identical to native macOS sidebar and card margins.
You can configure global defaults stored in ~/.config/sgwebapp/config.json:
# View current configuration
sgwebapp config
# Set default border to a colorful accent (e.g. Catppuccin Blue, Emerald, or Rose)
sgwebapp config set border_color 89b4fa
sgwebapp config set border_width 0.5
sgwebapp config set border_radius 16.0
sgwebapp config set padding 8.0
# Reset anytime back to defaults
sgwebapp config resetYou can also override the style when installing an individual app:
# macOS native window style (default: radius 16pt, padding 8pt, border 0.5pt)
sgwebapp install "Google Maps" "https://www.google.com/maps"
# Full-bleed style without frosted margin (padding: 0)
sgwebapp install "WhatsApp Web" "https://web.whatsapp.com" --padding 0.0
# Custom accent style for a specific app
sgwebapp install "GitHub" "https://github.com" --border-color "3b82f6" --border-width 2.0 --border-radius 16.0 --padding 8.0
# Custom User-Agent (Native engine defaults to modern desktop Safari UA, but can be overridden)
sgwebapp install "SpecialApp" "https://example.com" --user-agent "CustomUserAgent/1.0"Want the signature Omarchy / Hyprland active window border on macOS? sgwebapp includes a compiled Swift daemon that tracks active Chrome web app windows and renders a floating rounded border over them.
# Start with default accent color (#89b4fa, Catppuccin Blue, 2.5px width)
sgwebapp border start
# Or customize color, width, and corner radius:
sgwebapp border start --color 3b82f6 --width 3.0 --radius 12.0sgwebapp border status
sgwebapp border stopOptions:
--color <hex> Border color in hex (e.g. 89b4fa, #3b82f6, ff5555)
--width <float> Border stroke width in points (default: 2.5)
--radius <float> Window corner radius (default: 10.0)
--all-apps Render border for all active apps, not just web apps
--app <name> Add specific application name to track
Each app created by sgwebapp is a standard macOS application bundle located in ~/Applications/<AppName>.app:
~/Applications/WhatsApp Web.app/
├── Contents/
│ ├── Info.plist # App metadata, bundle id, border & login settings
│ ├── MacOS/
│ │ └── WhatsApp Web # Native engine: a copy of sgwebapp-runtime
│ │ # Chrome engine: a `launcher` script running chrome --app
│ └── Resources/
│ ├── AppIcon.icns # 10-tier high-res Apple icon
│ └── sgwebapp.json # URL, engine, border settings, creation timestamp
Native-engine apps store website data under ~/Library/WebKit/<bundle-id>/.
That path is derived from the bundle identifier and cannot be shared between
apps, which is why logins are handled through cookie sync rather than a shared
profile — see docs/cookies.md.
Only the Chrome engine and import-cookies need a browser on disk; native-engine
installs work on a machine with no Chromium installed at all. When one is needed,
sgwebapp looks for these in order of preference:
$SGWEBAPP_BROWSERenvironment variable (if specified)- Google Chrome (
/Applications/Google Chrome.app) - Brave Browser (
/Applications/Brave Browser.app) - Microsoft Edge (
/Applications/Microsoft Edge.app) - Arc (
/Applications/Arc.app) - Chromium (
/Applications/Chromium.app)
- Parses site HTML for
<link rel="apple-touch-icon">or<link rel="icon">. - Fallback to
<origin>/apple-touch-icon.png. - Fallback to Google Favicon 256px resolution API.
- Uses macOS native
sipsto generate 10 standard icon resolutions (16x16 up to 1024x1024). - Compiles
.iconsetinto a native.icnsfile usingiconutil.
| Feature | sgwebapp native |
sgwebapp chrome |
Chrome PWA | Safari Web App | Electron / Pake |
|---|---|---|---|---|---|
| No traffic lights / title bar | Yes | ❌ No | ❌ No | ❌ No | Custom work |
| Chrome cookie reuse | Import on request | Live | Live | ❌ Isolated | ❌ Re-login |
| Install any arbitrary URL | Yes | Yes | Only with a PWA manifest | Yes | Yes (needs build) |
| CLI automation | Yes | Yes | ❌ Manual clicks | ❌ Manual clicks | Needs packaging |
| Active window border | Built in | Via daemon | ❌ No | ❌ No | Custom CSS only |
| Widevine DRM | ❌ WebKit | Yes | Yes | Yes | Varies |
| Disk & RAM footprint | ~1 MB | ~1 MB | ~1 MB | ~1 MB | 100–300 MB |
Run the automated regression suite. It works inside a temporary sandbox and
never touches your real ~/.config/sgwebapp or ~/Applications:
make test # CLI, safety and unit tests
make test-e2e # launches a real .app against a local server (needs a desktop session)
make lint # shellcheck, if installedmake test verifies:
- CLI command validation and help output
- Swift compilation of both binaries
.appbundle structure, a lint-cleanInfo.plistand valid metadata JSON- Correct escaping for names/URLs containing
&and quotes, and distinct bundle identifiers for non-ASCII app names - Refusal to overwrite or delete a
.appsgwebapp did not create, rejection of path traversal in an app name, and that config keys cannot inject code - Daemon lifecycle (
start,status,stop) and config get/set/reset - Chrome cookie decryption (AES-CBC, PKCS7, the Chrome 118+ hash prefix, domain filtering) against a synthetic database
make test-e2e additionally proves, against a real running app, that staged
cookies reach the page before its first request, that window.open popups load,
and that cookies are written back to the jar with 0600 permissions.
MIT License. See LICENSE for details.