⌂ Home
Gemini CLI: From Zero to Production
Windows Reference
Reference appendix No quiz
Appendix · Windows Deep Reference

Windows-Specific Gemini CLI

This appendix is a desk reference for Windows developers. It covers setup quirks, path syntax, environment variable management, WSL2 interop, Docker Desktop configuration, and a troubleshooting table for the 15 most common Windows-specific issues. No quiz, no progress bar — just the facts, organized for quick lookup.

Installation Options #

Three package managers can install Node.js (the Gemini CLI runtime) on Windows. Choose based on what you already use.

winget

Built into Windows 10/11. No separate install needed.

winget install OpenJS.NodeJS.LTS

Chocolatey

Established Windows package manager. Requires choco installed first.

choco install nodejs-lts

Scoop

User-scoped installs, no admin required. Good for dev machines.

scoop install nodejs-lts

After installing Node.js, install Gemini CLI globally:

PowerShell
# Install Gemini CLI globally
npm install -g @google/gemini-cli

# Verify installation
gemini --version

# If "gemini" is not recognized after install, reload PATH:
$env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" +
            [System.Environment]::GetEnvironmentVariable("PATH", "User")

PowerShell Execution Policy Fix

PowerShell (run as Administrator)
# Check current policy
Get-ExecutionPolicy -List

# Fix: allow scripts from the internet that are signed, and local scripts
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force

# Verify
Get-ExecutionPolicy -Scope CurrentUser
# Output: RemoteSigned
Node.js Version Requirement

Gemini CLI requires Node.js 18.0.0 or later. Run node --version to check. If you have an older version, use nvm-windows (winget install CoreyButler.NVMforWindows) to install and switch Node versions without affecting other tools.

WSL2 as an Alternative

PowerShell (Administrator)
# Enable WSL2
wsl --install

# After reboot, install Ubuntu 22.04
wsl --install -d Ubuntu-22.04

# Inside WSL2 (Ubuntu), install Node.js and Gemini CLI:
# curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
# sudo apt-get install -y nodejs
# npm install -g @google/gemini-cli

WSL2 gives you a full Linux environment. Gemini CLI behaves identically to macOS/Linux in WSL2, making Bash examples in this course work without adaptation.

@ Path Syntax #

Gemini CLI's @ file references work with both Windows and Unix paths, but there are nuances.

PowerShell — path reference examples
# Relative path (preferred — works everywhere)
gemini -p "@./src/auth.ts review this"

# Absolute path with forward slashes (works in most contexts)
gemini -p "@C:/Users/vara/project/src/auth.ts review"

# Absolute path with quotes (required for paths with spaces)
gemini -p "@`"C:\Users\vara\my project\auth.ts`" review"

# Use $PWD for absolute paths portably
gemini -p "@$PWD/src/auth.ts review this file"

# Loop: pass each file as an @ reference
Get-ChildItem src/ -Filter "*.ts" | ForEach-Object {
    gemini -p "@$($_.FullName) add JSDoc" --yolo --no-interactive
}
Path with Spaces

If your path contains spaces (e.g., C:\My Projects\app.ts), always wrap it in double quotes inside the @ reference. In PowerShell, escape the quotes with backtick: @`"C:\My Projects\app.ts`".

Relative vs Absolute

Prefer relative paths (@./file.ts) in all prompts you share with teammates or check into GEMINI.md. Absolute paths include your username and machine structure, making them non-portable.

Environment Variables #

Three Ways to Set GEMINI_API_KEY

1. Session only (PowerShell) — lost when terminal closes:

PowerShell — session scope
$env:GEMINI_API_KEY = "your-key-here"

2. Persistent user-level — survives reboots, visible to your user only:

PowerShell — user persistent
[System.Environment]::SetEnvironmentVariable(
    "GEMINI_API_KEY",
    "your-key-here",
    "User"
)
# Open a new terminal to pick up the change

3. System-level — visible to all users including scheduled tasks (requires admin):

PowerShell (Administrator)
[System.Environment]::SetEnvironmentVariable(
    "GEMINI_API_KEY",
    "your-key-here",
    "Machine"
)
# Restart Task Scheduler service to pick up Machine-scope changes:
Restart-Service "Schedule"

.env File Loading

PowerShell — load .env file
# Load .env into current session
Get-Content .env | Where-Object { $_ -notmatch "^#" -and $_ -match "=" } | ForEach-Object {
    $parts = $_ -split "=", 2
    [System.Environment]::SetEnvironmentVariable($parts[0].Trim(), $parts[1].Trim(), "Process")
}
Never Commit API Keys

Add .env to your .gitignore immediately. Gemini CLI reads the key from environment variables — never hardcode it in GEMINI.md or any committed file.

WSL2 Interoperability #

You can run Gemini CLI from WSL2 and access files on your Windows filesystem using the /mnt/c/ mount point.

WSL2 bash — access Windows files
# Your Windows C: drive is mounted at /mnt/c
cd /mnt/c/Users/vara/myproject

# Run Gemini CLI on a Windows-hosted file
gemini -p "@./src/auth.ts review" --no-interactive

# Access Windows env vars from WSL2
# (they're not automatically inherited)
export GEMINI_API_KEY=$(cmd.exe /c "echo %GEMINI_API_KEY%" 2>/dev/null | tr -d '\r')

Windows Terminal UNC Paths

For Windows paths from within WSL2, use the /mnt/ prefix. UNC paths (\\server\share) are accessible at /mnt/\\server\share but performance is poor — copy files to WSL2 filesystem first for heavy processing.

Performance Tip

Gemini CLI runs significantly faster on WSL2 when files are in the WSL2 filesystem (~/projects/) rather than accessed via /mnt/c/. Use cp -r /mnt/c/Users/vara/project ~/project for intensive sessions, then copy changes back.

Docker Desktop for Sandbox #

Recommended Settings

For gemini --sandbox to work reliably on Windows:

  • Backend: Settings → General → "Use the WSL 2 based engine" (faster than Hyper-V)
  • WSL Integration: Settings → Resources → WSL Integration → enable your distro
  • File Sharing: Settings → Resources → File Sharing → add your project drive (C:\)
  • Memory: Settings → Resources → Memory → minimum 4GB recommended for sandbox workloads

Hyper-V vs WSL2 Backend

FeatureWSL2Hyper-V
Startup speedFast (~2s)Slower (~5-10s)
CPU overheadLowModerate
File I/O (on Linux FS)Native speedSlower
Windows Home supportYesNo
Resource Limits

By default, WSL2 can use up to 80% of your RAM. If Docker Desktop feels sluggish, cap WSL2 memory in %USERPROFILE%\.wslconfig:
[wsl2]
memory=4GB
processors=4

Troubleshooting Reference #

15 common Windows-specific issues, their causes, and fixes.

Error Cause Fix
'gemini' is not recognized npm global bin not in PATH Run npm config get prefix, add that path + \bin to your User PATH. Restart terminal.
PSSecurityException: script is not digitally signed Execution policy blocking script Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
GEMINI_API_KEY is not set Key set in wrong scope or terminal not restarted Set as User-level env var via System Properties → Advanced. Open a new terminal.
ENOENT: no such file — long path Windows MAX_PATH (260 char) limit hit Enable long paths: reg add "HKLM\SYSTEM\CurrentControlSet\Control\FileSystem" /v LongPathsEnabled /t REG_DWORD /d 1 /f then reboot.
CRLF in generated files causes lint errors Git or editors inserting Windows line endings Add .gitattributes: * text=auto eol=lf. Or configure: git config --global core.autocrlf input
--sandbox: Docker not found Docker Desktop not installed or not running Install Docker Desktop. Start it. Wait for "Docker Desktop is running" tray icon before using --sandbox.
Docker: WSL2 backend not available WSL2 not installed or Hyper-V not enabled wsl --install from an admin PowerShell, reboot. Or switch Docker to Hyper-V backend if on Windows Pro/Enterprise.
Access is denied (file read) Antivirus scanning or file locked by another process Add your project directory to antivirus exclusions. Check for other processes locking the file with handle.exe from Sysinternals.
Corporate proxy blocks API calls HTTPS proxy required in corporate network Set $env:HTTPS_PROXY = "http://proxy:8080" and $env:NODE_EXTRA_CA_CERTS = "C:\certs\corp-root.pem"
Git hook not executing on Windows Hook file has no execute permission or wrong interpreter Hook files must start with #!/usr/bin/env bash (for Git Bash) or invoke pwsh.exe via a shell wrapper. No file extension on the hook file name.
Scheduled task runs but GEMINI_API_KEY is empty Key set as User env var; task runs as SYSTEM Set the key as a System environment variable (Machine scope) via [System.Environment]::SetEnvironmentVariable(..., "Machine").
@path reference fails with "file not found" Path uses backslashes that Gemini CLI doesn't interpret Use forward slashes: @./src/file.ts or @C:/Users/vara/project/file.ts
node: 'ERR_MODULE_NOT_FOUND' Global npm install corrupted or multiple Node versions Uninstall and reinstall: npm uninstall -g @google/gemini-cli then npm install -g @google/gemini-cli. If using nvm-windows, ensure the active version matches the one used for install.
FileSystemWatcher stops firing after ~2 hours Windows power management suspending background processes Set the PowerShell process to prevent sleep: add [System.Threading.Thread]::CurrentThread.IsBackground = $false at the top of the watcher script.
WSL2: "/mnt/c" I/O very slow Cross-filesystem overhead between Windows and WSL2 Copy the project to the WSL2 native filesystem (~/), work there, then sync back. Or use \\wsl$\Ubuntu\home\user\project from Windows Explorer to access WSL2 files from Windows.

PowerShell Profile — Aliases & Helpers #

Add these to your PowerShell $PROFILE (notepad $PROFILE to open it) for a smoother Gemini CLI experience in every session.

$PROFILE — Gemini CLI helpers
# ── Gemini CLI Aliases ──────────────────────────────────────────────────
# Quick non-interactive prompt
function gask { param([string]$Prompt) gemini -p $Prompt --no-interactive }

# Review a file for issues
function greview { param([string]$File) gemini -p "@$File Review this file for bugs, security issues, and improvements" --no-interactive }

# Generate tests for a file
function gtest { param([string]$File) gemini -p "@$File Generate comprehensive tests for this file" --yolo --no-interactive }

# Explain a file
function gexplain { param([string]$File) gemini -p "@$File Explain what this code does in plain English. Use bullet points." --no-interactive }

# Quick commit message from staged diff
function gcommit {
    $diff = git diff --cached
    if (-not $diff) { Write-Warning "Nothing staged"; return }
    $msg = $diff | gemini -p "Write a conventional commit message for this diff. Output only the message." --no-interactive
    Write-Host "Suggested: $msg" -ForegroundColor Cyan
    $confirm = Read-Host "Use this message? (y/n/edit)"
    if ($confirm -eq "y") { git commit -m $msg }
    elseif ($confirm -eq "edit") { git commit }
}

# Load project .env into session
function loadenv {
    if (-not (Test-Path .env)) { Write-Warning "No .env file found"; return }
    Get-Content .env | Where-Object { $_ -notmatch "^#" -and $_ -match "=" } | ForEach-Object {
        $parts = $_ -split "=", 2
        [System.Environment]::SetEnvironmentVariable($parts[0].Trim(), $parts[1].Trim(), "Process")
    }
    Write-Host ".env loaded into session" -ForegroundColor Green
}

# ── Auto-complete for gemini (tab completion) ──
Register-ArgumentCompleter -Native -CommandName gemini -ScriptBlock {
    param($wordToComplete, $commandAst, $cursorPosition)
    @('--no-interactive','--yolo','--sandbox','--quiet','-p','--model',
      '--temperature','--version','extensions','--help') |
    Where-Object { $_ -like "$wordToComplete*" } |
    ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
}
Command Usage Description
gask "question"gask "What is a JWT?"Quick non-interactive question
greview file.tsgreview src/auth.tsReview a file for issues
gtest file.tsgtest src/users.tsAuto-generate tests for a file
gexplain file.pygexplain main.pyPlain-English file explanation
gcommitgcommitAI-generated commit message from staged diff
loadenvloadenvLoad .env into current session

Windows Terminal Setup #

Windows Terminal with custom settings makes Gemini CLI sessions faster to navigate and easier to read.

Windows Terminal settings.json — Gemini CLI profile
{
  "profiles": {
    "list": [
      {
        "name": "Gemini CLI",
        "guid": "{your-guid-here}",
        "commandline": "pwsh.exe -NoLogo",
        "startingDirectory": "%USERPROFILE%\\projects",
        "font": {
          "face": "Cascadia Code",
          "size": 12
        },
        "colorScheme": "One Half Dark",
        "tabColor": "#4285F4",
        "icon": "ms-appx:///ProfileIcons/{61c54bbd-c2c6-5271-96e7-009a87ff44bf}.png",
        "padding": "8, 8",
        "scrollbarState": "hidden",
        "experimental.retroTerminalEffect": false
      },
      {
        "name": "Gemini CLI (WSL2)",
        "source": "Windows.Terminal.Wsl",
        "tabColor": "#8B5CF6",
        "startingDirectory": "//wsl$/Ubuntu/home/vara/projects"
      }
    ]
  },
  "keybindings": [
    { "command": "newTab", "keys": "ctrl+t" },
    { "command": { "action": "splitPane", "split": "vertical" }, "keys": "ctrl+shift+d" },
    { "command": { "action": "splitPane", "split": "horizontal" }, "keys": "ctrl+shift+minus" }
  ]
}

Recommended Pane Layout for Coding Sessions

Font Recommendation

Cascadia Code (Microsoft's coding font, free) renders Gemini CLI's box-drawing characters and Unicode correctly. Install it via winget install Microsoft.CascadiaCode. Set it in both your Windows Terminal profile and your VS Code integrated terminal ("terminal.integrated.fontFamily": "Cascadia Code") for a consistent experience.

← Back to Course Index