Dev Servers
Raycast Extension to manage local dev servers
Dev servers outside the JS worldUnreleased
- Dev servers outside the JS world now show up. The list used to be built from processes running out of
node_modules(plus Bun and the Shopify CLI), so apython -m http.serveran agent started for you, a Flask or Django app,rails s,php -S,go run,cargo runor adeno runserver was invisible however plainly it was listening. Detection now recognises Python (http.server, Flask, Django, uvicorn, FastAPI, gunicorn, MkDocs, Streamlit), Ruby (Rails, Puma, Rack, Jekyll, WEBrick), PHP (php -S, Laravel, Symfony), Deno,go run/cargo run/dotnet runbinaries, Hugo, Zola, Caddy, and any script that Node, Python, Ruby or PHP is running out of a project folder. Rows carry the tool tag (http.server,Rails,Go) and, where it adds something, a runtime badge (Python,Ruby,PHP,Deno), the way Bun already had one. What it deliberately still ignores: daemons, language servers, and anything working out of an app's own folder (~/.codex,~/.cursor,~/.vscode,~/Library, system prefixes) or, for bare scripts, the filesystem root, so the list stays a list of dev servers rather than everything that listens. That last rule applies to every kind of server: Codex's visualization servers, which used to surface as projects named after a UUID, no longer appear. - Restart works for those projects too, from the dashboard and the menu bar alike. A server that is not a Node or Bun project is restarted with the command line it was running, in the same folder, even when the folder also carries a package.json for an asset build; for
go runandcargo runthat is the launcher's command, not the temporary binary. Node and Bun projects keep restarting through their package.json script as before. A server whose command line cannot be run again (Puma and gunicorn overwrite theirs with a status line) is refused up front with a message saying so, instead of being killed and left down. Kill, Copy URL, Open in Browser and the rest already worked on anything listed. - A supervisor and its workers on one port are one row, and go down together. uvicorn
--reload, gunicorn and clustered Puma bind the port in a parent and hand the socket to children; only the parent is listed, and killing or restarting it takes the workers with it, so nothing is left holding the port. - Only startable folders are remembered. A folder the extension has no way to start cold (a
python -m http.serverin Documents, a Rails app) is listed while it runs but does not appear later under Start.
Menu bar restart fixed, plus icon and row polish3 Aug 2026
- Restarting from the menu bar brings the server back. Restart used to kill the server and stop there: Raycast unloads a menu bar command shortly after its menu closes, and the respawn was still in flight when that happened. Restart now hands the whole job to the dashboard, the same way menu bar starts already work, so you also get what starts get: a live "Restarting…" row, and a diagnosed failure row if the server never comes back, instead of silence.
- The Kill action's icon now reads as a trash can. The old outlined glyph with its floating handle looked like a jar with a cork once tinted red; the solid-body variant from the same icon family keeps the trash silhouette at menu size.
- Every menu icon now draws completely. Raycast's SVG renderer skips
line,polyline, andpolygonelements, so Copy Port and Open in Terminal had no icon at all, the trash was missing its lid, and the Restart arrows lost their heads. All glyphs are now built from paths, which render fully. - Projects without a usable favicon get their own color in the menu bar. When a project's favicon only exists as an SVG (which the menu bar can't render as an image), the fallback glyph is now tinted with the favicon's dominant color instead of the framework color, so a row is recognizable per project rather than per framework. The framework tint remains only for projects with no favicon at all.
- Killing from the menu bar confirms itself. A small system HUD says "Killed
" the instant you click (and "Killed both/all N servers" for the per-project kill). The kill really is instant; the SIGKILL cannot be refused. The menu bar count, which used to be the only signal and lagged by several seconds, now updates a few seconds sooner as well. - Branch tags appear only when they mean something. A project running a single worktree no longer repeats "· main" on every row. The branch shows, main included, when two worktrees of the same project run side by side, or when two entries in the Start section share a project name.
- Fixed: restarting one of two servers running from the same folder could kill the wrong one. The menu bar's Restart now names the exact server that was clicked, so a sibling server sharing the project folder is left alone.
- Fixed: a dev server on a deliberately chosen high port (49152 and up) could vanish from every surface. The phantom-server cleanup now hides only processes it knows to be helpers (
workerd), instead of anything that looked abandoned. A server this extension starts is handed to the system the moment the command unloads, so a legitimate server looked exactly like a leftover. - Fixed: a project starting on a port another project used earlier could inherit that project's favicon, permanently. Favicons are now cached per project as well as per port.
- Favicon lookups can no longer be redirected off the dev server. Responses served from elsewhere were already refused; now the request itself stops before a redirect leaves the server's origin, so no other host is ever contacted.
Live rows for starts and restarts, and no more phantom servers26 Jul 2026
- Every server you start gets a row the moment you confirm it, spinning in its project's section until the port binds and then handing over to the real server row, cursor and all. Start several at once and you can watch each one come up instead of guessing behind a single toast.
- Restarting shows the same row, saying "Restarting…". It goes up before the old server is stopped, so the project never blinks out of the list and the cursor lands on the replacement.
- A start that never binds leaves a red row behind saying why. It names the cause where it can ("Portless proxy isn't running", "Port already in use") and keeps the remedies on the row: View Startup Log, Copy Fix Command, Open in Terminal, Dismiss. This used to be a toast, whose buttons vanished with it and were missing entirely when the Raycast window was closed. Several failures now each say their own piece instead of sharing one line.
- A failure waits for you. The row is not tied to the window that started the server: close Raycast during a start and, if it never comes up, the diagnosed red row is sitting in the dashboard the next time you open it. Rows that go stale are dropped after a day.
- The list is ordered newest first. It used to come out in process-ID order, which only loosely tracks start time, so a server from an hour ago could sit above one from seconds ago. Starting a server now moves its project to the top with it.
- The dashboard stays open when a server opens in your browser. Auto-open used to bring the browser to the front, and Raycast hides itself when it loses focus, so the window vanished a second after a start. The tab now opens behind it. Opening a URL yourself still switches to the browser.
- Folders selected in Finder can now be started from the dashboard.
⌘Nused to ignore your selection, so acting on it meant going back to root search. The picker now offers it at the top under Selected in Finder, naming what it would start, and↵starts it. - Fixed: Cloudflare and Wrangler projects showed phantom servers on odd ports like
51759, and restarting one made copies. Theworkerdhelpers those projects run were being taken for dev servers in their own right. They are now recognised as helpers however they were started, and killing or restarting a project clears them out, including leftovers that ignored Kill and held their ports until you rebooted. The cleanup only ever touches orphanedworkerdprocesses, so a tool of your own running from the project folder is never caught in the sweep. - Fixed: starting from the menu bar never opened the browser, even with the setting on. One thing to check after updating: the July 9 release moved that setting to the extension level, which reset it to off. If auto-open has felt broken since, turn Open in browser when the port binds back on once.
- Also: the menu bar count updates when a start or restart fails, not only when it succeeds; typing in the search bar no longer hides a starting or failed row; the "Restarted" confirmation hides itself after a couple of seconds; and Cloudflare Worker projects show a Wrangler tag in the Start picker.
Clearer startup failures, on start and on restart26 Jul 2026
- A dev server that fails to start because the portless proxy is down now says so. Dev scripts wrapped in
portless runneed the proxy already running: a background spawn has no TTY for portless's sudo prompt, so portless exits before the framework ever boots. The toast used to report only the generic "not detected after 15s", which reads as an extension bug rather than a machine-setup problem. It now says Portless proxy isn't running and offers a Copy Fix Command action forportless service install, which starts the proxy at boot so starts keep working after a reboot. - A restart that times out now names the cause too. Restarting respawns a server the same way starting it does, so it dies for the same reasons, but the timeout toast only offered a raw log path in the temp directory. It now reports a port conflict or a downed portless proxy in the same words the start toast uses, with the same actions.
- Failure toasts got a lot shorter. A toast gives you one line, and a long title cuts the rest off mid-word, so the explanation was landing where nobody could read it. The cause is now the title itself ("Port already in use") and the project name moves to the subtitle, with the fix on a button rather than buried in prose.
Menu bar polish and sharper tool detection9 Jul 2026
Menu bar
- Running servers now show their real favicon instead of a colored dot, and stopped projects in the Start section show a framework-tinted folder instead of a stark grey one.
- Each running server now leads with its project name, followed by the port (or custom domain) and branch. For example:
Novera (9292) · flagship-rebuild. The dim per-project section header is gone (the project name reads clearly in the row instead), and the port makes several servers of the same project on the same branch easy to tell apart. - The Start section no longer lists projects whose folder was deleted (e.g. a removed git worktree); it now matches the Start Dev Server command's list, which already filtered them out.
- Favicons render in color instead of a black square. The resolver now skips Safari's monochrome
mask-icon, prefers colored raster icons (apple-touch-icon, PNG, ICO), and ignorescurrentColor-only SVGs, so it lands on the real icon. Because the menu bar can't render SVGs in color, it uses a separate raster variant pulled from the page or from conventional paths (/favicon.ico,/apple-touch-icon.png). SVG-favicon sites still show a real icon there, falling back to a tinted dot only when no raster exists anywhere. - Starting a project from the menu bar's Start section now opens it in the browser when the port binds, matching the Start Dev Server command. "Open in browser when the port binds" is now an extension-wide preference shared by every start surface (Start command, dashboard, menu bar); since it moved from the command to the extension level, you may need to re-enable it once.
- The Kill and Kill All actions use a red icon to flag them as destructive, and menu bar actions now use a consistent set of polished Nucleo icons with bundled light/dark variants.
Tool detection
- Native helper binaries no longer masquerade as separate servers. Platform-binary packages (npm's
convention: workerd, esbuild, rollup, swc, sass-embedded, …) are never the tool you chose. Detection recognizes that shape and climbs the process tree to label the helper with its parent's tool. When no ancestor resolves, it strips the platform suffix (- - workerd, notworkerd-darwin-arm64). Helpers on OS-assigned ephemeral ports under an already-listed server (e.g. the workerd instances the Cloudflare Vite plugin runs undervite dev) are hidden; helpers on deliberately configured ports (workerd on 8787 underwrangler dev, a Hydrogen storefront undershopify app dev) stay visible, since those are the URLs you actually open. - New tool tags with Cloudflare styling: Wrangler, Workerd, and Miniflare.
Fix tool detection for pnpm and shim-relative launch paths7 Jul 2026
- Servers launched through pnpm's virtual store or a shim's relative self-exec path no longer show a raw filesystem path as their tool tag. Vite (and any framework) invoked as
node_modules/.bin/../vite/bin/vite.jsornode_modules/.bin/../.pnpm/vite@now resolves to its real package name: tool detection normalizes the script path and reads the package directory adjacent to the last_ /node_modules/vite/bin/vite.js node_modulessegment, instead of pattern-matching the command text. Scoped packages (@scope/pkg) and pnpm's encoded scoped store entries (@scope+pkg@version) resolve correctly too. - The SvelteKit promotion (Vite plus a
svelte.config.*) now applies on every launch layout, not just the plainnode_modules/.bin/viteform.
Menu Bar Command2 Jul 2026
- Adds Dev Servers Menu Bar, a compact menu bar command that shows running dev servers by project and keeps the count visible when you want it.
- Each running server gets quick actions for opening, restarting, killing, copying the URL or port, and jumping into your editor or terminal.
- Recent stopped projects appear in a Start section, ranked by use, and hand off to the dashboard so the normal startup toast and progress flow stay intact.
- Projects with two or more servers get a kill-all item at the bottom of their section: "Kill Both Servers" for a pair, "Kill All 3 Servers" beyond. It acts on click without a dialog (menus can't confirm), so the label always names the blast radius and single-server projects don't show it at all.
Automatic port fallback for Shopify themes2 Jul 2026
- Two copies of a theme now run side by side.
shopify theme devhas no next-free-port fallback: when its fixed default port 9292 is taken (say, by the main checkout while you start a git worktree of the same theme), the CLI just dies withEADDRINUSE(Shopify/cli#5554). Starting a theme now probes the default port first and, when it's taken, exportsSHOPIFY_FLAG_PORTwith the next free one. Because it's an environment variable, the fix reaches the CLI through any wrapping. A bare theme root started asshopify theme devand adevscript that nests it underconcurrentlyboth come up on their own port. A--portwritten explicitly into your own script still wins. - When a spawn dies on a port conflict anyway (a non-Shopify server with a fixed port, or every scanned port taken), the failure toast now says "a port is already in use by another process" instead of the generic "not detected after 15s". Its View Startup Log action opens the log of the server that actually hit the conflict.
Shopify support, faster polling, new actions10 Jun 2026
Shopify
- Detect running Shopify CLI dev servers launched globally, including
shopify theme dev,shopify app dev, andshopify hydrogen dev, so they appear in the dashboard even when the process is outsidenode_modules. Shopify-specific tool tags: Shopify Theme, Shopify App, and Hydrogen. - Start Dev Server now works for Shopify themes, which have no
package.jsonat all. A folder containinglayout/theme.liquid(orshopify.theme.toml) resolves as a theme root and starts withshopify theme dev; a folder withshopify.app.tomland no dev script falls back toshopify app dev. Restart on a detected theme server works through the same path. Scaffolded Shopify apps and Hydrogen storefronts already start via theirdevscripts, so all three project types are now coherent across detect → start → restart. - The Start picker tags Shopify projects (theme, app, Hydrogen) so they're recognizable among your recents.
- First-run note: the Shopify CLI prompts for login and store selection when it has no remembered state, which a detached spawn can't answer; run
shopify theme dev --storeonce in a terminal and the extension starts it cleanly from then on. The captured startup log shows the prompt if this happens.
Performance
- The portless lookup no longer spawns a zsh login shell (re-sourcing
~/.zshrc) on every refresh. The portless binary and login PATH are resolved once, persisted in Raycast's cache, and the binary is executed directly from then on: roughly 1s → 100ms per poll on a typical nvm setup, and the dominant cost of every refresh cycle. - Per-process metadata (working directory, framework, runtime) is now cached for the lifetime of each PID, so steady-state polls skip the second
lsofquery and the tool-detection regexes entirely. Guarded against PID reuse via process start time. - Git project info is cached per directory and invalidated by the
HEADfile's mtime (which changes on every checkout, per worktree), replacing agit rev-parsespawn per project per poll with a singlestat. - Branch switches now show up in the dashboard immediately: the change-detection that skips redundant re-renders compares branches too, instead of waiting for a PID change.
New actions and preferences
- Open in Editor (
⌘E): a new shared Editor App preference (VS Code, Cursor, Zed, …) adds an Open in Editor action to dashboard rows and recent-project rows. Hidden until the preference is set. - Copy Network URL (
⌘⌥C): when a server is bound beyond loopback and your Mac has a LAN address, copyhttp://for testing on a phone or another machine. Only offered when the server is actually reachable that way.: - Copy Port (
⌘⌥P): copy just the port number, for env files and config. - The startup log view now follows the file while open (live tail every 2s), so a slow boot or crash loop streams in without mashing refresh.
Start Dev Server1 Jun 2026Adds a Start Dev Server command for spinning up dev servers without leaving Raycast. Works from a Finder selection, from a list of recently-seen projects, or from a native folder picker.
Start Dev Server
- From Finder: select a project folder (or any file inside one) and run Start Dev Server. The extension walks up to the nearest
package.json, detects the package manager (npm / pnpm / yarn / bun), picks the right script, and spawns it with the same PATH-aware login-shell pattern used by Restart. The dashboard opens immediately and shows a "Starting…" toast that transitions to "X is running" the moment the server binds a port. - From recents: run the command with nothing selected in Finder and you get a picker over the projects the extension has seen running recently. Recents auto-populate from the dashboard's polling loop, with no explicit bookmarking. LRU-bounded at 30 entries. Running projects are hidden from this list (they live in the dashboard); they reappear once stopped.
- From anywhere: the picker also exposes a Choose Folder… entry that opens the native macOS folder dialog directly, with no intermediate screen.
- From the dashboard: the empty state offers a primary Start Dev Server action (just press
↵from a fresh dashboard to land in the picker). Each running-server row's action panel also carriesStart Dev Server(⌘N), so spinning up another project never requires bouncing back to root search. - Each picker row shows last-seen, git branch when applicable, and a framework tag inferred from
package.jsondependencies. Cached favicons appear inline once the dashboard has seen the project running, so even stopped projects keep their real icon. Per-row actions: Start, Open in Terminal (⌘T), Show in Finder (⌘⇧F), Copy Path (⌘C), Remove from Recents (⌃X). - Folders that no longer exist on disk are hidden this render but kept in storage so they reappear when (for example) an external drive remounts.
- Startup logs: every spawned server's stdout+stderr is captured to a per-project log. If a server doesn't bind a port within 15s, the toast escalates to a failure with a View Startup Log action instead of silently disappearing, so a misconfigured or custom setup (e.g. portless needing sudo, a missing binary, a crashing build) is diagnosable from inside Raycast. Every running-server row also carries a View Startup Log action (
⌘L) for inspecting output on demand.
Behavior
- Script picker tries
dev→start→developfirst, then scans script values for known dev-server tools (Vite, Next, Astro, Nuxt, Webpack, Parcel, Gatsby, Remix, Turbo, Bun watch/hot, nodemon, tsx watch, ts-node-dev, serve, http-server, live-server). Monorepo conventions likedev:webandstart:devresolve out of the box. - Already running on that folder? You get one consolidated alert:
X is already running. Restart?for a single target,All 3 already running. Restart them?when every selected folder is running, or2 of 3 already running. Restart these, then start the other one?for the mixed case. No more N-alert cascades for N-folder selections. - The Finder selection is only honored when Finder is the frontmost app. Previously a folder selected earlier (to start one server) lingered in Finder's selection, so running the command later from another app, e.g. the browser, would silently treat that stale folder as the target and surface a spurious
already running. Restart?. Now, unless you're actually in Finder, the command goes straight to the recents picker, where you can start whatever project you meant. - After a server is started (from Finder, the picker, or a recent), the dashboard moves the selection onto that new row, so pressing
↵acts on the server you just launched rather than re-opening whatever was previously selected. Restart (⌘⇧R) likewise re-focuses the replacement once it binds. - Multi-folder selection prompts for confirmation by default, useful for monorepo siblings or a "frontend + backend" startup, with an opt-out preference for users who do this regularly.
- New Open in browser when the port binds preference auto-opens the URL once the new server starts listening. Off by default; a one-time hint surfaces it in the in-flight toast for the first few starts.
Under the hood
- The dashboard is the controller for the entire spawn flow. The launching command resolves a target list and hands off via
launchContext, which lets the user land on the dashboard immediately and watch the spawn happen there, rather than waiting on a blank loading view for a pre-spawnfetchServerscall. - Spawn lifecycle is a clean state machine on the dashboard:
idle → pending → confirming → spawning → done. The "Starting…" toast lives on the dashboard so it's visible the whole time the user is waiting, and transitions to a green "running" state the moment every expected cwd appears in the polling loop. - All filesystem paths flow through
canonicalCwd(arealpathSyncwrapper) so symlinked project paths compare equal between Finder selections, the recents store, andlsof's view of running processes. - Extracted
startDevServer(cwd)andkillServer(pid)so the new command and the existing restart flow share one spawn path. Restart is nowkillServer + startDevServer. - The spawn passes the package manager and chosen script as separate arguments rather than building a shell string, so projects with unusual script names (spaces, punctuation) start reliably and the launch surface stays free of shell-interpolation surprises.
- Shared
tool-display.tsso the framework tag styling stays consistent across the dashboard and the picker. - Favicons cached onto recents for stopped-project icons are size-capped, keeping the recents store small; the live dashboard always renders the real favicon regardless.
Preferences
- Terminal App is now a single shared preference that applies to both Dev Servers and Start Dev Server: set the terminal
⌘Topens once, and both commands honor it.
Portless & Shortcuts26 May 2026Surfaces custom local domains from portless, and tightens the action panel, shortcuts, and preferences to align with Raycast conventions.
Custom domain detection
- Detect custom local domains via portless and show the named URL (e.g.
myapp.localhost) as the row title instead oflocalhost:PORT. Thelocalhost:PORTpill stays visible alongside it, since the raw loopback target is still useful for env files, OAuth allowlists, CORS rules, and anything that doesn't trust the local CA. - "Open in Browser" and "Copy URL" target the custom domain when one is present. New "Open Localhost URL" and "Copy Localhost URL" actions target loopback explicitly.
- Search the list by custom domain: typing "myapp" surfaces
https://myapp.localhost. - New "Show localhost URL with custom domain" preference, for users who'd rather hide the
localhost:PORTpill once a named domain is in place. - Filter out the portless proxy daemon itself so it never appears as a phantom dev server row.
Action panel and shortcuts
- Kill Server's shortcut moves from
⌘Dto⌃X.⌘Dis officially "Duplicate" in Raycast's keyboard conventions;⌃Xis "Remove". Kill All for Project and Kill All Servers shift to⌃⇧Xand⌃⌥Xto stay in the same family. - Copy Localhost URL is bound to
⌘⇧C, mirroring⌘Cfor Copy URL. - Action panel reordered: Restart Server now sits at position 3, above Kill Server. Restarting is the more common mutation (iterate-on-change), and placing it above Kill also means Raycast's reserved
⌘↵second-action shortcut never auto-fires Kill. It falls through to Open Localhost URL when a custom domain is present, or to Restart otherwise. Both are safe.
Preferences
- Refresh Interval (a behavior setting) moves above Project Display (cosmetic), so settings that change what the extension does appear before settings that change how it looks.
Worktree grouping and detection rewrite26 May 20263x faster, windows port preparation, support for git branches & worktrees, search by project and branch.
- Rewrote process detection from an embedded shell pipeline to TypeScript. Output is unchanged; the new path is roughly 3x faster, removes a class of shell-parsing bugs, and lays the groundwork for a future Windows port.
- Group multiple git worktrees of the same repo into one project section. Each row shows its current branch next to the link, and per-row actions (Open in Terminal, Show in Finder) still target the specific worktree on disk.
- Show the current git branch on every project's rows, so you can tell at a glance which branch a long-running dev server is on, even for single-worktree projects.
- Search by project name or branch directly in the Raycast search bar, Raycast's built-in filter previously only matched the port number and subtitle.
- New preferences to toggle each row accessory (uptime, git branch, framework tag) independently.
- Stylized framework names (SvelteKit, Astro, Next.js, esbuild, etc.) in the row tag and the filter dropdown.
- More reliable restarts: the old process is force-killed and confirmed exited before the replacement spawns, closing a rare race where the new server could fail to bind because the old one still held the port.
Detection and favicon improvements25 May 2026Detects more dev-server tools, renders favicons reliably across frameworks, and handles project paths that contain spaces.
- Detect any Node tool that runs out of
node_modules/, not just those launched vianode_modules/.bin/. Surfaces tools likeserveandhttp-serverthat were previously missed. - Render favicons inline so they display reliably for every framework, including SVG icons and dev servers (such as Astro) that don't expose static assets cross-origin.
- Preserve spaces in detected project paths. Restart, Open in Terminal, and Show in Finder no longer break on projects whose absolute path contains a space.
Initial Version19 May 2026Dashboard for every running dev server, grouped by project.
- A keyboard-first dashboard for every dev server you have running.
- Auto-detects servers from any framework that uses
node_modules/(Vite, Next.js, Astro, SvelteKit, Nuxt, Webpack, Parcel, Gatsby, Remix, Turbo, esbuild) plus the Bun runtime. - Servers are grouped by project with favicons, uptime, framework, and runtime tags.
Actions:
- Open in browser
- Copy URL
- Kill
- Restart
- Open in terminal
- Show in Finder
- Manual refresh
- Kill all in a project
- Kill all globally.
- Bulk-kill actions ask for confirmation.
- Restart picks the right package manager from the project's lockfile (npm, pnpm, yarn, bun) and polls until the new server binds a port.
- Failures surface as toast notifications with a link to the log.

