On this page
Frameworks
deno desktop ships in Deno v2.9.0 and is not in a stable release yet. To try
it now, run deno upgrade canary to install the
canary build. The command, configuration
keys, and TypeScript APIs may still change before the feature is stable.
Point deno desktop at a directory and it auto-detects the framework, picks the
right entry point, embeds the build output in the binary, and runs the
framework's production server (or dev server under --hmr) with the webview
pointed at it.
# Inside a Next.js / Astro / Fresh / etc. project:
deno desktop .
No code changes, no special adapter. The same project that runs as a web app ships as a desktop app.
Detection Jump to heading
Detection is based on config files and package.json dependencies. The first
match wins.
| Framework | Detected by |
|---|---|
| Next.js | next.config.{js,mjs,ts} |
| Astro | astro.config.{mjs,ts,js} |
| Fresh | fresh.gen.ts or _fresh/ directory |
| Remix | @remix-run/react or @remix-run/dev in package.json |
| Nuxt | nuxt.config.{ts,js,mjs} |
| SvelteKit | svelte.config.{js,ts} |
| SolidStart | @solidjs/start in package.json |
| TanStack Start | @tanstack/{react,solid}-start in package.json |
| Vite (SSR mode) | vite.config.* plus a server.{js,ts,mjs} entry |
If none match, deno desktop falls back to treating the path as a script, the
same as deno desktop main.ts. You write a
Deno.serve() handler and serve your own UI.
What detection does Jump to heading
When a framework is detected, the CLI:
- Generates a synthetic entry point that imports the framework's production
server (or dev server under
--hmr). - Embeds the build output into the binary's virtual filesystem (
.next/,dist/,.output/,_fresh/,build/, etc., depending on the framework). - Self-extracts the VFS at runtime so framework code finds its build output
relative to its own working directory. Next.js looks under
.next/, Astro underdist/, and so on. - Runs the framework server as your
Deno.serve()handler. The webview navigates to the bound port like any other desktop app.
Build your project before running deno desktop. It does not run next build,
astro build, and the like for you, so run the framework's build step first.
Per-framework notes Jump to heading
Next.js Jump to heading
cd my-next-app
npx next build # produce .next/
deno desktop .
Production: imports next/dist/cli/next-start.js. Dev (under --hmr):
next/dist/cli/next-dev.js. The .next/ directory is embedded.
App Router and Pages Router both work.
Astro Jump to heading
npm run build # produce dist/
deno desktop .
Astro projects with an SSR adapter import ./dist/server/entry.mjs. Static
projects (no adapter) are served via Deno's static file server pointed at
dist/.
Both modes work; SSR has access to the full Astro request lifecycle, static mode is faster to start.
Fresh Jump to heading
deno task build # produce _fresh/
deno desktop .
Fresh 2.x: imports _fresh/server.js and runs the Vite dev server under
--hmr. Fresh 1.x: imports ./main.ts directly.
Remix Jump to heading
npm run build
deno desktop .
Production: runs remix-serve against the build/ directory. Dev (under
--hmr): @remix-run/dev CLI.
Nuxt Jump to heading
npm run build # produce .output/
deno desktop .
Uses Nuxt's Nitro output at .output/server/index.{ts,mjs}. Dev (under
--hmr): nuxi dev.
SvelteKit Jump to heading
npm run build
deno desktop .
Looks for .deno-deploy/server.ts first (the Deno Deploy adapter's output),
falling back to .output/server/index.{ts,mjs} (the Node adapter's output).
Dev: Vite dev server.
If you use a different adapter (@sveltejs/adapter-static, etc.), serve the
output directory yourself with Deno.serve() instead
of relying on detection.
SolidStart and TanStack Start Jump to heading
Both use the Nitro framework underneath; detection handles them via the
.output/server/index.* entry. Build first (npm run build) before running
deno desktop.
Vite SSR Jump to heading
Plain Vite projects with a custom SSR entry (server.ts, server.js,
server.mjs) work with deno desktop if there is also a vite.config.*.
Production runs the SSR entry directly; dev (under --hmr) runs the Vite dev
server in middleware mode.
Forcing a framework or opting out Jump to heading
There is no flag to force detection. To opt out (to ship a framework project without using detection), pass an explicit script entry:
deno desktop ./my-server.ts
In my-server.ts you import and start the framework yourself. Use this when you
need control over startup that the detection cannot express.
Hot reload in framework projects Jump to heading
Under --hmr the framework's own dev server runs and the webview connects to it
directly. State preservation, fast refresh, and error overlays all work the same
as in a browser. See HMR for details on both framework
and non-framework HMR modes.