Skip to content

Serve files or a port

devhost serve gives a folder or an already running HTTP server an HTTPS hostname, without a manifest.

Terminal window
devhost serve --domain notes.localhost
devhost serve --dir "./my notes" --domain notes.localhost

The first command serves the current directory; --dir picks another one, relative to the current directory. Open https://notes.localhost once devhost prints the URL.

  • A folder serves index.html, then index.md, then README.md, then readme.md, and otherwise shows a clickable listing confined to the served folder.
  • Files are read on every request, so a reload shows edits and new files.
  • Markdown files (.md, any case) render as GitHub Flavored Markdown, without raw HTML or unsafe links. Show source switches to the raw text and Show rendered switches back; the choice is remembered for that hostname.
  • A breadcrumb above each listing and Markdown page links to its parent folders; devhost returns to the served root.
  • Listings and Markdown use the same React/shadcn interface as devhost’s other built-in pages. An empty folder shows an empty state; JavaScript is required for rendered Markdown and its source toggle. Without JavaScript, the page still exposes escaped source text or directory links.
  • Files support GET, HEAD, and byte ranges.
  • Files and folders whose names start with . are not listed and not served. Symbolic links work only when they point inside the served folder.
  • This is a static server: an unknown URL returns 404, with no fallback to a single-page app’s index.html.

Use serve in devhost.toml to run the same file server as a managed service:

name = "project"
[services.design]
serve = "packages/design"
host = "design.localhost"
alwaysStart = true

Relative directories resolve against the manifest that declares the service, including an included manifest. They stay within the root manifest directory; absolute directories can point elsewhere. The directory must exist. File browsing and symlink access remain confined to that directory.

The service defaults to an automatic port and the loopback bind address. You can set port and bindHost explicitly, add host aliases or path routes, configure HTTP or TCP health checks, and use dependencies and service selection. alwaysStart = true keeps it available when you select other services. Path routes match the original request path; they do not strip a prefix from file paths.

Devhost owns the file server directly. Starting, stopping, restarting, manifest reloads, and worktree switches use the stack’s normal service lifecycle. Files are read live, so edits need only a browser reload. serve replaces command; it rejects cwd, child-process env, injectPort, lifecycle, proxyLocalOrigin, watch, managed = false, and process-only health checks. The served directory also supplies the service’s project directory for editor and chat tools.

Terminal window
devhost serve --port 3000 --domain app.localhost

This routes https://app.localhost to an HTTP server already listening on 127.0.0.1:3000. devhost waits until the port accepts connections, then routes it like a stack service, including the devtools toolbar on HTML pages. It never starts, restarts, or stops that server. For a Docker container, publish its port on the host first.

Use a manifest instead when you want devhost to run the server, check an HTTP health URL, or route several services.

OptionMeaning
--domain, -dRequired. A hostname without scheme, port, or path. It must resolve to this machine; .localhost names always do.
--dirFolder to serve. Defaults to the current directory.
--port, -pPort of a running HTTP server on 127.0.0.1, from 1 to 65535. Cannot be combined with --dir.

devhost serve ignores any devhost.toml, including one named by DEVHOST_MANIFEST, and writes nothing into the served folder.

devhost serve starts the shared Caddy when it is not running. The first time, devhost installs Caddy’s local certificate authority, which can ask for your password; see Route apps over HTTPS.

The session runs in the foreground. Ctrl-C removes its route and stops the file server; Caddy and any server you routed keep running. A hostname held by another session or stack is rejected, so give concurrent sessions different hostnames. devhost stack list shows only manifest-backed stacks: stop a serve session from its terminal.