Skip to main content
fyrer can run multiple dev servers simultaneously, streaming each server’s logs in a unified TUI. This guide shows how to configure persistent tasks for your dev servers and manage their dependencies so everything starts in the right order.

What is a persistent task?

Setting persistent: true on a task marks it as long-running. fyrer keeps it alive until you explicitly quit — unlike normal tasks, persistent tasks never exit on their own. This makes them the right choice for dev servers, watchers, and any other process you want running in the background while you work.

Basic dev server setup

The example below shows a typical frontend + backend monorepo. ui:build is a normal cacheable task that must finish before web:dev starts; api:dev runs independently.
fyrer.yml

Starting all dev servers

Run the dev task across every package that defines one:
fyrer resolves the dependency graph, runs ui:build first, and then launches web:dev and api:dev concurrently once their prerequisites are satisfied.

Dependency ordering with persistent tasks

fyrer executes the task graph level by level — all tasks at the same graph level run concurrently, and a level must complete before the next one starts. Because persistent tasks never exit, they block all later graph levels. This means:
  • If web:dev and api:dev have no dependencies between them, they occupy the same graph level and start concurrently. ✅
  • If any task lists a persistent task in its depends_on, that task will wait forever and never start. ❌
Keep dev servers as leaves of the dependency graph — nothing should depend on them.
Do not add a depends_on entry that points to a persistent task. Because the persistent task never exits, any task waiting for it will never start and will block the entire run.

TUI navigation

While dev servers are running, fyrer’s interactive TUI lets you inspect each one:

Plain mode for scripts

To run dev servers without the TUI — for example inside a terminal multiplexer or a script — pass the -n flag:
In plain mode each log line is prefixed with [package:task] and colorized by package, making it easy to tell servers apart in a shared terminal session.