DEV Community

Cover image for Batch .bat in 2026: Legacy Glue, Not a Personality
arnostorg
arnostorg

Posted on

Batch .bat in 2026: Legacy Glue, Not a Personality

I still write .bat files in 2026. I also refuse to build an identity around them. That distinction—legacy glue vs personality—is the retrospective I wish someone had handed me earlier.

Where .bat still appears (unironically)

  • Vendor installers and unwrap scripts.
  • Scheduled tasks authored a decade ago that still pay the bills.
  • Tiny wrappers that set env vars and launch something else.
  • Locked images where PowerShell scripts are political and CMD isn’t.

If your job touches Windows estates, you will read batch. Pretending otherwise is aesthetic, not operational.

What I no longer use batch for

  • Nontrivial logic (nested delayed expansion temples).
  • JSON / HTTP workflows.
  • Anything that needs testable functions and clear error objects.
  • Team-shared automation when PowerShell is available.

Writing clever batch to prove cleverness is a personality choice. Production doesn’t owe you applause.

Glue patterns that aged okay

Thin wrapper:

@echo off
setlocal
set APP_ENV=prod
"C:\Program Files\App\app.exe" %*
exit /b %ERRORLEVEL%
Enter fullscreen mode Exit fullscreen mode

Explicit failure:

some-tool.exe || exit /b 1
Enter fullscreen mode Exit fullscreen mode

Boring. Copyable. Reviewable.

Retrospective rules I keep

  1. Prefer PowerShell (or a real language) for new automation when the environment allows.
  2. Keep batch short when you must maintain it—delegate to something saner quickly.
  3. Comment the why, especially quoting and setlocal choices.
  4. Don’t teach batch as a first language for beginners beyond survival file ops and reading existing glue.

Teaching without contempt

Calling batch “ancient trash” shames juniors who just opened a vendor script. Calling it “beautiful” traps them in a cul-de-sac. Better: classify it as glue. You learn enough to untangle it, then you graduate.

Reading legacy batch without drowning

When you inherit a 400-line .bat:

  1. Find the entry points and goto labels.
  2. Note every setlocal / endlocal.
  3. Track ERRORLEVEL after external calls.
  4. Extract the “real work” (usually one .exe with flags).
  5. Decide whether to wrap, rewrite, or quarantine.

Often the right 2026 move is a PowerShell rewrite plus a one-line .bat shim for callers that still expect a .bat path. Glue on the outside, sense on the inside.

Personality check

If you enjoy delayed-expansion puzzles more than shipping the installer’s outcome, notice that. Fascination is fine; production ownership is a different scoreboard.

Compatibility shim pattern

@echo off
pwsh -NoProfile -File "%~dp0tools\task.ps1" %*
exit /b %ERRORLEVEL%
Enter fullscreen mode Exit fullscreen mode

Callers keep a .bat path; logic lives in something testable. That’s legacy glue with a 2026 brain—not a personality built out of goto.

When rewrite is the wrong first move

If a .bat is called from fifteen undocumented scheduled tasks, a clever rewrite without inventory is how you create an outage. Inventory callers, add logging, shim carefully, then rewrite the core. Legacy glue rewards patience more than contempt.

Documentation stub worth pasting above legacy scripts

REM Owner: platform-team
REM Purpose: thin launcher only — logic in tools\task.ps1
REM Last verified: 2026-09
Enter fullscreen mode Exit fullscreen mode

Three lines prevent the next engineer from assuming the .bat is the product.

Glue is honorable when it’s thin, labeled, and temporary-by-intent—even if temporary lasts years.

That framing matches how I sequence Windows CLI practice in CMD Master: respect the artifact, don’t romanticize the dialect.

What I disabled in my own habits

  • Clever goto forests.
  • Environment mutation without setlocal.
  • Silent error ignoring.
  • Using batch where a checked-in PowerShell task would be clearer for the team.

.bat in 2026 is a compatibility surface. Use it like duct tape: proud when it holds, eager to replace it when you can engineer a joint.

Top comments (0)