bun/no-console-window-flash

Require windowsHide for a child process that does not share a stream with its parent

On Windows, a child process started from an app without a console gets its own console window. The window opens and closes again as the process runs, which users see as a black flash. windowsHide: true prevents it and has no effect on other systems.

The rule looks at exec, execSync, execFile, execFileSync, spawn, and spawnSync from node:child_process, and at Bun.spawn and Bun.spawnSync.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"bun/no-console-window-flash" = "error" # or "warn"

Examples#

example.js1 problem
import { execFile } from "node:child_process";

execFile("git", ["status", "--short"], (error, stdout) => {
  show(stdout);
});
example.js1 problem
const git = Bun.spawn(["git", "status", "--short"], { stdout: "pipe" });
example.jsNo problems
import { execFile } from "node:child_process";

execFile("git", ["status", "--short"], { windowsHide: true }, (error, stdout) => {
  show(stdout);
});

const git = Bun.spawn(["git", "status", "--short"], { stdout: "pipe", windowsHide: true });

A process that inherits a stream writes to its parent's terminal, so it isn't reported. Any value for windowsHide counts, because writing false is a deliberate choice. Options that aren't an object literal in the call, or that spread another object, aren't checked:

example.jsNo problems
import { spawn } from "node:child_process";

spawn("bun", ["test"], { stdio: "inherit" });
spawn("bun", ["test"], { stdio: ["ignore", "inherit", "pipe"] });
spawn("notepad", [file], { windowsHide: false });
spawn("bun", ["test"], options);
spawn("bun", ["test"], { ...options, cwd });

When not to use it#

Code that never runs on Windows doesn't need the option.