Why browsers work while PowerShell, Git, and npm do not
On Windows, most people discover Clash through a GUI that offers a convenient toggle for system proxy. When that toggle is on, compliant desktop applications read the WinHTTP or WinINET proxy configuration and send HTTP(S) traffic through the loopback listener that Clash exposes. Microsoft Edge and Google Chrome typically cooperate with those settings, which is why it feels unfair when PowerShell, Git, or npm still behave as if nothing changed. The short explanation is that system proxy is not the same thing as process environment variables such as http_proxy or HTTPS_PROXY, and many command-line tools either ignore the system proxy entirely or consult a different configuration path first.
Another layer of confusion comes from the word proxy itself. In Clash documentation you will see mixed port, HTTP port, and SOCKS port mentioned side by side. Some tools speak HTTP CONNECT fluently; others insist on SOCKS5; still others read only ALL_PROXY and expect a socks5:// scheme. If you aim the wrong scheme at the wrong listener, you will get instant failures that look like generic network timeouts rather than a clear schema mismatch. The goal of this article is to give you a repeatable mental model: identify the listener you actually enabled in Clash, map it to the variable names your tools honor, and verify with small tests before you touch large installs.
This walkthrough intentionally stays in the per-user shell environment lane. You do not need a new TUN profile, you do not need administrator rights for basic HTTP proxying to loopback, and you do not need to re-architect your entire routing table just to make git clone reliable. When you eventually want system-wide capture for UDP-heavy apps or stubborn binaries, our Clash TUN on Windows article covers the firewall and routing angles. Here we focus on the developer-shaped problem: terminals, package managers, and repository traffic that should ride your existing Clash policy groups.
Mixed port versus dedicated SOCKS: what to type
In modern Clash and mihomo setups, the mixed port is a single TCP listener that multiplexes compatible HTTP and SOCKS clients. Practically, that means you can often standardize on one loopback port—frequently 7890 in fresh profiles, though your packager may choose another value—and point both http://127.0.0.1:7890 style URLs and socks5://127.0.0.1:7890 style URLs at the same numeric port. That convenience is exactly why mixed ports show up in so many screenshots and starter YAML files: fewer moving parts, fewer firewall prompts, and fewer mismatches between a browser extension and a terminal session.
When a profile also exposes separate HTTP and SOCKS listeners, purists sometimes split traffic so that each stack uses the narrowest endpoint. That is valid, but it increases cognitive load. If you are troubleshooting timeouts, start with the mixed port unless you have a concrete reason not to. Git over https:// uses HTTP CONNECT semantics; npm uses HTTP as well; most corporate inspection and TLS middleboxes sit on the HTTP path. SOCKS still matters when a tool insists on it, yet many Node-based utilities will happily use an HTTP proxy variable if you give them a URL they understand.
Whatever port you choose, prefer 127.0.0.1 over the bare word localhost on Windows when you are scripting. localhost can resolve to IPv6 ::1 first depending on NIC order, prefix policies, and hosts file customizations, while your Clash listener might temporarily be IPv4-only during experiments. The mismatch produces maddening intermittent failures: the same command works after a reboot, then breaks again after a VPN session toggles interface metrics. Loopback numeric literals are boring and reliable.
Verify what Clash is actually listening on
Before you export variables, open your Clash-compatible GUI—for example Clash Verge Rev—and read the ports panel carefully. Confirm the mixed port value, confirm whether Allow LAN is enabled, and confirm you did not randomize the port in an advanced YAML override. If you are sharing the listener with phones on the same Wi-Fi, our LAN proxy walkthrough explains firewall rules and bind addresses; for local-only developer traffic you still want to see a green indicator that the core is running and the listener is not colliding with another service.
Quick sanity checks from PowerShell help separate Clash is down
from my variables are wrong.
A lightweight approach is to call Test-NetConnection 127.0.0.1 -Port 7890 with your real port substituted. If the TcpTestSucceeded field is false while Clash claims to be online, you are chasing the wrong abstraction—fix the listener first. If the port test succeeds yet Git still hangs, you almost certainly have an application-level bypass, a stale NO_PROXY entry, or a tool-specific configuration that overrides the environment.
PowerShell: set http_proxy for the current user session
PowerShell inherits environment variables from the Windows user session and applies its own profile scripts on top. For an immediate experiment, assign the common trio in the same window where you plan to run Git or npm. Use uppercase names for compatibility with cross-platform documentation, even though Windows is historically case-insensitive: $env:HTTP_PROXY="http://127.0.0.1:7890", $env:HTTPS_PROXY="http://127.0.0.1:7890", and optionally $env:ALL_PROXY="socks5://127.0.0.1:7890" when you know the downstream tool prefers SOCKS. Many Node utilities read HTTPS_PROXY for TLS tunnels; omitting it while only defining HTTP_PROXY is a classic partial configuration.
Also set NO_PROXY thoughtfully. A practical starter value is 127.0.0.1,localhost plus any corporate registry hosts that must never leave your direct path. If you wildcard too aggressively, you will accidentally exempt exactly the host you meant to accelerate. If you leave NO_PROXY empty while pointing everything at Clash, some local dashboards and device portals may break until you add exceptions. Treat NO_PROXY like a firewall allowlist: explicit beats clever.
After exporting variables, verify with a network-aware command that respects them. curl.exe is present on current Windows builds and provides clearer error messages than many wrappers. A HEAD request to a well-known HTTPS endpoint should return quickly when the chain is healthy. If curl.exe succeeds while Git still fails, you have already proven that Clash and the port are fine—the remaining work is inside Git configuration or authentication, not inside the tunnel itself.
Persist variables for your user without touching other accounts
Interactive assignments with $env: disappear when the window closes. That is good for experiments and bad for productivity. To persist for your user only, write the same names through the System Properties environment dialog or use [Environment]::SetEnvironmentVariable in PowerShell with scope User. Sticking to per-user scope respects the constraint only current user from support threads where administrators do not want machine-wide proxy surprises for unrelated accounts.
Remember that newly launched terminals read persisted values, while already-open IDEs sometimes cache an older environment until you restart them. Visual Studio Code terminals inherit the parent process environment captured at launch; JetBrains terminals behave similarly. If you update variables and nothing changes inside an embedded terminal, fully quit the IDE once instead of toggling random internal proxy knobs first.
Git: align http.proxy, https.proxy, and URL remotes
Even with correct environment variables, Git maintains its own configuration keys. Many teams therefore set both layers during onboarding: shell variables for tools that read them, and Git keys for repositories. Use git config --global http.proxy http://127.0.0.1:7890 and git config --global https.proxy http://127.0.0.1:7890 with your port substituted. If you only clone over https://, that pair covers the majority of GitHub, GitLab, and Azure DevOps scenarios.
SSH remotes are a different animal. When the remote URL starts with [email protected]:, traffic flows over port 22 as SSH rather than HTTP CONNECT through your mixed port. Users who switch remote URLs from SSH to HTTPS often see instant improvement in restrictive networks because HTTPS rides the proxy path you already tuned. Conversely, if you must stay on SSH, you need an SSH-aware tunnel or ProxyCommand wiring, which is outside the narrow mixed-port scope here but explains why Git still times out
after perfect http.proxy settings.
Corporate TLS inspection sometimes conflicts with Git certificate stores. If you see MITM-related errors only inside Git, not inside the browser, compare http.sslBackend and the Windows schannel store. Do not disable verification globally; fix the trust chain or use your organization documented extra CA bundle. The symptom pattern is easy to misattribute to Clash when it is really an intercepted TLS handshake that Git refuses quietly until verbosity is raised.
npm, Yarn, and pnpm: registry traffic and corporate mirrors
npm reads proxy configuration from environment variables, from project-level .npmrc, and from the user-level .npmrc in your home directory. When multiple sources disagree, precedence rules can surprise you. A clean approach is to standardize on environment variables for host and port while keeping authentication tokens out of the proxy string. If you must embed credentials because of a legacy appliance, rotate them aggressively and prefer dedicated service accounts.
For Yarn Classic and modern Yarn Berry, the same environment variables propagate into most installs, but Berry introduces additional network configuration through .yarnrc.yml. PNPM honors similar environment keys. When installs are slow even though plain curl.exe is fast, check whether your registry URL points at a geographically distant mirror or an internal Verdaccio instance that should be on NO_PROXY. Container-oriented readers can continue with Docker registry split routing once daemon-level proxies enter the picture.
Node itself can be told about proxies independent of npm through NODE_OPTIONS or third-party agents, but that should be a second-line intervention. Most registry timeouts disappear once HTTPS_PROXY is coherent and DNS resolution for registry.npmjs.org is stable inside your Clash DNS stanza. If you recently enabled aggressive Fake-IP modes, confirm that your resolver and rules agree; our YAML routing and Fake-IP article walks through the trade-offs.
Editor-hosted terminals and the GitHub CLI
Developers rarely run Git only from a bare shell. They run it inside VS Code, Cursor, or JetBrains terminals. Those hosts inherit environment snapshots, and some ship with bundled Git builds that do not read the same global config paths you edited in PowerShell. When Cursor sits on Connecting
while tunnels look fine, split routing for editor hosts may be involved; see Cursor IDE split routing for hostname-level ideas that complement the proxy fundamentals here.
The GitHub CLI gh uses Go networking stacks that respect HTTPS_PROXY in most builds. If gh auth login succeeds but API calls fail intermittently, capture verbose logs and compare with plain curl.exe to the same endpoint. Discrepancies usually mean different CA bundles or HTTP/2 quirks rather than a dead mixed port.
Common pitfalls that waste time on Windows
Even experienced users repeat a handful of Windows-specific mistakes. The table below is a triage grid you can reuse during onboarding.
| Symptom | Likely cause | What to try first |
|---|---|---|
| Browser works, terminal does not | System proxy toggle does not populate shell variables | Export HTTP_PROXY and HTTPS_PROXY explicitly; verify with curl.exe |
Intermittent localhost failures |
IPv6 vs IPv4 resolution mismatch | Use 127.0.0.1 numerically in URLs |
| Git still uses direct after edits | SSH remote or tool-specific override | Check remote URL scheme; inspect repo-local .git/config |
| npm ECONNRESET against registry | TLS inspection or stale .npmrc proxy keys |
Align env vars and npmrc; test with verbose npm logging |
| Everything pauses on corporate Wi-Fi | Captive portal or HTTP proxy auth required | Authenticate on the portal; avoid machine-wide forced tunnels during login |
| Works in CMD, fails in PowerShell | Different profile scripts or aliases | Compare Get-ChildItem Env: output side by side |
When environment variables stop being enough
HTTP proxies solve a large fraction of developer workflows because Git, npm, and most REST clients speak TCP over TLS in predictable ways. They do not magically capture UDP game traffic, raw QUIC experiments, or binaries that open custom sockets while ignoring both WinINET and environment variables. If you hit that wall, TUN becomes attractive because it routes eligible IP flows through mihomo at the stack level. The cost is higher surface area: services, adapters, and firewalls all participate. Treat TUN as a deliberate escalation rather than the first knob.
If you choose to stay on mixed-port proxies for daily coding, keep your Clash profile healthy: refresh subscriptions on a sane cadence, avoid stacking multiple experimental DNS modes during the same debugging night, and read connection logs when a single host misbehaves. Boring profiles with explicit rules for registry and Git providers tend to outperform gigantic generic rule sets that chase every domain on the internet.
Closing thoughts
Clash shines when you stop fighting the platform defaults and instead align each layer—listener, environment variables, and tool-specific configuration—so they all point at the same loopback port. Windows makes that slightly opaque because system proxy toggles help browsers first, while terminals expect explicit variables. Once you standardize on your Clash mixed port, wire Git and npm deliberately, and respect NO_PROXY boundaries, most timeout mysteries shrink into ordinary misconfigurations you can fix in minutes.
When you are ready to install or refresh a maintained desktop build alongside these guides, start from our download page so binaries, checksum expectations, and documentation stay aligned. For broader topics beyond terminals, the documentation hub collects complementary articles. → Download Clash for free and experience the difference.