Skip to main content

Overview

The kosh serve command starts a local HTTP server to preview your site. In development mode (--dev), it builds the site, watches for changes, and automatically reloads the browser.

Usage

kosh serve [flags]

Flags

--dev
boolean
default:"false"
Enable development mode with build, watch, and live reload. This mode:
  • Builds the site on startup
  • Watches for file changes and rebuilds automatically
  • Skips PWA generation for faster builds
  • Auto-detects baseURL as http://localhost:2604 if empty in config
  • Enables Server-Sent Events for browser auto-reload
--host
string
default:"localhost"
Host or IP address to bind the server to.Use 0.0.0.0 to make the server accessible on your local network:
kosh serve --host 0.0.0.0
--port
string
default:"2604"
Port number to listen on.
kosh serve --port 8080
-drafts
boolean
default:"false"
Include draft posts in development mode. Posts with draft: true in frontmatter are normally excluded.
-baseurl
string
Override base URL from config. In dev mode with empty baseURL, this is auto-detected as http://localhost:2604.

Examples

# Serve pre-built site from public/
kosh serve

Development Mode

When using --dev, the server provides:

Live Reload

  • Browser connects to /events endpoint for Server-Sent Events
  • File changes trigger automatic page reload
  • No browser extensions required

File Watching

Monitors these paths for changes:
  • content/ - Markdown files
  • Template directory (default: themes/<theme>/templates/)
  • Static directory (default: themes/<theme>/static/)
  • kosh.yaml - Configuration file

Fast Rebuilds

  • Incremental builds process only changed files
  • Cache rehydration for template-only changes
  • Debounced rebuilds (500ms delay) to batch rapid changes

Auto baseURL Detection

If baseURL is empty in kosh.yaml, dev mode auto-detects it:
πŸ“ Auto-detected baseURL: http://localhost:2604

Caching Behavior

The server applies different cache headers based on file type:

Hashed Assets (Immutable)

Files with content hashes (e.g., style-a1b2c3d4.css):
Cache-Control: public, max-age=31536000, immutable

HTML Pages (No Cache)

HTML files and directory indexes:
Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
Expires: 0

Other Static Files

Images, fonts, etc.:
Cache-Control: public, max-age=60

Terminal Output

$ kosh serve
🌍 Serving on http://localhost:2604
   (Auto-reload enabled via /events)

404 Handling

When a page is not found, the server:
  1. Returns HTTP 404 status
  2. Serves public/404.html if it exists
  3. Falls back to plain text β€œ404 - Page Not Found”

Security Features

Path Validation

All requested paths are validated to prevent directory traversal attacks:
GET /../../../etc/passwd
β†’ 403 Forbidden: Invalid path

MIME Types

Proper MIME types are set, including:
  • .wasm β†’ application/wasm
  • .css β†’ text/css
  • .js β†’ application/javascript

Graceful Shutdown

The server supports graceful shutdown via:
  • SIGINT (Ctrl+C)
  • SIGTERM
Shutdown sequence:
  1. Stop accepting new connections
  2. Finish processing active requests (5-second timeout)
  3. Stop file watcher
  4. Clean up resources

Troubleshooting

Port Already in Use

# Use a different port
kosh serve --port 3000

Changes Not Reloading

  1. Check browser console for /events connection
  2. Verify watched paths include changed file
  3. Clear browser cache or use incognito mode

Assets Not Loading

Ensure the build completed before serving:
kosh build
kosh serve

Build docs developers (and LLMs) love