GuideOctober 20, 20267 min read

Cross-Platform Config Patterns: macOS + Linux + Windows in One Setup

One ConfigSync account. Three operating systems. Here is how templates, machine tags, and platform-aware modules keep everything consistent while handling the differences.

The Multi-Platform Developer

Many developers work across platforms. Your primary machine runs macOS. Your home server runs Linux. Your gaming PC dual-boots Windows and you occasionally develop there. Or your company issues MacBooks while your CI runs on Linux and some team members use WSL on Windows.

Each platform has different paths, different package managers, different default behaviors. Maintaining separate configurations for each is a maintenance nightmare. ConfigSync lets you manage all three from a single setup, using templates and platform-aware modules to handle the differences.

Platform Detection with Templates

The {{platform}} template variable gives you the operating system. Use it to branch platform-specific sections in your configs:

Platform-aware ~/.zshrc
# Shared aliases (all platforms) alias g="git" alias ll="ls -la" alias ..="cd .." {{#if platform == "darwin"}} # macOS-specific eval "$(/opt/homebrew/bin/brew shellenv)" alias copy="pbcopy" alias paste="pbpaste" alias flushdns="sudo dscacheutil -flushcache" {{/if}} {{#if platform == "linux"}} # Linux-specific alias copy="xclip -selection clipboard" alias paste="xclip -selection clipboard -o" alias open="xdg-open" {{/if}} {{#if platform == "win32"}} # Windows (Git Bash / WSL) alias copy="clip.exe" alias explorer="explorer.exe" {{/if}} # Shared config (all platforms) eval "$(starship init zsh)"

The template resolves at pull time. On macOS, you get Homebrew initialization and pbcopy aliases. On Linux, you get xclip and xdg-open. The shared sections appear on every platform.

Machine Tags for Granular Control

Platform alone is not always enough. WSL is technically Linux but behaves differently. A headless server does not need GUI aliases. Tags give you finer control:

Tag-based cross-platform config
# Tag your machines # configsync machine tag --add macos (MacBook) # configsync machine tag --add linux (home server) # configsync machine tag --add wsl (Windows WSL) # configsync machine tag --add headless (servers without GUI) # In your config: {{#if tags contains "wsl"}} # WSL-specific: access Windows filesystem export WINHOME="/mnt/c/Users/sean" alias cdwin="cd $WINHOME" # Use Windows browser from WSL export BROWSER="wslview" {{/if}} {{#if tags contains "headless"}} # No GUI tools unalias open 2>/dev/null export EDITOR="vim" {{else}} # GUI available export EDITOR="code --wait" {{/if}}
Tags complement platforms. Use {{platform}} for broad OS differences (paths, package managers). Use tags for specific machine characteristics (WSL, headless, GPU, Docker-enabled).

Package Manager Mapping

Different platforms use different package managers for the same tools. ConfigSync's scan command understands this mapping:

ToolmacOS (Homebrew)Ubuntu (apt)Windows (Chocolatey)
ripgrepbrew install ripgrepapt install ripgrepchoco install ripgrep
jqbrew install jqapt install jqchoco install jq
fdbrew install fdapt install fd-findchoco install fd
batbrew install batapt install batchoco install bat

When configsync scan detects your installed tools, it records them in a platform-independent format. On pull, the appropriate package manager command is generated for the target platform. Your Homebrew packages on macOS become apt packages on Linux automatically.

Platform-Aware Modules

Built-in modules handle platform differences automatically. The VS Code module is a good example — it knows that VS Code stores settings in different paths per OS:

VS Code paths per platform
# macOS ~/Library/Application Support/Code/User/settings.json # Linux ~/.config/Code/User/settings.json # Windows %APPDATA%/Code/User/settings.json

You never think about these path differences. Push your VS Code settings from macOS, pull on Linux, and the module places the files at the correct Linux path. The same applies to other cross-platform tools like Git, SSH, npm, and Docker.

Cross-Platform Git Config

Git has subtle platform differences that cause real problems. Line endings, credential helpers, and diff tools differ per OS. Templates handle this cleanly:

~/.gitconfig with platform handling
[user] name = Sean email = {{vars.git_email}} [core] {{#if platform == "darwin"}} autocrlf = input credential helper = osxkeychain {{/if}} {{#if platform == "linux"}} autocrlf = input credential helper = store {{/if}} {{#if platform == "win32"}} autocrlf = true credential helper = manager-core {{/if}} [diff] tool = {{vars.diff_tool}} [alias] co = checkout br = branch st = status lg = log --oneline --graph --decorate

The line ending setting, credential helper, and other OS-specific options are set correctly on each platform. The aliases and user identity are shared everywhere.

One Push, Three Platforms

The workflow is simple: maintain one set of config files with platform conditionals where needed. Push from any machine. Pull on any other machine, regardless of OS. The templates resolve, the modules place files at the right paths, and the package manager mapping installs the right packages. One ConfigSync account, one push, and your Mac, Linux server, and Windows WSL setup all stay in sync.

Ready to try ConfigSync?

Sync your entire dev environment across machines in minutes. Free forever for up to 3 devices.