Live reload
File-watch restarts, the file-set filter, cross-service dependencies, and port reclaiming.
blink restarts a service when its files change, orders startup by declared dependencies, and reclaims stale ports before a service binds. This guide covers the three blocks that drive that behavior, reload, fs, and ports.
Enabling reload
reload.reload enables file-change-driven restart for a service. Without it the service gets no watcher and never restarts on edits.
reload:
reload: trueReload is not implied by the runtime: field, so a plain shell service must set reload: true explicitly. The go, node, and docker runtimes configure this for you, and the docker runtime deliberately leaves it off since compose manages its own containers. When a service has no watcher, blink logs an info-level hint at startup so the silence is not a surprise.
reload_on_delete is a list of globs that restart the service when a matching file is removed, for example an sqlite database file. It works even with reload: false, in which case only deletes restart, not content changes.
reload:
reload: true
reload_on_delete:
- "**/*.sqlite"Choosing which files count
The fs block controls which file changes the watcher reacts to. It is consulted only when reload is enabled.
fs:
extensions: [go, sql]
include:
- ../schema
exclude:
- "**/testdata/**"extensions filters matched files by extension, with the leading dot optional and matching case-insensitive. Empty watches every extension. include adds extra recursive watch roots resolved against the project root, which is how you watch a cross-module path like ../schema that lives outside the service directory. exclude subtracts globs on top of blink's built-in excludes.
Note
blink always excludes .git, node_modules, dist, build, .next, .idea, .vscode, .blink at any depth, plus .DS_Store. A service whose real source lives in a directory literally named build or dist will not be watched there.
Cross-service dependencies
reload_on_service does two things. It orders startup, so the service waits for each listed dependency to reach running (or exited, for a one-shot) before it starts. And it cascades restarts, so whenever a listed dependency restarts, this service restarts too.
reload:
reload_on_service:
- dbIf a listed dependency crashes on boot, the dependent does not hang. It is marked crashed with a diagnostic naming the failed dependency. Unknown dependency names and cycles are rejected at load time.
Reclaiming ports
ports lists the TCP ports a service binds. They feed the port-reclaim step that runs just before the service starts, so a lingering child from a previous run cannot block the new bind.
ports:
- 8080 # literal
- PORT # env-var name, resolved at runtime
- ${API_PORT} # sigil accepted on input, stored as API_PORT
force_shutdown: falseA bare integer is a literal port that must be in the range 1 to 65535. Anything non-numeric is an env-var name, with a ${KEY} or $KEY sigil stripped on input, resolved at runtime from the service env first, then the process environment.
force_shutdown controls the reclaim step. It defaults on project-wide, so a service's declared ports are reclaimed before it starts. Setting it false on a service never reclaims, even when the project default is on. When on, blink sends SIGTERM and then SIGKILL to any process still listening after 150ms, skipping its own process and its parent. The reclaim only does anything when the service also declares ports, and it is best-effort, so a missing lsof or a permission error is logged and never blocks the start.
The exact precedence and field types live in the configuration reference.