# dev

URL: /milo-cli/api/milo/dev/
Section: milo
Description: Hot-reload dev server with smart file watching.

---

> For a complete page index, fetch /milo-cli/llms.txt.

Open LLM text
(/milo-cli/api/milo/dev/index.txt)

Share with AI

Ask Claude
(https://claude.ai/new?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fmilo-cli%2Fapi%2Fmilo%2Fdev%2Findex.txt)

Ask ChatGPT
(https://chatgpt.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fmilo-cli%2Fapi%2Fmilo%2Fdev%2Findex.txt)

Ask Gemini
(https://gemini.google.com/app?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fmilo-cli%2Fapi%2Fmilo%2Fdev%2Findex.txt)

Ask Copilot
(https://copilot.microsoft.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fmilo-cli%2Fapi%2Fmilo%2Fdev%2Findex.txt)

Module

#
`dev`

Hot-reload dev server with smart file watching.

5Classes1Function

## Classes

`_FileWatcher`

2

▼

Base watcher interface.

Base watcher interface.

#### Methods

`watch`

2

▼

`def watch(self, callback: Any, stop_event: threading.Event) -> None`

##### Parameters

Name
Type
Description

`callback`
`—`

`stop_event`
`—`

Internal Methods
1

▼

`__init__`

3

▼

`def __init__(self, dirs: tuple[Path, ...], *, extensions: frozenset[str] | None = None, poll_interval: float = 0.5) -> None`

##### Parameters

Name
Type
Description

`dirs`
`—`

`extensions`
`—`

Default:`None`

`poll_interval`
`—`

Default:`0.5`

`_PollingWatcher`

2

▼

Polling-based watcher (stdlib only, no dependencies).

Polling-based watcher (stdlib only, no dependencies).

#### Methods

`watch`

2

▼

`def watch(self, callback: Any, stop_event: threading.Event) -> None`

##### Parameters

Name
Type
Description

`callback`
`—`

`stop_event`
`—`

Internal Methods
1

▼

`__init__`

2

▼

`def __init__(self, *args: Any, **kwargs: Any) -> None`

##### Parameters

Name
Type
Description

`*args`
`—`

`**kwargs`
`—`

`_WatchfilesWatcher`

1

▼

Rust-based watcher using the ``watchfiles`` package.

Rust-based watcher using the`watchfiles`package.

#### Methods

`watch`

2

▼

`def watch(self, callback: Any, stop_event: threading.Event) -> None`

##### Parameters

Name
Type
Description

`callback`
`—`

`stop_event`
`—`

`_ChangeBatcher`

3

▼

Collects file changes and flushes them after a debounce window.

Collects file changes and flushes them after a debounce window.

#### Methods

`set_callback`

1

▼

`def set_callback(self, callback: Any) -> None`

##### Parameters

Name
Type
Description

`callback`
`—`

`add`

1

▼

`def add(self, paths: list[Path]) -> None`

##### Parameters

Name
Type
Description

`paths`
`—`

Internal Methods
1

▼

`__init__`

1

▼

`def __init__(self, debounce: float = 0.1) -> None`

##### Parameters

Name
Type
Description

`debounce`
`—`

Default:`0.1`

`DevServer`

3

▼

Watches templates and content, re-renders on change.

Tries ``watchfiles`` (Rust-based) for perform…

Watches templates and content, re-renders on change.

Tries`watchfiles`(Rust-based) for performance, falls back to
stdlib polling. Dispatches smart reload actions:

- `@@CSS_RELOAD`for style-only changes

- `@@HOT_RELOAD`for everything else

Usage::

```
dev = DevServer(
    app,
    watch_dirs=("templates", "content", "static"),
    debounce=0.15,
)
dev.run()
```

#### Methods

`run`

0

`Any`

▼

Run app with hot-reload enabled.

`def run(self) -> Any`

##### Returns

`Any`

Internal Methods
2

▼

`__init__`

5

▼

`def __init__(self, app: Any, *, watch_dirs: tuple[str | Path, ...] = (), extensions: frozenset[str] | None = None, poll_interval: float = 0.5, debounce: float = 0.1) -> None`

##### Parameters

Name
Type
Description

`app`
`—`

`watch_dirs`
`—`

Default:`()`

`extensions`
`—`

Default:`None`

`poll_interval`
`—`

Default:`0.5`

`debounce`
`—`

Default:`0.1`

`_on_changes`

1

▼

Dispatch appropriate reload action for changed files.

`def _on_changes(self, paths: list[Path]) -> None`

##### Parameters

Name
Type
Description

`paths`
`—`

## Functions

`_make_watcher`

3

`_FileWatcher`

▼

Try watchfiles first, fall back to polling.

`def _make_watcher(dirs: tuple[Path, ...], *, extensions: frozenset[str] | None = None, poll_interval: float = 0.5) -> _FileWatcher`

##### Parameters

Name
Type
Description

`dirs`
`tuple[Path, ...]`

`extensions`
`frozenset[str] | None`

Default:`None`

`poll_interval`
`float`

Default:`0.5`

##### Returns

`_FileWatcher`
