Dev Preview
An embedded browser that runs your dev server, with full device emulation, a dual Output and Console drawer, script discovery across nine sources, clipboard screenshots, and Turbopack support for Next.js.
Overview
A Dev Preview panel runs your project's dev server and shows its output in a browser embedded inside Daintree. Your UI updates in real time as agents change the code. Each panel runs its own isolated dev server session, so you can open several previews at once without them stepping on each other.
The toolbar is the same one the Browser panel uses. You can take a clipboard screenshot, open DevTools, or capture the page's console alongside the dev server logs. A set of viewport presets emulates real mobile devices, so you can check responsive layouts without leaving the panel.
Setting Up
Starting the Dev Server
Open a Dev Preview panel with no dev command running and it shows one of two empty states, depending on whether it can find a likely script.
If Daintree finds a candidate, the panel shows a Start the dev server heading with a note that it found a script in your package.json. You get:
- An Auto-detected
[command]chip showing the script it picked - A Run
[command]button (it reads "Detecting…" while it works out the launch details) - A Use a different script… popover listing every detected runner with its command and source
- An Open project settings link for manual configuration
Candidates are ranked by name. Scripts called dev, then start, then serve come first. After those, a .devcontainer postStartCommand if no named script matches, then any other detected runner. Next.js candidates get the --turbopack flag applied automatically (see the Turbopack note below).
If no candidate is found, the panel shows a Set a dev command heading with an inline text input (placeholder npm run dev) and a Run button. The command is validated when you submit it. An inline warning appears if it's empty or invalid. The Open project settings link is available here too.
Manual Configuration
You can also set the dev command directly in project settings instead of going through the empty-state prompts:
- Open your project's settings (or use the Dev Server button in the toolbar)
- Set the dev server command (e.g.,
npm run dev,yarn dev,pnpm dev) - Daintree runs the command and detects the local URL it serves on
Automatic Discovery
Daintree scans your project for runnable commands every time it loads. Detection covers nine sources:
package.jsonscripts: the runner is selected automatically based on your lock file (bun.lockuses bun,pnpm-lock.yamluses pnpm,yarn.lockuses yarn, otherwise npm)- Makefile targets (non-private, non-PHONY)
- Justfile recipes (skips underscore-prefixed entries)
- Taskfile.yml tasks (only those with a
descfield) - Procfile: every
NAME: commandline, with the command body used verbatim - mise.toml:
[tasks]entries with arunfield (string form included), skippinghide = trueand_-prefixed tasks; surfaced asmise run [name] - Django
manage.py: common commands likerunserver,migrate,test, andshell composer.jsonscripts (non-lifecycle).devcontainer/devcontainer.json: thepostStartCommandin string, array, or object form, withnohup, a trailing&, andbash -cwrappers stripped
Every discovered command shows up in the QuickRun autocomplete. Detection results are cached for 60 seconds and refresh on project load or when you switch worktrees.
--turbopack flag before spawning the dev server. The reason: webpack's style-loader injects CSS using unsafe-inline, which Electron's Content Security Policy blocks. Turbopack serves CSS as regular files, so styles render correctly in the embedded browser. The version is detected from
node_modules/next/package.json, falling back to your package.json dependencies. On Next.js 14 or older, or when the version can't be determined, the flag is stripped rather than injected, since Turbopack only became stable for next dev in Next.js 15. Injection is idempotent and adapts to your command form.
next dev becomes next dev --turbopack. npm run dev / yarn dev / pnpm dev get -- --turbopack appended, and bun run dev gets --turbopack appended directly. Compound commands containing &&, ;, or | are left alone. You can turn this off per project in Project Settings > Dev Server Command with the Auto-inject
--turbopack for Next.js 15+ projects checkbox (on by default). Disable it if your project relies on a custom webpack() config, a .babelrc, or loaders that aren't Turbopack-compatible (SVGR is a common one). With the toggle off, Daintree leaves your dev command alone and strips any --turbopack flag a previous run may have added.Opening Dev Preview
Launch a Dev Preview panel from the toolbar (Dev Server button), the panel palette (Cmd+N), or the worktree context menu. If no dev server command is configured, the panel shows the Start the dev server or Set a dev command prompt described above.
You can show, hide, or reposition the toolbar button in Settings > Toolbar. It uses the Monitor icon and is labeled "Dev Preview" in the toolbar configuration.
QuickRun
Discovered commands surface in QuickRun, a managed panel at the bottom of the project sidebar that runs detected scripts and ad-hoc commands against the active worktree. See QuickRun for the full reference.
Toolbar
The toolbar at the top of each Dev Preview panel is the same one the Browser panel uses, plus a cluster of responsive-preview controls only Dev Preview shows. The shared controls:
- Back / Forward: move through page history (disabled when there's no history)
- Reload: refresh the current page (animates while loading). Shift+click does a hard reload that ignores the cache
- Zoom Out / Zoom Level / Zoom In: adjust the preview zoom. Click the percentage label to reset to 100%. Available presets: 25%, 50%, 75%, 100%, 125%, 150%, 200%
- Address bar: shows the current URL. Edit it and press Enter to navigate directly. Frecency-based autocomplete suggests URLs from your history as you type
- Copy URL: copies the current URL to the clipboard
- Screenshot (camera icon): captures the visible page and copies it to the clipboard as a PNG. Disabled until the webview is ready, and skipped on blank pages
- Console (terminal icon): toggles the Output drawer and selects the Console tab
- DevTools (code icon): opens Chromium DevTools for the previewed page in a standard detached window. Disabled until the webview is ready
- Open in Browser: opens the current page in your default browser
The responsive-preview cluster (viewport presets, rotation, device pixel ratio, and zoom to fit) is specific to Dev Preview. It's covered in Device Emulation below.
Device Emulation
Dev Preview emulates real mobile devices, not just their user agent. Turn on a preset and you get full Chromium device emulation: a real mobile viewport, the correct window.devicePixelRatio, proper viewport-meta handling, touch and pointer media features (pointer: coarse, hover: none), and mobile scrollbars. The old approach only swapped navigator.userAgent, which left layouts looking like a narrow desktop window rather than a phone.
Click the viewport toggle (smartphone icon) in the toolbar to turn emulation on. When it's active, a row of preset chips appears. Each preset carries the matching device dimensions and user-agent string:
| Preset | Viewport (portrait) |
|---|---|
| Galaxy S25 | 360 × 780 |
| iPhone 16 | 393 × 852 |
| Pixel 9 | 412 × 923 |
| iPad Air M3 | 820 × 1180 |
With a preset active, the page renders inside a rounded, bordered device frame, centered in the pane. Three more controls fine-tune it:
- Rotate (rotate icon): swaps width and height to switch between portrait and landscape. The tooltip flips between "Portrait" and "Landscape"
- Device pixel ratio: a 1× / 2× / 3× selector (default 1×) that sets the device scale factor, so high-DPR assets and
srcsetselection behave the way they would on the real device - Zoom to fit (maximize icon): scales the device frame down to fit the pane
The preset, rotation, DPR, and zoom settings are per-panel state that Daintree remembers, not global settings. There's nothing to configure in Settings for device emulation.
Find in Page
Press Cmd+F (Ctrl+F on Windows and Linux) to search for text on the current preview page. A floating find bar appears in the top-right corner of the webview with a text input, match count, and navigation buttons.
The search runs in real time as you type and shows the current match position (e.g., "3 / 12"). If there are no matches, the bar shows "No results". The shortcut works whether the Daintree UI or the embedded page has focus. Press Cmd+F again while the bar is open and it refocuses the input and selects the text.
Find in Page is SPA-aware. It restarts the search when the page navigates internally. Closing the bar clears all highlights.
| Action | macOS | Windows / Linux |
|---|---|---|
| Open find bar | Cmd+F | Ctrl+F |
| Next match | Enter or Cmd+G | Enter or Ctrl+G |
| Previous match | Shift+Enter or Cmd+Shift+G | Shift+Enter or Ctrl+Shift+G |
| Close find bar | Escape | Escape |
Find in Page is also in Portal Browser, where it works the same way.
Output Drawer
The Output drawer is a collapsible panel at the bottom of the Dev Preview. Toggle it with the Output drawer button, which has a chevron showing the open/closed state. The drawer has two tabs:
- Output: your dev server's terminal output, the same stream you'd see if you ran the command yourself
- Console: the previewed page's browser console, with a red badge showing the current error count
A status indicator in the drawer header shows the server's state with a color-coded dot:
| State | Indicator | Meaning |
|---|---|---|
| Stopped | Grey | Server not running |
| Starting | Amber | Process launched, waiting for the ready signal |
| Installing | Amber | Missing packages detected; auto-installing dependencies |
| Running | Green | Server is up and serving |
| Stopping | Amber | Shutting the server process down |
| Error | Red | Server failed to start or crashed |
While a restart is underway, the header shows a Restarting label in amber.
Stop and Restart
A Stop button (stop icon) sits in the drawer header whenever the server is starting, installing, running, or stopping. It's disabled while a restart is already underway. Stopping the server doesn't clear your configured command, so the panel doesn't fall back to the setup prompt. It shows a Waiting for dev server placeholder until you start it again.
Restart is a split button. Clicking the main part restarts the dev server. The chevron next to it opens a menu with four options:
- Reload preview: reloads the page without touching the server process
- Restart dev server: kills the server process and relaunches it
- Restart and clear cache: relaunches after deleting framework build caches (
.next,.vite,.turbo) - Reinstall dependencies: relaunches after deleting
node_modulesand reinstalling
The last two options open a confirmation dialog first, since they delete files. They only remove build artifacts and dependencies. Your source files and git history are untouched.
node_modules respectively. Source files and git history are never touched, but a reinstall can take a while on a large project.If a panel re-mounts while the server is still starting (for example, after docking or undocking), the last 300 lines of terminal output are replayed on the Output tab so you don't lose context.
Browser Console Capture
The Console tab captures the previewed page's browser console, the same messages you'd see in DevTools. It's separate from the Output tab, which shows the dev server's own stdout.
It has the tools you'd expect from a console:
- Level filters: All, Errors, Warn, and Log (Log includes
info). The Errors and Warn filters show counts - Text filter: a free-text input to narrow messages by content
- Message detail: each entry has a level badge (LOG / INF / WRN / ERR), a timestamp, an object inspector for logged objects, stack traces, and collapsible console groups
- Clear: empties the captured log
Capture holds roughly the last 500 messages and survives switching between the Output and Console tabs. It's cleared when you delete the panel. This is the same console capture the Browser panel uses.
console.log calls and runtime errors). The Output tab shows the dev server's terminal output (build steps, compile errors, request logs). When something's wrong, check both.Session Lifecycle
Each Dev Preview panel keeps its own isolated dev server session, keyed by project and panel. Sessions survive panel remounts, so docking, undocking, or rearranging panels won't restart your server.
Lazy Loading
The embedded browser isn't created until the panel is first visible. Background panels show a placeholder until you switch to them. This saves memory when you have several panels open.
Slow or Stuck Startup
Daintree waits for the dev server to respond before showing the preview. The wait window is configurable from 1 to 120 seconds (default: 30 seconds) in Project Settings. Daintree no longer restarts a slow server on its own. If the server stays in the Starting state with no URL detected, it surfaces the problem in stages so you can decide what to do:
- After 6 seconds: an ambient working indicator on the panel. No banner
- After 12 seconds: a warning banner ("Dev server is slow to start") with a Restart dev server button. It notes that restarting clears the logs, so you may want to read them first
- After 25 seconds: an error banner ("Dev server still hasn't started"). If the server logged a recognizable error, the banner shows it. Otherwise it lists likely causes: the port is still bound, dependencies are missing, or the build cache is stuck. It may offer a targeted fix (Restart and clear cache, or Reinstall dependencies) alongside a plain Restart
The timers reset the moment the server leaves the Starting state. The Installing state suppresses these banners, so a long first-run install doesn't trigger a false warning.
Connection Retry
If the embedded browser gets a connection-refused or connection-reset error, Daintree retries up to 5 times with exponential backoff, starting at 500ms and capping at 8 seconds. This covers the common race where the dev server reports ready before it's fully reachable.
Scroll Position
Daintree saves your scroll position when a panel unmounts and restores it when the same URL loads again. Restarting the dev server clears the saved position, since the page content has changed.
Memory Reclaim
A background panel may have its webview released to free memory. When that happens, the panel shows a "Reclaimed for memory" placeholder. The webview is recreated the next time you focus the panel.
Blocked External Navigation
If a page in the preview tries to navigate to an external site (a different origin from your dev server), Daintree intercepts it and shows a banner at the top of the webview: Navigation blocked: [domain]. The domain shown is the registrable domain, for example example.com rather than the full hostname. From the banner you can Copy URL or Open in External Browser, which dismisses it.
OAuth Sign-In
When the blocked URL looks like an OAuth flow, the banner offers Sign in via browser instead. This runs a loopback sign-in. Daintree intercepts the token exchange and completes the sign-in back in the embedded page, so you stay in the preview rather than bouncing out to a separate browser session.
The flow moves through a few states. It starts, then enters an intercepting state (with a Cancel option) while it waits for the redirect. From there it either completes ("Sign in completed"), times out ("Sign in didn't complete"), or errors ("Couldn't start sign-in") with a Try again option.
Two-Pane Layout
Dev Preview pairs well with the two-pane split layout. Turn on "prefer preview" in Settings > Terminal (Panel Grid) and Daintree places Dev Preview panels in the secondary pane, so you see agent work and your running app side by side.
Settings Reference
- Dev server command: the command to run (e.g.,
npm run dev). Set in Project Settings - Dev server load timeout: how long to wait for the server to respond, 1 to 120 seconds, default 30. Set in Project Settings
- Auto-inject
--turbopackfor Next.js 15+ projects: controls whether Daintree appends the--turbopackflag when your dev command runs Next.js. Checked by default. Only takes effect on Next.js 15+; older projects have the flag stripped either way. Uncheck if your project uses a custom webpack config, Babel, or loaders that aren't Turbopack-compatible. Set in Project Settings > Dev Server Command - Environment variables: injected into the dev server process. Set in Settings > Project > Variables
- Prefer preview: places Dev Preview panels in the secondary pane automatically. Set in Settings > Terminal (Panel Grid)
- Dev Preview toolbar button: show, hide, or reorder the Dev Preview button (Monitor icon) in the toolbar. Set in Settings > Toolbar
- Always show dev server in launcher: shows the dev server option in the launcher palette even when no command is configured for the project. Set in Settings > Toolbar
The viewport preset, rotation, device pixel ratio, zoom-to-fit, and Output drawer state are per-panel state that Daintree remembers for each panel, not Settings options. There's nothing to configure in Settings for device emulation or the drawer.