CLAUDE LABJP
FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as OctoberFORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October
Articles/Claude Code
Claude Code/2026-04-26Intermediate

Should You Flip CLAUDE_CODE_USE_POWERSHELL_TOOL=1? — A Practical Decision Guide for Windows Developers

When you run Claude Code on Windows, you eventually wonder whether CLAUDE_CODE_USE_POWERSHELL_TOOL=1 is worth flipping on. After running both modes across several projects, here is the decision rubric I now use.

claude-code129windows2powershell2wslenvironment3

If you run Claude Code on Windows, this environment variable has probably crossed your radar. Set CLAUDE_CODE_USE_POWERSHELL_TOOL=1 and Claude Code will prefer PowerShell when it executes shell commands internally. Whether that is actually the right move, though, depends a lot on what you are building and where you are running it.

I had occasion recently to use both WSL2 and bare PowerShell on the same Windows 11 box, so I tested this variable across a few projects. The short answer is: it is not a flip-it-on-for-everyone setting. There are clear cases where it helps and clear cases where it just adds friction. This article lays out my decision rubric.

What actually changes

The variable affects which shell Claude Code reaches for when it runs commands. Without any configuration, on a bare Windows host, Claude Code may go through cmd.exe, which can produce odd UTF-8 issues and surprising behavior when running PowerShell scripts (.ps1).

With CLAUDE_CODE_USE_POWERSHELL_TOOL=1 set, Claude Code reaches for PowerShell first (powershell.exe or pwsh.exe). The most visible difference is that Windows-native commands and PowerShell cmdlets like Get-ChildItem execute correctly without translation.

That much is in the docs. What I want to share is what actually happens during day-to-day work that the docs do not cover.

When to turn it on

Across the projects where I have run both, I now flip it on without hesitation in three situations.

First, projects that lean on Windows-only tooling. WPF, WinForms, UWP — anything where you call dotnet or MSBuild — runs more predictably under PowerShell. PATH and environment variable inheritance behave more reliably than via cmd.exe.

Second, when I want Claude Code to author or edit .ps1 scripts. In cmd.exe mode, Claude has to do a translation step to actually execute PowerShell snippets, and you start hitting cases where it hesitates or guesses about how to invoke them.

Third, teams that have already standardized on PowerShell 7 (pwsh) as their primary shell. If you have profile settings like Set-PSReadlineOption you want honored, you want Claude Code launching from inside that environment.

When to leave it off

There are equally clear cases where flipping it on creates more confusion than it solves.

If you do most of your development inside WSL2, the variable does nothing useful. Claude Code running inside WSL is in a Linux process tree — it will use bash or zsh regardless. Setting it inside .bashrc is just confusing future you.

If your toolchain is purely cross-platform — npm, pip, pytest, and friends — the shell choice does not affect behavior. In this case, switching to PowerShell can actually slow things down a touch, since PowerShell has heavier startup than cmd.exe. You feel it in rapid file searches and npm run dev boots.

If you mix WSL and Windows host work in the same session, only setting USE_POWERSHELL_TOOL makes the picture muddier. The actual behavior depends on which parent process started Claude Code, and trying to debug that with one variable in flight is harder than just being explicit about which shell you launched from.

What I observed across three projects

I compared both modes side by side on real work.

Case 1: Next.js front-end (cross-platform). With the variable on, every command spawned PowerShell, so file scans and dev server launches felt fractionally laggier. Off was the better default here.

Case 2: .NET 9 WPF project (Windows-native). With the variable on, dotnet build output came through correctly in UTF-8 and build errors were easier to read. This was a clear win.

Case 3: Python project inside WSL2. The variable made no observable difference. WSL runs bash internally; the Windows-side variable does not propagate. Even when starting WSL from PowerShell explicitly, behavior was unchanged.

How to set it and verify

The conventional way is to set it as a user environment variable.

# Persist (PowerShell)
[Environment]::SetEnvironmentVariable("CLAUDE_CODE_USE_POWERSHELL_TOOL", "1", "User")
 
# Verify
[Environment]::GetEnvironmentVariable("CLAUDE_CODE_USE_POWERSHELL_TOOL", "User")

Close and reopen PowerShell after setting. Then launch Claude Code and try a small command (Get-ChildItem is a good probe) to confirm it executes as a PowerShell cmdlet.

To remove it later:

[Environment]::SetEnvironmentVariable("CLAUDE_CODE_USE_POWERSHELL_TOOL", $null, "User")

Setting it to 0 works as a temporary disable.

Pitfalls when flipping the switch

After turning it on, I had a project where npm run scripts started failing. The cause turned out to be && chained commands in package.json.

{
  "scripts": {
    "build": "tsc && next build"
  }
}

Old Windows PowerShell (5.1 and earlier) does not support &&. PowerShell 7 added it. If your team has anyone still on Windows PowerShell, replace these with npm-run-all or similar.

The other gotcha is path quoting. PowerShell handles spaces in paths differently from cmd.exe. Claude Code usually quotes correctly, but it can slip. When in doubt, be explicit: & "path with space\app.exe".

A simple decision checklist

A short rubric I now run through:

You write .ps1 scripts. You build on Windows-native SDKs (dotnet, MSBuild). You launch Claude Code directly from Windows Terminal. You want PowerShell profile settings honored.

If two or more of these are true, give it a try.

You live in WSL2. You write only Node/Python cross-platform scripts. You notice startup latency.

If you fall into this group, leave it off.

Personally, my main work happens in WSL2, but when I write small Windows-native utilities, I set $env:CLAUDE_CODE_USE_POWERSHELL_TOOL=1 per session rather than persisting it. Per-session toggling has caused me less confusion than a global flag.

When in doubt, flip it on for a day, see how it feels, and revert if anything is off. It is a low-stakes setting to experiment with.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Claude Code2026-04-21
When Bash Misbehaves in Claude Code on Windows — A Practical Note on CLAUDE_CODE_USE_POWERSHELL_TOOL=1
On Windows, Claude Code's Bash-based shell tool sometimes fails in odd ways. Setting CLAUDE_CODE_USE_POWERSHELL_TOOL=1 routes commands through PowerShell and removes many of the symptoms. Here are the practical trade-offs I've seen after living with the switch.
Claude Code2026-05-14
Claude Code Doesn't Recognize nvm/pyenv/asdf — Shell Initialization and 4 Fixes
Fix 'node: command not found' and Python version mismatches in Claude Code when using nvm, pyenv, or asdf. Learn why shell initialization is skipped and how to solve it for good.
Claude Code2026-07-17
The Morning My Table Ended in "… 2,847 more rows" — Separating Render Caps from Token Cost in Tool Output
Claude Code 2.1.209 caps markdown tables at 200 rows plus a remainder count. Only the rendering is capped — the model still receives every row. Here is how to measure the gap and redesign tool output around aggregates.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →