Skip to main content
The deno serve command runs a JavaScript or TypeScript file as an HTTP server.

Usage

deno serve [OPTIONS] [SCRIPT]

Description

The serve command is optimized for running HTTP servers. It automatically handles multiple workers for improved performance and provides special handling for modules that export a default object with a fetch handler.

Flags

--port
number
The port to listen on (default: 8000)
--host
string
The host to listen on (default: 0.0.0.0)
--parallel
boolean
Run multiple server instances in parallel for better performance
--open
boolean
Open a browser window to the server URL after starting
--watch
boolean
Watch for file changes and restart the server
--hmr
boolean
Enable Hot Module Replacement (requires —watch)
--no-clear-screen
boolean
Do not clear the screen when restarting in watch mode

Permission Flags

--allow-net
string
Allow network access. Usually required for servers
--allow-read
string
Allow file system read access
--allow-write
string
Allow file system write access
--allow-env
string
Allow environment access
--allow-all
boolean
Allow all permissions

Other Runtime Flags

--import-map
string
Load import map file
--config
string
Specify the configuration file
--no-config
boolean
Disable automatic loading of the configuration file
--lock
string
Check the specified lock file
--node-modules-dir
boolean
Enables or disables the use of a local node_modules folder

Server Module Format

Your server module should export a default object with a fetch handler:
export default {
  fetch(req: Request): Response | Promise<Response> {
    return new Response("Hello, World!");
  },
};
Or using the Deno.ServeDefaultExport type:
export default {
  fetch(req) {
    const url = new URL(req.url);
    
    if (url.pathname === "/") {
      return new Response("Home page");
    }
    
    return new Response("Not found", { status: 404 });
  },
} satisfies Deno.ServeDefaultExport;

Examples

Basic server

Create a simple server (server.ts):
export default {
  fetch(req) {
    return new Response("Hello from Deno!");
  },
};
Run it:
deno serve --allow-net server.ts

Custom port and host

deno serve --port 3000 --host localhost server.ts

With file system access

Serve static files:
deno serve --allow-net --allow-read server.ts

Watch mode

Automatically restart on file changes:
deno serve --watch --allow-net server.ts

Hot Module Replacement

Enable HMR for faster development:
deno serve --watch --hmr --allow-net server.ts

Parallel workers

Run multiple workers for better performance:
deno serve --parallel --allow-net server.ts

Open browser automatically

deno serve --open --allow-net server.ts

Complete development setup

deno serve --watch --hmr --parallel --port 3000 --allow-net --allow-read server.ts

Routing Example

Handle different routes:
export default {
  fetch(req) {
    const url = new URL(req.url);
    
    switch (url.pathname) {
      case "/":
        return new Response("Home page");
      
      case "/about":
        return new Response("About page");
      
      case "/api/users":
        return Response.json({ users: ["Alice", "Bob"] });
      
      default:
        return new Response("Not found", { status: 404 });
    }
  },
};

Using URLPattern

Match dynamic routes:
const userPattern = new URLPattern({ pathname: "/users/:id" });
const staticPattern = new URLPattern({ pathname: "/static/*" });

export default {
  fetch(req) {
    const url = new URL(req.url);
    
    const userMatch = userPattern.exec(url);
    if (userMatch) {
      const userId = userMatch.pathname.groups.id;
      return new Response(`User ID: ${userId}`);
    }
    
    if (staticPattern.test(url)) {
      return serveStaticFile(req);
    }
    
    return new Response("Not found", { status: 404 });
  },
};

Performance Tips

Use parallel workers

For CPU-intensive workloads:
deno serve --parallel --allow-net server.ts

Enable caching

Use Deno’s built-in caching:
const cache = await caches.open("my-cache");

export default {
  async fetch(req) {
    const cached = await cache.match(req);
    if (cached) return cached;
    
    const response = await generateResponse(req);
    await cache.put(req, response.clone());
    return response;
  },
};

Environment Variables

Access environment variables:
export default {
  fetch(req) {
    const port = Deno.env.get("PORT") || "8000";
    return new Response(`Server configured for port ${port}`);
  },
};
Run with environment variables:
PORT=3000 deno serve --allow-net --allow-env server.ts

See Also

Build docs developers (and LLMs) love