Module

server.dev_server

Development server with file watching and hot reload.

Classes

DevServer
Development server with file watching and auto-rebuild. Provides a complete development environmen…
11

Development server with file watching and auto-rebuild.

Provides a complete development environment for Bengal sites with:

  • HTTP server for viewing the site locally
  • File watching for automatic rebuilds
  • Graceful shutdown handling
  • Stale process detection and cleanup
  • Automatic port fallback
  • Optional browser auto-open

The server performs an initial build, then watches for changes and automatically rebuilds only what's needed using incremental builds.

Features:

  • Incremental + parallel builds (5-10x faster than full builds)
  • Beautiful, minimal request logging
  • Custom 404 error pages
  • PID file tracking for stale process detection
  • Comprehensive resource cleanup on shutdown

Methods 1

start
Start the development server with robust resource cleanup. This method: 1. Che…
0 None
def start(self) -> None

Start the development server with robust resource cleanup.

This method:

  1. Checks for and handles stale processes
  2. Prepares dev-specific configuration
  3. Performs an initial build
  4. Creates HTTP server (with port fallback if needed)
  5. Starts file watcher (if enabled)
  6. Opens browser (if requested)
  7. Runs until interrupted (Ctrl+C, SIGTERM, etc.)

The server uses ResourceManager for comprehensive cleanup handling, ensuring all resources are properly released on shutdown regardless of how the process exits.

Internal Methods 10
__init__
Initialize the dev server.
6 None
def __init__(self, site: Any, host: str = DEFAULT_DEV_HOST, port: int = DEFAULT_DEV_PORT, watch: bool = True, auto_port: bool = True, open_browser: bool = False) -> None

Initialize the dev server.

Parameters 6
site Any

Site instance

host str

Server host

port int

Server port

watch bool

Whether to watch for file changes

auto_port bool

Whether to automatically find an available port if the specified one is in use

open_browser bool

Whether to automatically open the browser

_prepare_dev_config
Prepare site configuration for development mode. Sets development-specific def…
0 bool
def _prepare_dev_config(self) -> bool

Prepare site configuration for development mode.

Sets development-specific defaults:

  • Disables asset fingerprinting (stable URLs for hot reload)
  • Disables minification (faster rebuilds, easier debugging)
  • Clears baseurl (serves from root '/' not subdirectory)

When baseurl is cleared, also clears the build cache to prevent stale baseurl values from persisting in cached data.

Returns

bool

True if baseurl was cleared (requires clean rebuild)

_get_watched_directories
Get list of directories that will be watched.
0 list[str]
def _get_watched_directories(self) -> list[str]

Get list of directories that will be watched.

Returns

list[str]

List of directory paths (as strings) that exist and will be watched

_create_observer
Create file system observer (does not start it).
1 Any
def _create_observer(self, actual_port: int) -> Any

Create file system observer (does not start it).

Parameters 1
actual_port int

Port number to display in rebuild messages

Returns

Any

Configured Observer instance (not yet started)

_is_port_available
Check if a port is available for use.
1 bool
def _is_port_available(self, port: int) -> bool

Check if a port is available for use.

Parameters 1
port int

Port number to check

Returns

bool

True if port is available, False otherwise

_find_available_port
Find an available port starting from the given port.
2 int
def _find_available_port(self, start_port: int, max_attempts: int = 10) -> int

Find an available port starting from the given port.

Parameters 2
start_port int

Port to start searching from

max_attempts int

Maximum number of ports to try

Returns

int

Available port number

_check_stale_processes
Check for and offer to clean up stale processes. Looks for a PID file from a p…
0 None
def _check_stale_processes(self) -> None

Check for and offer to clean up stale processes.

Looks for a PID file from a previous Bengal server run. If found, verifies the process is actually a Bengal process and offers to terminate it gracefully.

_create_server
Create HTTP server (does not start it). Changes to the output directory and cr…
0 tuple[socketserver.…
def _create_server(self) -> tuple[socketserver.ThreadingTCPServer, int]

Create HTTP server (does not start it).

Changes to the output directory and creates a TCP server on the specified port. If the port is unavailable and auto_port is enabled, automatically finds the next available port.

Returns

tuple[socketserver.ThreadingTCPServer, int]

Tuple of (httpd, actual_port) where httpd is the TCPServer instance and actual_port is the port it's bound to

_print_startup_message
Print server startup message using Rich for stable borders. Displays a beautif…
1 None
def _print_startup_message(self, port: int) -> None

Print server startup message using Rich for stable borders.

Displays a beautiful panel with:

  • Server URL
  • Output directory being served
  • File watching status
  • Shutdown instructions
Parameters 1
port int

Port number the server is listening on

_open_browser_delayed
Open browser after a short delay (in background thread). Uses a background thr…
1 None
def _open_browser_delayed(self, port: int) -> None

Open browser after a short delay (in background thread).

Uses a background thread to avoid blocking server startup.

Parameters 1
port int

Port number to include in the URL