How I use a single .zshrc file on macOS and Windows (WSL2)

Lobsters Hottest Tools

Summary

The article details a method to maintain a single .zshrc file for both macOS and Windows (WSL2) by using conditional logic for OS-specific behaviors, such as SSH and path commands, to simplify cross-platform shell configuration.

<p><a href="https://lobste.rs/s/9ukost/how_i_use_single_zshrc_file_on_macos">Comments</a></p>
Original Article
View Cached Full Text

Cached at: 09/14/26, 09:05 PM

# How I use a single .zshrc file on macOS and Windows (WSL2) Source: [https://talkoren.com/blog/single-zshrc-macos-windows-wsl2](https://talkoren.com/blog/single-zshrc-macos-windows-wsl2) Ever since The Matrix came out in 1999, I've been into command line interfaces\. The feeling of knowing how to navigate your way around verbose interfaces has its magic \(which is also part of the reason why I like CSS, vim and RegEx\)\. Today I have 3 machines \- my personal MacBook Pro, and two desktop Windows gaming PCs \(long story, don't ask\)\. Being the CLI geek that I am, I started playing around with WSL back in 2016 \(and afterwards WSL2, which runs an actual Linux kernel inside a lightweight virtual machine\)\. Since then I've been a huge Z shell \(zsh\) user, and I use it across all my machines\. I'm using[chezmoi](https://chezmoi.io/)to manage my dotfiles, and \.zshrc among them\. Using zsh on WSL and macOS may seem trivial because both give me a Unix\-like environment, but there are some differences when it comes to core OS behavior, like using ssh or having convenience commands like`open`\. Therefore, maintaining separate`\.zshrc\.mac`and`\.zshrc\.wsl`files would inevitably make them drift apart, and as a developer with ADHD, I know it's just a matter of time until I update one and forget the other\. Hence my rule for managing this was to have a file that's shared by default, and conditional when the OS actually matters\. ## Cutting to the chase First, I need to know whether the shell is running inside WSL: ``` if grep -qi microsoft /proc/version 2>/dev/null; then IS_WSL=1 fi ``` I set the`IS\_WSL`variable to distinguish between the operating systems\. The`q`flag is for quiet \(we don't want the`grep`output to print every time a shell starts\), and`i`makes the check case\-insensitive, so it does not depend on how Microsoft is capitalized\. On macOS,`/proc/version`doesn't exist, but the error is redirected to`/dev/null`, so the condition simply fails\. ## SSH I use the 1Password ssh agent to avoid keeping my private keys in`~/\.ssh`\(sorry AI agents and supply chain attackers\), and it's supported in macOS, Linux, and Windows\. This distinction matters because the 1Password ssh agent runs as part of the Windows app and not inside WSL\. In my setup, WSL uses Windows' ssh client so it can talk to the 1Password agent running on Windows\. After[configuring 1Password](https://www.1password.dev/cli/get-started#step-2-turn-on-the-1password-desktop-app-integration)to enable me to use their CLI and configuring the[ssh agent](https://www.1password.dev/ssh/agent), all I had to do was: ``` if [ "$IS_WSL" = 1 ]; then alias ssh='ssh.exe' alias ssh-add='ssh-add.exe' fi ``` This works, but there's a slight issue with git here \- the`ssh`alias only exists inside my interactive zsh session\. When Git launches ssh itself, that alias isn't involved, so I also need to set[`GIT\_SSH\_COMMAND`](https://git-scm.com/docs/git#Documentation/git.txt-GITSSHCOMMAND)to ssh\.exe\. The same is true for`scp`\. The resulting conditional in that case, is: ``` if [ "$IS_WSL" = 1 ]; then alias ssh='ssh.exe' alias ssh-add='ssh-add.exe' alias scp='scp.exe' export GIT_SSH_COMMAND='ssh.exe' fi ``` Now I can handle all ssh\-related operations across macOS and WSL\. ## Using Finder and Explorer On macOS,`open \.`opens the current directory in Finder\. In WSL,`explorer\.exe \.`does roughly the same thing in Windows Explorer\. You see where this is going\.\.\. Since`open`is already a system command on macOS, I only need to overwrite it when using WSL on Windows: ``` open() { explorer.exe "$(wslpath -w "${1:-.}")" 2>/dev/null } ``` `wslpath \-w`converts the WSL path to Windows format, while`$\{1:\-\.\}`defaults to the current directory if no path is provided\. And since this is irrelevant to macOS, it makes sense to only set it under WSL, making our conditional: ``` if [ "$IS_WSL" = 1 ]; then alias ssh='ssh.exe' alias ssh-add='ssh-add.exe' alias scp='scp.exe' export GIT_SSH_COMMAND='ssh.exe' open() { explorer.exe "$(wslpath -w "${1:-.}")" 2>/dev/null } fi ``` ## Simplicity equals sanity The result is one \.zshrc that behaves like a native configuration on both systems\. Most of it stays shared, and the handful of Windows\-specific differences remain visible in one small conditional\. Predictable, readable, and sane to maintain \(mainsane?\)\.

Similar Articles

@ChrisWangwy: https://x.com/ChrisWangwy/status/2064589910485684254

X AI KOLs Timeline

Microsoft has released Coreutils for Windows, bringing 78 Unix-like commands to the native Windows terminal, enabling AI agents (such as Hermes, Claude Code) to use commands like grep and ls directly on Windows, reducing translation overhead. The article details installation steps, alias conflicts, and acceptance methods.

Microsoft’s new developer-optimized Windows embraces Linux even more

The Verge

Microsoft announced a developer-optimized Windows 11 experience at Build, including Coreutils for Windows (native Linux-like utilities), WSL containers for easy Linux container management, an experimental Intelligent Terminal with AI integration, and Windows Developer Configurations for quick setup.

A tale of two path separators (2021)

Lobsters Hottest

Explains how macOS handles two path separators (slashes and colons) due to its dual heritage from classic Mac OS and NeXTSTEP, and how this leads to files appearing with slashes in Finder but colons in the terminal.

@justloveabit: https://x.com/justloveabit/status/2053659118175715713

X AI KOLs Timeline

The Hermes AI agent tool now supports native Windows installation without requiring WSL, allowing Windows users to run CLI tools and bots directly. This article reviews the Early Beta experience, outlines the installation process, and compares it with the WSL2 version.