Cross-platform scripts
When a project targets users on Windows, macOS, and Linux all at once, the choice of tool for automation scripts becomes a recurring question. There is no single right answer — environment constraints and team familiari…
Table of contents
When a project targets users on Windows, macOS, and Linux all at once, the choice of tool for automation scripts becomes a recurring question. There is no single right answer — environment constraints and team familiarity steer the pick.
1. bash everywhere + Git Bash · WSL guidance
Write all automation in bash and tell Windows users to run it inside Git Bash (bundled with Git for Windows) or WSL2.
- Pros — most natural on macOS · Linux. Plenty of online material. Standard shell tools (
grep,awk,sed) are right there. - Cons — extra installs for native Windows users. Path mismatches (
/c/Users/...vsC:\Users\...). Won't run directly under cmd or PowerShell. - Good fit — backend, data, and DevOps-centric teams.
2. Node-based scripts
Write automation on top of Node.js. JavaScript/TypeScript front-end projects already have Node, so there is little extra dependency.
Notable tools:
zx(Google) — a Node library for running commands with a bash-like feel. Syntax such asawait $\ls``.tsx— runs TypeScript files directly.tsx scripts/build.ts.- Plain
.mjs— no external deps, just ESM.node scripts/clean.mjs.
// scripts/clean.mjs
import { rm } from "node:fs/promises";
await rm("dist", { recursive: true, force: true });
console.log("cleaned");
The strength is OS abstraction in the standard library (fs, path, os). The downside is that without Node nothing runs, and non-CLI work can balloon in code volume.
3. PowerShell 7+
PowerShell 7+ runs on Windows, macOS, and Linux. Object pipes and the .NET library underneath.
- Pros — most natural for Windows users. Rich admin/automation cmdlets. 7+ is genuinely cross-platform.
- Cons — a separate install for macOS and Linux users (
brew install powershell,apt install powershell). The shell itself has lower mindshare in the Unix camp. - Good fit — Windows-led teams adding macOS · Linux compatibility.
4. Python scripts
Python ships a thick standard library with solid OS abstractions (pathlib, subprocess, shutil).
- Pros — broad standard library. Readable. Data, HTTP, file handling each fit on a single line.
- Cons — needs the interpreter and version management (virtual envs). For simple command launching, the code is longer than a shell line.
- Good fit — projects already centered on Python, or scripts dealing with data and networking.
5. Make · Just
make is the classic Unix build automation tool. just is a modern simplification of the same idea.
make— bundled on macOS · Linux. Windows needs a separate install (MSYS2, GnuWin). Makefile tab/space syntax is finicky.just— written in Rust. A flat command collection without dependency graphs. Friendlier to cross-platform thanmake.cargo install justorbrew install just.
# Makefile
build:
npm run build
test:
npm test
# justfile
build:
npm run build
test:
npm test
The strength is gathering commands in one file. The downside is that internally each rule still calls a shell command, so OS differences come back.
6. package.json scripts
For JS · TS projects, package.json's scripts is the de facto entry point.
{
"scripts": {
"dev": "next dev",
"build": "next build",
"lint": "eslint ."
}
}
Works under npm, pnpm, or yarn. Calls tools from node_modules/.bin without global installs. OS-sensitive commands get smoothed with helpers like cross-env (env vars), rimraf (directory removal), or npm-run-all.
Once a scripts entry grows long, splitting it out into zx or a separate .mjs becomes friendlier to maintenance.
7. Comparison summary
| Approach | Windows fit | macOS · Linux fit | Extra install | Suitable scale |
|---|---|---|---|---|
| bash | Moderate (Git Bash needed) | High | Git Bash · WSL | Any size |
Node (zx, .mjs) |
High | High | Node | Small to medium |
| PowerShell 7 | High | Moderate | pwsh | Small to medium |
| Python | High | High | Python | Medium to large |
| Make | Moderate | High | (separate on Windows) | Small to medium |
| Just | High | High | just binary | Small to medium |
8. The same task in four flavors
# bash
rm -rf dist
# PowerShell
Remove-Item -Recurse -Force dist -ErrorAction SilentlyContinue
// Node .mjs
import { rm } from "node:fs/promises";
await rm("dist", { recursive: true, force: true });
# Python
import shutil; shutil.rmtree("dist", ignore_errors=True)
9. Common pitfalls
bash scripts saved with CRLF break on Linux — declare *.sh text eol=lf in .gitattributes.
Node scripts hard-coding "a/b/c" instead of path.join — works on Windows but logs and outputs look off.
Calling pwsh assuming PowerShell 7+ is installed when only 5.1 is — detect first and guide.
Makefiles indented with spaces breaking make — Make requires literal tabs.
Calling && from PowerShell 5.1 (instead of cmd) on Windows — parser error.
Closing thoughts
There is no single right answer for cross-platform scripts. The team's environment mix (Windows · Unix) and the project's nature (front-end · backend · data) decide. Either keeping three OS-equivalent scripts side by side or unifying on a Node .mjs set are the two shapes that show up most often.
Next
- markdown
- text-encoding-line-endings
google/zx · tsx · PowerShell install · casey/just · npm Docs scripts for reference.
Terms in this content
More in environment
All in this category →Related posts
Windows vs macOS dev environment
Even with the same language and the same code, the basics like paths, line endings, shells, and permissions shift once the operating system changes. Linux falls on the macOS side of this split (both are Unix-flavored).
Cross-platform Mobile — Comparing the Candidates
The desire to build the same app for iOS, Android, and the web from a single codebase has been around for a long time. The tools that emerged as answers picked different approaches in different eras. Some sit on top of…
Hooks and Settings — wiring external behavior into tool execution
There are places where you want external behavior to run before or after an LLM agent's tool call. Auto-formatter execution, change watching, logging, policy validation, secret-leak blocking — that kind of work.
AI workflow tools — n8n · Dify · LangFlow · Flowise · Make · Zapier
Beyond using LLMs as one-shot calls, more tools bundle multi-step automation and integration flows. The strands vary — connecting nodes without writing code (GUI), or self-hosting to keep operational control.