I Fixed Windows Native Development
Source: Hacker News
Build Requirements: Install Visual Studio
If you’re lucky enough not to know this yet, I envy you. Unfortunately, at this point even Boromir knows…
Well put, Boromir.
The hidden cost of “Install Visual Studio”
Listing Visual Studio as a dependency turns you into an unpaid tech‑support agent for Microsoft’s Visual Studio Installer.
Instead of focusing on code, you end up:
- Explaining to contributors that they need the “Desktop development with C++” workload, v143 build tools, and the 10.0.22621.0 SDK (not the other SDK).
- Spending hours troubleshooting broken builds that stem from missing or mismatched components.
- Re‑imaging your OS multiple times because a single wrong checkbox can ruin the whole setup.
Saying “Install Visual Studio” is essentially handing contributors a choose‑your‑own‑adventure book riddled with dead ends—some of which force you to start over from scratch.
Why is this tragedy unique to Windows?
| Platform | Typical experience |
|---|---|
| Linux | A single apt, yum, or pacman command usually pulls in the entire toolchain. |
| Windows | Visual Studio is a thousands‑of‑components monolith delivered via a GUI installer. You must navigate a maze of checkboxes to select the right Workloads or Individual Components. Selecting the wrong ones can add gigabytes of unnecessary files, while missing a single component (e.g., Windows 10 SDK (10.0.17763.0) or Spectre‑mitigated libs) leads to cryptic errors like MSB8101 hours later. |
The ecosystem conflates editor, compiler, and SDK into a single tangled web. When we list “Visual Studio” as a dependency we fail to distinguish between:
- The IDE you use to write code.
- The compiler/toolset required to build it.
- The runtime SDKs needed for linking and packaging.
Pain points that compound quickly
- Hours‑long waits – A 15 GB download for a 50 MB compiler.
- Zero transparency – No clear view of which files were installed or where they reside; the registry becomes littered with cruft, and background update services permanently occupy the Task Manager.
- No version control – You can’t check the compiler into Git. Slight version differences between teammates cause silent build divergence.
- “Ghost” environments – Uninstalling never truly cleans up. Moving to a new machine forces you to repeat the entire GUI dance, hoping you tick the same boxes.
- Fragile command‑line usage – Compiling a single C file requires launching the Developer Command Prompt, which runs
vcvarsall.bat. This batch script mutates global environment variables each time, making the setup brittle.
The resulting build instructions
“Works on my machine with VS 17.4.2 (Build 33027.167) and SDK 10.0.22621.0.
If you have 17.5, see Issue #412.
If you are on ARM64, godspeed.”
On Windows this has become the cost of doing business—a 20 GB install for a 5 MB executable, effectively deterring native development.
Bottom line: Listing “Visual Studio” as a single dependency hides a massive, opaque, and fragile toolchain. A cleaner, component‑by‑component specification (or a lightweight, reproducible build environment) would spare contributors endless hours of troubleshooting.
A New Way to Use the MSVC Toolchain
I’m tired of being a “human debugger” for someone else’s installer. I want the MSVC toolchain to behave like a modern dependency: versioned, isolated, declarative.
After a few weeks of work I created an open‑source CLI tool that does exactly that: msvcup.
- Installs the MSVC toolchain and Windows SDK in a few minutes (on a decent network/hardware).
- Each version lives in its own isolated directory.
- Idempotent – you can run it on every build without penalty.
Below is a minimal example that shows how to compile a simple program with zero manual installation of Visual Studio.
1. Create the source file hello.c
#include
int main() {
printf("Hello, World\n");
}
2. Create the build script build.bat
@setlocal
rem -------------------------------------------------
rem Download msvcup if it isn’t already present
rem -------------------------------------------------
@if not exist msvcup.exe (
echo msvcup.exe: installing...
curl -L -o msvcup.zip ^
https://github.com/marler8997/msvcup/releases/download/v2026_02_07/msvcup-x86_64-windows.zip
tar xf msvcup.zip
del msvcup.zip
) else (
echo msvcup.exe: already installed
)
@if not exist msvcup.exe exit /b 1
rem -------------------------------------------------
rem Choose the versions you want
rem -------------------------------------------------
set MSVC=msvc-14.44.17.14
set SDK=sdk-10.0.22621.7
rem Install the selected toolchain/SDK (idempotent)
msvcup install --lock-file msvcup.lock --manifest-update-off %MSVC% %SDK%
@if %errorlevel% neq 0 (exit /b %errorlevel%)
rem Generate an “auto‑environment” that points cl.exe to the right tools
msvcup autoenv --target-cpu x64 --out-dir autoenv %MSVC% %SDK%
@if %errorlevel% neq 0 (exit /b %errorlevel%)
rem Compile the program using the generated environment
.\autoenv\cl hello.c
3. Run the script
> build.bat
- The first run downloads msvcup, installs the requested MSVC version and Windows SDK, and builds
hello.c. - Subsequent runs are instant – the
msvcup installandautoenvsteps take only a few milliseconds because everything is already cached.
Why This Matters
- No Visual Studio Installer – the script works on any Windows 10+ machine that has
curl/tar(shipped since 2018). - Reproducible builds – the exact toolchain versions are declared in the script (
MSVCandSDKvariables). - Isolation – each version lives in its own directory; nothing pollutes the registry or the global environment.
- Speed – after the first run the overhead is negligible, so you can safely keep the commands in CI pipelines or per‑developer scripts.
Take a moment, give it a try, and enjoy a declaration of independence from the monolithic Visual Studio Installer. Your builds are now fully self‑contained and portable across any modern Windows machine.
How?
msvcup is inspired by a small Python script written by Mārtiņš Možeiko.
The key insight is that Microsoft publishes JSON manifests describing every component in Visual Studio—the same manifests the official installer uses.
msvcup parses these manifests, selects only the packages required for compilation (compiler, linker, headers, and libraries), and downloads them directly from Microsoft’s CDN. Everything is placed in version‑ed directories under C:\msvcup\.
For details on lock files, cross‑compilation, and other features, see the msvcup README.md.
Automatic environment
Our build.bat script never sources the usual Developer Environment batch files.
It contains two msvcup commands:
- Install the toolchain/SDK – this also installs the standard
vcvarsscripts. - Create an “Automatic Environment” –
msvcup autoenvgenerates a directory with wrapper executables that set the required environment variables before invoking the underlying tools.
The generated directory also includes a toolchain.cmake file, which points CMake projects to the installed tools. This lets you build CMake projects outside a special environment.
Real‑world usage
At Tuple (a pair‑programming app) I integrated msvcup into our build system and CI pipelines. This removed the need for users or CI agents to pre‑install Visual Studio. Tuple compiles hundreds of C/C++ projects—including WebRTC—on both x86_64 and ARM targets, keeping the CI and all developers on the same toolchain/SDK.
Benefits
- Versioned installations – each version lives in its own directory, making side‑by‑side installs, removal, or re‑installation trivial.
- Cross‑compilation out of the box –
msvcupalways downloads tools for all supported cross‑targets, so you never have to hunt down extra components. - Lock‑file support – a self‑contained list of all payload URLs guarantees that everyone uses the same packages; changes upstream are immediately visible.
- Blazing fast –
installandautoenvare idempotent and complete in milliseconds when there is nothing to do.
No more “it works on my machine because I have the 2019 Build Tools installed.”
No more digging through the registry to locatecl.exe.
Withmsvcup, your environment is defined by code, portable across machines, and ready to compile in milliseconds.
Limitations
msvcup focuses on the core compilation toolchain. If you need:
- the full Visual Studio IDE,
- MSBuild‑based project systems,
- or components such as the C++/CLI compiler,
you’ll still have to use the official installer. For most native development workflows, however, msvcup provides everything you actually need.
A Real‑World Example: Building raylib
Below is a self‑contained batch script that builds raylib from source on a clean Windows system.
It uses msvcup to install the required MSVC and Windows SDK toolchains, then compiles the library without any Visual Studio installation, GUI, or manual steps.
@setlocal
rem -------------------------------------------------
rem Configuration
rem -------------------------------------------------
set TARGET_CPU=x64
set MSVC=msvc-14.44.17.14
set SDK=sdk-10.0.22621.7
rem -------------------------------------------------
rem Install msvcup (if not already present)
rem -------------------------------------------------
if not exist msvcup.exe (
echo msvcup.exe: installing...
curl -L -o msvcup.zip ^
https://github.com/marler8997/msvcup/releases/download/v2026_02_07/msvcup-x86_64-windows.zip
tar xf msvcup.zip
del msvcup.zip
)
rem -------------------------------------------------
rem Install the selected toolchains
rem -------------------------------------------------
msvcup.exe install --lock-file msvcup.lock --manifest-update-off %MSVC% %SDK%
if %errorlevel% neq 0 exit /b %errorlevel%
rem -------------------------------------------------
rem Clone raylib (if not already present)
rem -------------------------------------------------
if not exist raylib (
git clone https://github.com/raysan5/raylib -b 5.5
)
rem -------------------------------------------------
rem Load the toolchain environment
rem -------------------------------------------------
call C:\msvcup\%MSVC%\vcvars-%TARGET_CPU%.bat
call C:\msvcup\%SDK%\vcvars-%TARGET_CPU%.bat
rem -------------------------------------------------
rem Build raylib for Windows
rem -------------------------------------------------
cmd /c "cd raylib\projects\scripts && build-windows"
if %errorlevel% neq 0 exit /b %errorlevel%
rem -------------------------------------------------
rem Success message
rem -------------------------------------------------
echo Build succeeded! Executable located at:
echo .\raylib\projects\scripts\builds\windows-msvc\game.exe
What this script does
- Installs
msvcup(a tiny downloader for MSVC/SDK) if it isn’t already on the machine. - Installs the exact MSVC and Windows SDK versions specified by
MSVCandSDK. - Clones the
raylibrepository (branch 5.5) only when the folder is missing. - Sets up the compiler environment by calling the
vcvars‑*.batscripts from the freshly installed toolchains. - Runs the official
build-windowsscript located inraylib\projects\scripts. - Prints the path to the resulting
game.exeon success.
No Visual Studio, no GUI, no manual configuration—just a reproducible, script‑driven build.
Further reading:
A detailed walkthrough of using msvcup to build LLVM and Zig from scratch on Windows can be found here.