A dev server is a local HTTP server optimized for the development loop. Its job is to serve your application locally with features that make iteration fast.
- Hot Module Replacement (HMR) — when you save a file, only the changed module is swapped in the browser without a full page reload. State (like form inputs, scroll position) is preserved.
- On-demand transformation — instead of bundling everything upfront, modules are transformed (TypeScript → JS, JSX → JS, etc.) only when the browser requests them. This makes startup near-instant even for large projects.
- File watching — monitors the filesystem and triggers rebuilds/HMR updates.
- Error overlay — compilation errors are shown directly in the browser.
- Uses native ES modules in the browser during dev. The browser sends
importrequests, and Vite intercepts them, transforms the file on the fly, and serves it. - Pre-bundles dependencies (node_modules) with esbuild for speed, but your source code is served unbundled.
- Injects a small HMR client via WebSocket that listens for updates.
vite devstarts the server, typically onlocalhost:5173.
bun --hotruns a script and hot-reloads it on file changes (server-side HMR).- For frontend, Bun's bundler can serve files, but it's less mature than Vite's dev server.
- The pitch is speed — Bun's native TypeScript/JSX support means less transformation overhead.
Deno already has some pieces:
deno serve— runs an HTTP server from a file exporting afetchhandler. It watches for changes with--watchand restarts.- Native TypeScript/JSX — no transpilation step needed for server-side code.
--watchflag — available ondeno run, restarts the process on file changes.
-
Frontend asset serving with on-demand transforms — serving
.tsx/.tsfiles to the browser as ES modules, transpiled on the fly. The browser can't consume TypeScript natively, so something needs to transform it before serving. -
HMR protocol — a WebSocket connection to the browser that pushes granular module updates instead of full page reloads. This requires an HMR client runtime injected into the HTML and an HMR API (like
import.meta.hot). -
CSS/asset handling — processing CSS imports, CSS modules, static assets, etc.
-
Dependency pre-bundling — npm packages with CJS or many small files need bundling for browser performance (hundreds of individual HTTP requests are slow even with HTTP/2).
- Deno already transpiles TS/JSX natively — it could serve browser-ready code with minimal overhead, no extra tooling needed.
- "Zero config" story:
deno devcould just work for a frontend project without installing Vite, webpack, etc. - Bun is marketing this as a differentiator, so there's competitive pressure.
- Aligns with Deno's "batteries included" philosophy.
- Vite is excellent and widely adopted. Building a competitive dev server is a massive surface area (plugins, framework integrations, CSS preprocessors, etc.).
- Deno could focus on being a great Vite backend instead (Vite already has experimental Deno support).
- Maintenance burden — frontend tooling moves fast and has many edge cases.
# Start dev server for a frontend project
deno dev
# Or with explicit entry
deno dev --port 3000 index.htmlIt would scan your HTML for <script> tags, serve those files with on-demand TS/JSX transformation, inject an HMR client, and watch for changes. Frameworks like Fresh already do a version of this within Deno's ecosystem.
The pragmatic middle ground (which Deno seems to be pursuing with Fresh and deno serve --watch) is: provide great server-side DX natively, and integrate well with Vite for frontend-heavy projects rather than reinventing the entire frontend dev server.