Neetly is a Mac code editor built for web development and designed to work with AI agents.
- Built in Browser - each tab/session gets its own browser.
- Worktree enabled - each tab/session gets its own worktree.
- detach session - once the work is done, detach from the session. You can attach to the session at any time later. When you attach to the session, then Claude also resumes from where you left off with full context.
- See PR status - you can see the status of the PR in the session panel.
- Custom layout - arrange your pane the way you want. Give 40% to Claude and the rest to the browser.
- Programmatically open tab - after starting the server, you want to open the browser at a specific place.
- small codebase - Codebase is small enough that you can make changes to meet your needs.
- One click diff view - execut Cmd+1 to see the diff. You can use any tool you want to see the diff.
-
Download neetly-macos.dmg and open the DMG and drag
neetly.appto Applications. -
Set up Claude Code notifications (one-time): Execute the following command to do a one-time setup. It adds hooks to
~/.claude/settings.jsonso that neetly is notified when Claude is done processing and is waiting. When Claude is done, the session tab turns "green". If Claude is waiting for permission, then the session tab turns "red". Clicking a colored session tab also clears the color./Applications/neetly.app/Contents/MacOS/neetly notify_neetly_of_claude_events
git clone https://github.com/neetozone/neetly.git
cd neetly
swift build
# Symlink the CLI to your PATH
ln -sf $(pwd)/.build/arm64-apple-macosx/debug/neetly /usr/local/bin/neetly
# Run
swift run neetly-app- Cmd+1 is configured to show you the diff by executing
lazygit. If you want to use a different tool for the diff then you can configure it in Settings. - After viewing the diff you can close the diff by executing Cmd+2.
- Here is what Cmd+1 does: opens a new terminal in the right most pane. Executes the diff command specified in the Settings. Hits Cmd+Shift+m to maximize the window.
- Here is what Cmd+2 does: Hits Cmd+Shift+m to get out of the full screen mode and then kills that tab.
Declarative pane layout using split, tabs, run, and visit:
split: columns
left:
run: claude --dangerously-skip-permissions
right:
tabs:
run: bin/setup;bin/launch --neetly
visit: http://localhost:3000| Key | Value | Children |
|---|---|---|
split |
columns |
left: and right: |
split |
rows |
top: and bottom: |
tabs |
— | Multiple run/visit as tabs in one pane |
run |
<command> |
Terminal tab |
visit |
<url> |
Browser tab |
size |
35% |
Percentage of the parent split taken by this child. Optional; defaults to 50/50. |
By default, every split is 50/50. Add a size attribute to any child to change that:
split: columns
left:
size: 35%
run: claude --dangerously-skip-permissions
right:
run: bin/setup;bin/launch --neetlyThe left pane takes 35% of the width, the right pane takes the remaining 65%. If you specify sizes on both sides and they don't add up to 100%, the first one wins and the second gets the remainder — no error. size can appear in any child of a split (left/right/top/bottom) and nests naturally.
The neetly CLI runs in any terminal spawned by' neetly'. It communicates with the app via a Unix domain socket.
neetly tabsTAB PANE TYPE TITLE
--------------------------------------------------
1 1 terminal claude *
2 2 terminal bin/launch *
3 2 browser localhost *
# In current pane (default)
neetly browser open http://localhost:3000
# In a specific pane
neetly browser open http://localhost:3000 --pane 3
# Without stealing focus
neetly browser open http://localhost:3000 --background
# Short alias
neetly visit http://localhost:3000# Send "time" + Enter to tab 1
neetly send 1 "time\n"\n is converted to a newline (Enter key). \t is converted to a tab.
neetly run "npm test"Change the session tab color to signal status across sessions. Useful when Claude finishes a task while you're working in another session.
neetly notify # green (task done)
neetly notify red # red (Claude needs permission)
neetly notify clear # reset to normal| Shortcut | Action |
|---|---|
| Cmd+T | New terminal tab in focused pane |
| Cmd+Shift+T | New browser tab in focused pane |
| Cmd+W | Close active tab |
| Cmd+K | Clear terminal |
| Cmd+R | Reload browser |
| Cmd+Shift+] | Next tab |
| Cmd+Shift+[ | Previous tab |
| Cmd+Click | Open a URL displayed in the terminal |
Session (named after your feature/bug, multiple per window)
Pane (a rectangular region, split horizontally or vertically)
Tab (terminal or browser — multiple per pane, one visible at a time)
Customize the terminal font, size, and colors by creating ~/.config/neetly/terminal.json:
{
"fontFamily": "JetBrains Mono",
"fontSize": 17,
"backgroundColor": "#1e1f2e",
"foregroundColor": "#cdd8f4",
"selectionColor": "#635b70",
"linkColor": "#8bb8fa"
}| Field | Description | Default |
|---|---|---|
fontFamily |
Any font installed on your system. Falls back to Symbols Nerd Font Mono, Noto Color Emoji, then system monospace. | JetBrains Mono |
fontSize |
Point size. | 17 |
backgroundColor |
Hex color (#RRGGBB). |
#1e1f2e (Catppuccin base) |
foregroundColor |
Hex color (#RRGGBB). |
#cdd8f4 (Catppuccin text) |
selectionColor |
Background color for selected text. | #635b70 |
linkColor |
Overrides ANSI palette blue (colors 4 and 12), where most terminals render URLs. | #8bb8fa |
scrollback |
Number of lines retained in the scroll-back buffer. | 10000 |
All fields are optional — omit any to use the default. The config is read when each terminal tab is created, so restart neetly to pick up changes.
-
Terminal: SwiftTerm (pure Swift, CPU-rendered). In the future, we could swap it for libghostty (Ghostty's Zig-based engine with Metal GPU rendering) for better performance on 4K displays and large scrollback workloads. It's a "someday maybe" note, not anything planned.
-
Browser: WKWebView is Apple's native web view — the same WebKit engine that powers Safari. It's built into macOS, so neetly ships with zero browser dependencies and no extra download (unlike Electron or CEF which bundle a full Chromium). Every browser tab in neetly is a
WKWebViewembedded directly in the window.Debugging browser tabs with Safari's Web Inspector: neetly enables
isInspectableon all browser tabs, so you can use Safari's full Web Inspector (DOM, console, network, breakpoints) against them. One-time setup: Safari → Settings → Advanced → check "Show features for web developers". Then in Safari → Develop → (your Mac name), you'll see all of neetly's open browser tabs listed. Click one to attach the inspector. -
IPC: Unix domain socket at
/tmp/neetly-<pid>.sock -
Persistence:
~/.config/neetly/repos.json— list of added repos and their default layouts~/.config/neetly/sessions.json— open sessions, restored on relaunch~/.config/neetly/terminal.json— terminal font and color overrides~/neetly/<repo-name>/<session-name>— git worktrees are created here, one per session
-
File watcher: WKWebView (WebKit) does not support HMR (Hot Module Replacement) the way Chrome's DevTools protocol does, so neetly polls the repo every 2 seconds for changes to JavaScript/React/CSS files and triggers a browser reload when anything changes.
Please see this.
Google chrome would be nice but that is a much more heavy lift. I noticed that WKWebView gets 98% of my work done. For the remaining 2% cases I open Google Chrome and do the work there.