Fluxta

Development

Build, link, restart, and read the logs.

Day to day, one command covers the loop:

pnpm dev

The rest of this page is what that command does on your behalf, and what to reach for when you need to step outside it.

How the loop works

pnpm dev starts two watchers — one for the background process, one for the editor — and each rebuilds into dist/<your-plugin-id>/. That folder is the plugin: manifest, code, and editor assets in the shape Fluxta loads.

After every successful background-process build, the watcher runs fluxta restart, which does two things:

  1. Points Fluxta at dist/<your-plugin-id>/ with a development link, so the app loads that build instead of any installed copy of the same plugin.
  2. Restarts the plugin's process and waits for it to come back up.

Saving a .ts file in the background process is therefore enough: Fluxta is already running the new code.

Editors do not restart the process

The editor is static files. When it rebuilds, nothing needs restarting — Fluxta picks up the new assets the next time it opens that iframe. An editor left open while it rebuilds keeps showing the old bundle until it is closed and reopened.

Reading the logs

The background process has no console of its own, so console.log and console.error are how to see what it is doing. Both are captured to a file inside the plugin folder:

tail -f dist/<your-plugin-id>/logs/<your-plugin-id>.log

stdout is recorded as info, stderr as errors.

A full build deletes the logs

pnpm build clears dist/ before rebuilding, and the log file lives inside it. pnpm dev does not, so a running loop keeps its log.

Plugin status

Fluxta reports one status per plugin:

StatusWhat it means
AvailableThe plugin loaded. It either needs no background process, or one has not started yet.
StartingThe process was launched and has not connected yet.
RunningThe process is up and connected. This is the normal state.
DisconnectedThe process is alive but its connection to Fluxta dropped.
StoppedThe process exited normally.
ErrorThe plugin failed to load, or the process exited with an error.

A crashed process is not restarted automatically. A dead plugin stays dead until it is rebuilt or restarted, so that a crash loop cannot hide.

Commands

CommandWhat it does
pnpm buildA clean, full build of dist/<your-plugin-id>/. Owned by your project, not the CLI.
pnpm typecheckType-checks both halves without building.
pnpm lintRuns ESLint. fluxta publish runs this too and stops if it fails.
pnpm formatRewrites files with Prettier. publish runs format:check and stops if it fails.
fluxta linkRegisters an existing build folder as a development link, without building.
fluxta restartRefreshes the link and restarts the process. What the dev loop calls.
fluxta startStarts a stopped plugin.
fluxta stopStops a running plugin.
fluxta unlinkRemoves the development link and restores the installed copy, if there is one.
fluxta validateChecks the project and build output against everything publishing requires.

The CLI never builds. If a command needs a build folder and cannot find a valid one, fix the build and run pnpm build again.

Fluxta has to be running

Anything that touches the app — link, restart, start, stop, unlink — needs Fluxta already running; the CLI does not launch it. If it is not running, the command says so. A build still succeeds; only the restart step is skipped.

Several plugins at once

A development link is per plugin, and links persist across restarts of Fluxta. Several plugins can be linked at once — run pnpm dev in each project.

If a link's build folder goes missing or becomes invalid, Fluxta reports the link as broken and refuses to fall back to the installed copy of that plugin. Silently running installed code while you believe you are testing your own is the worse outcome. Fix the build folder, or run fluxta unlink to hand the plugin back to its installed version.

Build output rules

Two rules catch most people:

  • Bundle everything. Fluxta runs the background process with its own Node runtime and does not install node_modules in the plugin folder. The entry file must be a self-contained ES module. The generated project already does this.
  • Keep editor paths relative. The editor is served from a nested path, so its bundle must not reference assets with absolute / paths. With Vite that means base: "./", which the generated project already sets.

Get either wrong and the plugin loads but does nothing visible — see Troubleshooting.

On this page