flinux essentially had the architecture of WSL1, while CoLinux was more like WSL2 with a Linux kernel side-loaded.
Cygwin was technically the correct approach: native POSIX binaries on Windows rather than hacking in some foreign Linux plumbing. Since it was merely a lightweight DLL to link to (or a bunch of them), it also kept the cruft low without messing with ring 0.
However, it lacked the convenience of a CLI package manager back then, and I remember being hooked on CoLinux when I had to work on Windows.
Cygwin is way older than CoLinux. CoLinux is from 2004. Cygwin was first released in 1995.
The problem with Cygwin as I remember it was DLL hell. You'd have applications (such as a OpenSSH port for Windows) which would include their own cygwin1.dll and then you'd have issues with different versions of said DLL.
Cygwin had less overhead which mattered in a world of limited RAM and heavy, limited swapping (x86-32, limited I/O, PATA, ...).
Those constraints also meant native applications instead of Web 2.0 NodeJS and what not. Java specifically had a bad name, and back then not even a coherent UI toolkit.
Just use ssh from Cygwin. DLL hell was rarely a problem, just always install everything via setup.exe.
The single biggest problem it has is slow forking. I learned to write my scripts in pure bash as much as possible, or as a composition of streaming executables, and avoid executing an executable per line of input or similar.
Meanwhile those that complained about Java, now ship a whole browser with their "native" application, and then complain about Google taking over the Web.
Technically correct by some estimation, perhaps, but Cygwin is a crazy approach, was slow (contrary to the implication of the "low cruft" claim), was not as compatible as these other approaches, required recompilation, and was widely disliked at most points in its life. There's a lot of crazy voodoo stuff happening in cygwin1.dll to make this work; it totally qualifies as "hacking in some foreign Linux plumbing", it's just happening inside your process. Just picture how fork() is implemented inside cygwin1.dll without any system support.
Cygwin doesn't work at all in Windows AppContainer package isolation; too many voodoo hacks. MSYS2 uses it to this day, and as a result you can't run any MSYS2 binaries in an AppContainer. Had to take a completely different route for Claude Code sandboxing because of this: Claude Code wants Git for Windows, and Git for Windows distributes MSYS2-built binaries of bash.exe and friends. Truly native Windows builds don't do all the unusual compatibility hacks that cygwin1.dll requires; I found non-MSYS2-built binaries of the same programs all ran fine in AppContainer.
Nowadays MSYS2, which does depend on cygwin under the hood, offers such a package manager (pacman of Arch Linux) and it is quite a user friendly to run native POSIX binaries on Windows without a linux VM.
In my personal experience, Msys 2 would work great until it didn't. Unless this has changed, from what I remember, Msys2 compiled everything without PIC/PIE, and Windows does allow you to configure, system-wide, whether ASLR is used, and whether it's used "if supported" or always. If that setting is set to anything but off, Msys2 binaries will randomly crash with heap allocation errors, or they do on my system. It happened so much to me when I had actual coreutils installed that I switched to uutils-coreutils even though I knew that uutils-coreutils has some discrepancies/issues. Idk if they've fixed that bug or not; I did ask them once why they didn't just allow full ASLR and get on with things and they claimed that they needed to do non-ASLR compilations for docker.
MSYS2 is very confusing. When you pick "MSYS2", you are building exclusively for the MSYS2 target environment, and might not have proper compatible windows headers. When you pick "MINGW32/64", you are instead building for the normal windows environment, and get proper windows headers. But if you didn't know that, you would end up confused about why your program is not building.
It doesn't help that the package simply named "gcc" is for the MSYS2 target.
Developing on cygwin, however, was a right pain. If a C library you wanted to use didn't have a pre-built cygwin version (understandable!) then you end up doing 'configure, make' on everything in the dependency tree, and from memory about two thirds of the time you had to edit something because it's not quite POSIX enough sometimes.
Ha ha doing Unix like it was 1989. At the time I thought configure was the greatest of human achievements since I was distributing software amongst Sun machines of varying vintage and a Pyramid. I want to say good times but I prefer now ha ha
Cygwin implements a POSIX API on Win32 with a smattering of Nt* calls to improve compatibility but there's a lot of hoop jumping and hackery to get the right semantics. Fork isn't copy on write, for one thing.
I was a Cygwin user from about 1999 to 2022 or so, spent a little time on wsl2 (and it's what I still use on my laptop) but I'm fully Linux on the desktop since last year.
Requiring every single Linux app developer to recompile their app using Cygwin and account for quirks that it may have is not the correct approach. Having Microsoft handle all of the compatibility concerns scales much better.
Why not? That is just a matter of porting stuff over, like a FreeBSD ports collection, an apt repo, or a bunch of scripts for Proton/Wine such as Lutris.
Cygwin started in 1995. Microsoft wasn't cooperative with FOSS at all at that point. They were practicing EEE, and eating some expensive Unix/VMS machines with WNT.
So, is it like colinux[0], but for pre-NT windows? Neat!
Back when I was still using windows (probably XP era), I used to run colinux, it was kind of amazing, setting up something like LAMP stack on the linux side was a lot easier and then using windows editors for editing made for quite nice local dev env, I think! Could even try some of the X11 servers on windows and use a linux desktop on top of windows.
When I noticed I kept inching towards more and more unixy enviornment on the windows, I eventually switched to macOS.
Apart from the obvious hack-value, I can't quite imagine even pretend use-case, with some 486 era machine, you would be limited by memory quite quickly!
I remember myself on my first year of CS, set theory classes, at the whiteboard, trying to make a proof, but there something I was not able to prove at all, so I said 'it's trivial' and the doctor said 'yeah, it's trivial' and we went further.
> But I wonder how it seems to people who understand how it works?
As someone who mostly understands what's going on - It does not seem like wizardry to me, but I am very impressed that the author figured out the long list of arcane details needed to make it work.
The primary function of modern operating systems is to allow multiple programs to run, without interfering with each other, even if they try too. This means that each program can only read its own limited amount of memory and only gets to use the processor for a limited time, before another program gets a turn. Windows did not start using those features until Windows NT, which XP is based off of. Through Windows 98, any program could do whatever it wanted, and that hardware sat idle. Windows versions up to 98 were more like a library of features that a program could use, to display a user interface and talk to hardware peripherals.
There's special hardware in a processor, for the operating system to limit each programs access to memory and processing time, which Windows 9x leaves unused. This means that the Windows 9x Subsystem for Linux can say "look at me i'm the operating system now" and take over that hardware to run a modern operating system.
That's greatly oversimplified, or less generously, just flat out wrong. Win32 programs have always had their own isolated address space. That infamous BSOD is the result of memory protection hardware catching an access to something outside of that address space. When you open a DOS box, it uses the paging and V86 hardware mechanisms to create a new virtual machine, even though it shares some memory with the instance of DOS from which Windows was booted.
What Windows 9x didn't have was security. A program could interfere with these mechanisms, but usually only if it was designed to do that, not as a result of a random bug (if the entire machine crashed, it was usually because of a buggy driver).
It's mostly explained if you go to the project page. For me, the I would say the hardest thing about something like this is gleaning the Microsoft driver APIs. In the 9x days, Microsoft documentation was not quite thorough and difficult to access. It's still not pleasant.
This is in the class of things where even if the specific text doesn't trace to a true story, it has certainly happened somewhere, many times over.
In the math space it's not even quite as silly as it sounds. Something can be both "obvious" and "true", but it can take some substantial analysis to make sure the obvious thing is true by hitting it with the corner cases and possibly exceptions. There is a long history of obvious-yet-false statements. It's also completely sensible for something to be trivially true, yet be worth some substantial analysis to be sure that it really is true, because there's also a history of trivial-yet-false statements.
I could analogize it in our space to "code so simple it is obviously bug free" [1]... even code that is so simple that it is obviously bug free could still stand to be analyzed for bugs. If it stands up to that analysis, it is still "so simple it is obviously bug free"... but that doesn't mean you couldn't spend hours carefully verifying that, especially if you were deeply dependent on it for some reason.
Heck I've got a non-trivial number of unit tests that arguably fit that classification, making sure that the code that is so simple it is bug free really is... because it's distressing how many times I've discovered I was wrong about that.
[1]: In reference to Tony Hoare's "There are two ways to write code: write code so simple there are obviously no bugs in it, or write code so complex that there are no obvious bugs in it."
This being on the front page the same day as "Show HN submissions tripled and now mostly have the same vibe-coded look" is nice to see. One person spends 6 years understanding Win9x internals to run a modern Linux kernel inside it. The other thread is full of apps that took 20 minutes to prompt into existence. Posts like this make me happy.
And likely the prompt itself was generated. Instead of "create me an owl app" write: "create me a comprehensive prompt to create an owl app". Then paste that prompt to next AI session.
I agree. Don't have a citation now, but I remember reading that this was a copyright problem. They wanted to name it "Linux Subsystem for Windows", but apparently the Linux foundation does not allow unaffiliated projects to have a name beginning with "Linux", or something like that.
It runs Linux with Windows underneath it, hence Windows is the subsystem being subordinate (in the most literal sense where it simply means "order" with no further implications) to Linux.
Per wongarsu's post, something like the OS/2 Subsystem is an OS/2 system with Windows beneath it, but the OS/2 Subsystem is much smaller and less consequential, thus subsidiary (in the auxiliary sense) to Windows as a whole.
Isn't marketing fun?
This is how we end up with hundreds of products that provide "solutions" to your business problems and "retain customers" and upwards of a dozen other similar phrases they all slather on their frontpages, even though one is a distributed database, one is a metrics analysis system, one handles usage-based billing, one is a consulting service, one is a hosted provider for authentication... so frustrating trying to figure out just what a product is sometimes with naming conventions that make "Windows Subsystem for Linux" look like a paragon of clarity. At least "Linux" was directly referenced and it wasn't Windows Subsystem for Alternate Binary Formats or something.
The NT kernel (used in NT 3.1 through 2000, XP, and eventually backported to Windows 10/11's WSL) was designed from scratch in 1993 with a POSIX subsystem from day one. The whole design philosophy was "multiple personalities" - handle syscalls from different environments by translating them to native NT kernel calls. WSL1 in 2016 essentially reimplemented that same trick for Linux.
Windows 9x, by contrast, was DOS-derived. Running Linux inside it would require fundamentally different (and messier) hacks - which is probably why nobody did it at the time. The very fact that this works at all is a testament to how ahead-of-its-time NT's architecture was.
For a practical answer: you'd need something like this for legacy locked-in situations. Old medical or industrial software that only runs on Windows 98, or specialized hardware without modern drivers. That said, if you have a 486 handy in 2026, running Linux natively is almost certainly more useful than running it inside a 30-year-old DOS derivative.
I remember running CoLinux back in my training days ~2005-2006. It seemed a bit like black magic to me at the time, but it worked quite well for my needs.
But CoLinux - IIRC - required the NT branch of Windows. I can only imagine the level of hackery it takes to make this happen on Windows 9x.
Part of me wants to weep at the sheer perversity, part of me wants to burst into manic laughter. It is indeed a world of endless wonders.
Little late but would this have actually allowed running early Linux under Windows when Windows 95 came out in the 90s? I remember only dual booting being available at that time.
Hmm I wonder how stable it is.. It cannot render correctly Window control buttons (Minimize, Maximize, Close). If it fails on such basic task, I wonder where it crashes...
If I can get this to work (haven't tried yet) it directly solves a problem I have right now this week right here in 2026, 30 years after Windows 95 was even a thing.
Yes, I have weird problems. I get to look after some very weird shit.
If you're dealing with weird legacy 9x systems in 2026, another headache you've probably run into is getting them to talk to the modern web (since modern TLS and JS completely break old browsers).
I actually built a win9x compatibility mode into BrowserBox specifically for this kind of weirdness. You run the server on a modern system and launch it with bbx win9x-run, and it proxies the modern web to legacy clients. It works surprisingly well with IE5, IE6, and old Netscape on Windows 95/98/NT. Might be a fun addition to your retro utility belt!
There is a section of the Forties Pipeline where they have a huge amount of gas handling plant in central Scotland. Last time I was on site (admittedly 15 years ago but I don't see this changing soon) the SCADA outstations were run by absolutely minty box fresh VAXStation 3100s. Plastic not even peeled off the front panel badges fresh.
Everytime I see something like this, I'm like, how in the hell did they learn and then figure this out? Congrats on this!!!! I will definitely have to play with this for some of that sweet nostalga.
Wait until you find IE was released for Unix, using some Win32 shims. And... die hard Unix sysadmin ran it under FVWM and compared to Netscape wasn't half bad.
Both propietary, but sadly NScape didn't open Mozilla yet, and the rest of the alternatives such as Arena/Amaya coudn't compete with 'modern' CSS features and the like.
Speaking of vintage IE and Netscape on old Win, it's actually still possible to use them to browse the modern web if you proxy it.
I built a Win9x compatibility mode for BrowserBox that does exactly this (https://github.com/BrowserBox/BrowserBox/blob/main/readme-fi...). Ur modern server does all the rendering, and it outputs a client link specifically designed for legacy browsers like IE5, IE6, and Netscape running on Windows 95/98/NT, streaming them the pixels. It's definitely an abomination, but there's something magical and retro that I like about viewing the 2026 internet through an IE6 window ;) ;p xx
This. The post immediately reminded me of Win4Lin 9x (the version before it became just another boring VM) and SCO Merge. It was insanely fast, even on the hardware of the day.
The Wikipedia page is not verify informative and presents it as a regular VM (possibly mixing up 9x and later versions that run the NT line of kernels). The manual is a bit more informative about the tech:
I’m a bit surprised it hasn’t been mentioned a lot in the comments. Maybe it’s a bit too old for most people here (Linux in the late 90ies/early 00s was a much smaller community)?
Sidebar: does anyone else find the naming of this super confusing—does this mean embedding windows in linux or linux in windows? Surely we could find a way to refer to composing operating systems that isn't inherently ambiguous. Say, "linux inside of windows" would be less ambiguous.
Edit: to the people who downvoted, I corrected my spelling mistake. I will perform due penance.
Interesting idea. Does it actually work? If so, didn't the guy kind of simplified WSL here?
I have not tested this yet, so I have no idea - but if he managed to pull this off then this may be one of the greatest achievements this year. Or perhaps there are some restrictions to it? Does compiling stuff work in it? So many questions ... who has the answers?
WSL was a subsystem to run Linux under Windows 10 without an explicit VM host. It was an Ubuntu Linux version. Later MS released WSL2, complete redesign, still for Windows 10.
With Windows 11 the WSL2 also supported GUI programs.
lol, if you do assemble that Pentium desktop, one of the first things you'll notice is that the modern web is completely unusable on it natively.
To get around that, I recently added a legacy compatibility mode to BrowserBox (bbx win9x-run). It basically lets you run the server on your modern daily driver, and access it via IE 5, IE 6, or Netscape on the Pentium box. It strips away the modern TLS/JS rendering issues and lets you actually browse the modern web from Windows 9x. Highly recommend giving it a spin if you get that machine built!
Oddly enough, I could kind of use this right now. I have some software which used SCSI (Adaptec WNASPI32.dll) calls to administer a device over the SCSI bus .. would this Subsystem be usable for that, or does it still require I build a WNASP32.dll shim to do translation?
So, you have Windows software. This "Windows 9x Subsystem for Linux" just boots Windows 95. I don't know what you would use the Linux part for. Care to explain more what you want to do?
If you want to run your windows software in Linux, you could try Wine. Wine seems to have support for WNASPI so it's possible your software would just work. (You might have to run Wine as root I guess, to get access to the SCSI devices.)
If Wine doesn't work, Windows in QEMU with PCI passthrough to the SCSI controller might have better chances to work.
I need raw SCSI I/O to be virtualizable in the linux context, so I could run a Windows app (yes it already works in Wine), and have it 'see' a SCSI device as if it were real hardware.
Wines WNASPI32.dll is really just a facade - it doesn't provide actual SCSI services, its just there for SCSI-using apps to think they have ASPI onboard - so for my case I would need to write a shim to pass through SCSI IO requests to a Linux service - or loopback file? - to actually process the requests. I've been meaning to do this for a long time, but if there is some way I can set up a loopback file under Linux to 'pretend' to be a SCSI block device for a Windows app, I'd sure like to know if its possible ..
The core of the software is a subsystem, specifically a Windows subsystem; you're not running this subsystem on macOS or FreeBSD.
The "for Linux" is added because it's a subsystem for Linux applications (originally not leveraging a VM).
Microsoft also had the "Microsoft POSIX subsystem" (1993) and "Windows Services for UNIX" (1999) which were built on the "Subsystem for Unix-based Applications" (rather than "Unix-based Application Subsystem"). That chain of subsystems died at the end of Windows 8, though.
There are many reasons not to put "Linux" in front, but the naming is consistent with Microsoft's naming inconsistencies. It's not the first time they used "subsystem for" and it's not the first time they used "Windows x for y" either.
The naming is ambiguous, you could interpret the Windows subsystem for Linux as a subsystem of Linux (if it had such a thing) that runs Windows, or as a Windows subsystem for use with Linux. Swapping the order doesn't change that.
In other languages, the difference would be clearer.
My personal experience with our legal department on naming is that if your product name includes someone else's trademark, you have to say "Our Thing for Their Thing", exactly like that. I was involved in a product that did this, and we came up with some better names, but legal said no, it must be named with "for Their Thing" at the end. Those were the magic words so we don't get sued, and indeed, we weren't sued. Our legal was non-technical and never heard of WSL; they came to this conclusion independently.
The name we shipped was even worse than Windows Subsystem for Linux, honestly. At least Microsoft spent some time on it.
I always have the same problem myself. Same as I had with version naming of old programs like "Microsoft Word for Windows 2.0" instead of the easier "Microsoft Word 2.0 for Windows".
The problem is Word 2.0 for Dos was released in 1985, and Word for Windows 2.0 was released in 1991. Calling it Word 2.0 for Windows wouldn't make sense, because it wasn't the 1985 release with a new coat of paint, Word for Windows was its own thing, and this was the second version. Word for Mac was also separate, but eventually Word 6 was a common code base and it made sense to have Word 6.0 for [whatever]
Other people already answered but windows was just another personality on the original idea that cutler had for WNT. It just took a while for it to get implemented as a linux
To reciprocate the naming of Wine, maybe it could have been named Line. Also, both have this positive clang, being associated with "having a good time".
Before WSL, the best ways to run unmodified Linux binaries inside Windows were CoLinux and flinux.
http://www.colinux.org/
https://github.com/wishstudio/flinux
flinux essentially had the architecture of WSL1, while CoLinux was more like WSL2 with a Linux kernel side-loaded.
Cygwin was technically the correct approach: native POSIX binaries on Windows rather than hacking in some foreign Linux plumbing. Since it was merely a lightweight DLL to link to (or a bunch of them), it also kept the cruft low without messing with ring 0.
However, it lacked the convenience of a CLI package manager back then, and I remember being hooked on CoLinux when I had to work on Windows.
Cygwin is way older than CoLinux. CoLinux is from 2004. Cygwin was first released in 1995.
The problem with Cygwin as I remember it was DLL hell. You'd have applications (such as a OpenSSH port for Windows) which would include their own cygwin1.dll and then you'd have issues with different versions of said DLL.
Cygwin had less overhead which mattered in a world of limited RAM and heavy, limited swapping (x86-32, limited I/O, PATA, ...).
Those constraints also meant native applications instead of Web 2.0 NodeJS and what not. Java specifically had a bad name, and back then not even a coherent UI toolkit.
As always: two steps forward, one step back.
Just use ssh from Cygwin. DLL hell was rarely a problem, just always install everything via setup.exe.
The single biggest problem it has is slow forking. I learned to write my scripts in pure bash as much as possible, or as a composition of streaming executables, and avoid executing an executable per line of input or similar.
6 replies →
Cygwin works fine if I am compiling stuff locally for my own use, but that cygwin1.dll (plus any dependencies) is a problem for distribution.
What I usually do is make sure my code builds with both Cygwin and MingW, and distribute the binaries built with MingW.
> Cygwin had less overhead which mattered in a world of limited RAM and heavy, limited swapping (x86-32, limited I/O, PATA, ...).
Maybe so, but my memory of Cygwin was waiting multiple seconds just for the Cygwin CLI prompt to load. It was very slow on my machines.
> Java specifically had a bad name, and back then not even a coherent UI toolkit.
Java was ahead of its time, now nothing has a coherent UI toolkit.
1 reply →
Meanwhile those that complained about Java, now ship a whole browser with their "native" application, and then complain about Google taking over the Web.
1 reply →
Technically correct by some estimation, perhaps, but Cygwin is a crazy approach, was slow (contrary to the implication of the "low cruft" claim), was not as compatible as these other approaches, required recompilation, and was widely disliked at most points in its life. There's a lot of crazy voodoo stuff happening in cygwin1.dll to make this work; it totally qualifies as "hacking in some foreign Linux plumbing", it's just happening inside your process. Just picture how fork() is implemented inside cygwin1.dll without any system support.
Cygwin doesn't work at all in Windows AppContainer package isolation; too many voodoo hacks. MSYS2 uses it to this day, and as a result you can't run any MSYS2 binaries in an AppContainer. Had to take a completely different route for Claude Code sandboxing because of this: Claude Code wants Git for Windows, and Git for Windows distributes MSYS2-built binaries of bash.exe and friends. Truly native Windows builds don't do all the unusual compatibility hacks that cygwin1.dll requires; I found non-MSYS2-built binaries of the same programs all ran fine in AppContainer.
Nowadays MSYS2, which does depend on cygwin under the hood, offers such a package manager (pacman of Arch Linux) and it is quite a user friendly to run native POSIX binaries on Windows without a linux VM.
In my personal experience, Msys 2 would work great until it didn't. Unless this has changed, from what I remember, Msys2 compiled everything without PIC/PIE, and Windows does allow you to configure, system-wide, whether ASLR is used, and whether it's used "if supported" or always. If that setting is set to anything but off, Msys2 binaries will randomly crash with heap allocation errors, or they do on my system. It happened so much to me when I had actual coreutils installed that I switched to uutils-coreutils even though I knew that uutils-coreutils has some discrepancies/issues. Idk if they've fixed that bug or not; I did ask them once why they didn't just allow full ASLR and get on with things and they claimed that they needed to do non-ASLR compilations for docker.
MSYS2 is very confusing. When you pick "MSYS2", you are building exclusively for the MSYS2 target environment, and might not have proper compatible windows headers. When you pick "MINGW32/64", you are instead building for the normal windows environment, and get proper windows headers. But if you didn't know that, you would end up confused about why your program is not building.
It doesn't help that the package simply named "gcc" is for the MSYS2 target.
1 reply →
MSYS2 is my favorite in this area. Super lightweight and easy to use, highly recommend.
w64devkit it's fine too; with just a few PATH settings and SDL2 libraries I could even compile UXN and some small SDl2 bound emulators.
https://github.com/skeeto/w64devkit
Developing on cygwin, however, was a right pain. If a C library you wanted to use didn't have a pre-built cygwin version (understandable!) then you end up doing 'configure, make' on everything in the dependency tree, and from memory about two thirds of the time you had to edit something because it's not quite POSIX enough sometimes.
Ha ha doing Unix like it was 1989. At the time I thought configure was the greatest of human achievements since I was distributing software amongst Sun machines of varying vintage and a Pyramid. I want to say good times but I prefer now ha ha
2 replies →
Cygwin implements a POSIX API on Win32 with a smattering of Nt* calls to improve compatibility but there's a lot of hoop jumping and hackery to get the right semantics. Fork isn't copy on write, for one thing.
I was a Cygwin user from about 1999 to 2022 or so, spent a little time on wsl2 (and it's what I still use on my laptop) but I'm fully Linux on the desktop since last year.
> However, it lacked the convenience of a CLI package manager back then
Cygwin still lacks that to this day, you have to fire up to GUI installer to update packages.
MSYS2 is cygwin with pacman cli.
I thought WSL2 is functionally a virtual machine with deep host integration. That’s why you need HyperV.
Sort of. Technically speaking, just enabling hyper-v turns your base windows install into a VM. Wsl2 then just runs along side
3 replies →
I remember when I first put cygwin in my path on Windows and it felt like magic. I can just ssh and git now? No need for putty or WinGit????
Nope, the best way was VMWare Workstation, followed by Virtual Box.
And before those Virtual PC by Connectix. Which Microsoft bought and dumped.
1 reply →
I've been running colinux for years until early 2009 when I reinstalled my laptop with Ubuntu 8.04 and Windows XP in a VM. So much faster.
On Windows NT building software from source under Interix[0] (nee OpenNT, later "Subsystem for Unix Applications") was pretty nice.
Interix was implemented as proper NT kernel "subsystem". It was just another build target for GNU automake, for example.
(Being that Interix was a real kernel subsystem I have this fever dream idea of a text-mode "distribution" of NT running w/o any Win32 subsystem.)
[0] https://en.wikipedia.org/wiki/Interix
>Cygwin was technically the correct approach
Requiring every single Linux app developer to recompile their app using Cygwin and account for quirks that it may have is not the correct approach. Having Microsoft handle all of the compatibility concerns scales much better.
Why not? That is just a matter of porting stuff over, like a FreeBSD ports collection, an apt repo, or a bunch of scripts for Proton/Wine such as Lutris.
Cygwin started in 1995. Microsoft wasn't cooperative with FOSS at all at that point. They were practicing EEE, and eating some expensive Unix/VMS machines with WNT.
So, is it like colinux[0], but for pre-NT windows? Neat!
Back when I was still using windows (probably XP era), I used to run colinux, it was kind of amazing, setting up something like LAMP stack on the linux side was a lot easier and then using windows editors for editing made for quite nice local dev env, I think! Could even try some of the X11 servers on windows and use a linux desktop on top of windows.
When I noticed I kept inching towards more and more unixy enviornment on the windows, I eventually switched to macOS.
Apart from the obvious hack-value, I can't quite imagine even pretend use-case, with some 486 era machine, you would be limited by memory quite quickly!
[0] http://colinux.org/
Colinux was a tech feat, just not that many people noticed.
Is this person a wizard?
To me, this seems an impossible feat.
But I wonder how it seems to people who understand how it works?
I'm reminded of this joke:
Two mathematicians are talking. One says a theorem is trivial. After two hours of explanation, the other agrees that it is indeed trivial.
I remember myself on my first year of CS, set theory classes, at the whiteboard, trying to make a proof, but there something I was not able to prove at all, so I said 'it's trivial' and the doctor said 'yeah, it's trivial' and we went further.
"Trivial" doesn't exclusively mean "easy", though it is often used as a euphemism like that.
In a literal sense, it very well may have been trivial, even if neither you nor the professor would have been able to easily show it.
2 replies →
Maybe it wasn't trivial at all for both of you ...
1 reply →
> But I wonder how it seems to people who understand how it works?
As someone who mostly understands what's going on - It does not seem like wizardry to me, but I am very impressed that the author figured out the long list of arcane details needed to make it work.
The primary function of modern operating systems is to allow multiple programs to run, without interfering with each other, even if they try too. This means that each program can only read its own limited amount of memory and only gets to use the processor for a limited time, before another program gets a turn. Windows did not start using those features until Windows NT, which XP is based off of. Through Windows 98, any program could do whatever it wanted, and that hardware sat idle. Windows versions up to 98 were more like a library of features that a program could use, to display a user interface and talk to hardware peripherals.
There's special hardware in a processor, for the operating system to limit each programs access to memory and processing time, which Windows 9x leaves unused. This means that the Windows 9x Subsystem for Linux can say "look at me i'm the operating system now" and take over that hardware to run a modern operating system.
That's greatly oversimplified, or less generously, just flat out wrong. Win32 programs have always had their own isolated address space. That infamous BSOD is the result of memory protection hardware catching an access to something outside of that address space. When you open a DOS box, it uses the paging and V86 hardware mechanisms to create a new virtual machine, even though it shares some memory with the instance of DOS from which Windows was booted.
What Windows 9x didn't have was security. A program could interfere with these mechanisms, but usually only if it was designed to do that, not as a result of a random bug (if the entire machine crashed, it was usually because of a buggy driver).
Thank you, that's a great explanation.
It's mostly explained if you go to the project page. For me, the I would say the hardest thing about something like this is gleaning the Microsoft driver APIs. In the 9x days, Microsoft documentation was not quite thorough and difficult to access. It's still not pleasant.
Never heard of this joke, very funny !
The win9x kernel famously doesn't do very much, which seems like it can give you ample room to port some of Linux's low level functionality to it.
I believe this wasn't really even a joke, but a real story that got distorted as joke: https://hsm.stackexchange.com/a/8054
This is in the class of things where even if the specific text doesn't trace to a true story, it has certainly happened somewhere, many times over.
In the math space it's not even quite as silly as it sounds. Something can be both "obvious" and "true", but it can take some substantial analysis to make sure the obvious thing is true by hitting it with the corner cases and possibly exceptions. There is a long history of obvious-yet-false statements. It's also completely sensible for something to be trivially true, yet be worth some substantial analysis to be sure that it really is true, because there's also a history of trivial-yet-false statements.
I could analogize it in our space to "code so simple it is obviously bug free" [1]... even code that is so simple that it is obviously bug free could still stand to be analyzed for bugs. If it stands up to that analysis, it is still "so simple it is obviously bug free"... but that doesn't mean you couldn't spend hours carefully verifying that, especially if you were deeply dependent on it for some reason.
Heck I've got a non-trivial number of unit tests that arguably fit that classification, making sure that the code that is so simple it is bug free really is... because it's distressing how many times I've discovered I was wrong about that.
[1]: In reference to Tony Hoare's "There are two ways to write code: write code so simple there are obviously no bugs in it, or write code so complex that there are no obvious bugs in it."
> this seems an impossible feat
What makes you think so?
AAA+ joke
[flagged]
The README states:
> Proudly written without AI.
2 replies →
As the repo says
> Proudly written without AI.
Stuff like this is far above the capabilities of today’s top AIs.
It’ll produce something, sure, but it won’t actually work, and making it work takes as much effort as building it from scratch.
This is way beyond the current capability of AI. You should likely know that instead of just trashing random projects.
This being on the front page the same day as "Show HN submissions tripled and now mostly have the same vibe-coded look" is nice to see. One person spends 6 years understanding Win9x internals to run a modern Linux kernel inside it. The other thread is full of apps that took 20 minutes to prompt into existence. Posts like this make me happy.
The project's readme states "Proudly written without AI." Love seeing this.
And likely the prompt itself was generated. Instead of "create me an owl app" write: "create me a comprehensive prompt to create an owl app". Then paste that prompt to next AI session.
> Proudly written with zero AI.
Unfortunately this is ambiguous, as there's an AI product called Zero AI.
> Proudly written without AI.
Looks like it's been updated now to be more clear. Amazing though.
Looks like opportunity for new AI product called "without AI".
2 replies →
Letter case matters.
Direct link without the social hop-through: https://codeberg.org/hails/wsl9x
Thanks. Mastodon still requires executing javascript just to read a post, so I usually ignore it.
https://github.com/mastodon/mastodon/issues/23153
https://github.com/mastodon/mastodon/issues/19953
By microsoft's naming scheme this should be Linux Subsystem for Windows
No? WSL is Linux on Windows — so W9xSL is Linux on Windows 9x. I think… :)
WSL is "Windows Subsystem for Linux", so this should be "Linux Subsystem for Windows 9x"
5 replies →
I agree. Don't have a citation now, but I remember reading that this was a copyright problem. They wanted to name it "Linux Subsystem for Windows", but apparently the Linux foundation does not allow unaffiliated projects to have a name beginning with "Linux", or something like that.
also bad for your product name to start with a competitors brand
Yeah this has never made sense...
It runs Linux with Windows underneath it, hence Windows is the subsystem being subordinate (in the most literal sense where it simply means "order" with no further implications) to Linux.
Per wongarsu's post, something like the OS/2 Subsystem is an OS/2 system with Windows beneath it, but the OS/2 Subsystem is much smaller and less consequential, thus subsidiary (in the auxiliary sense) to Windows as a whole.
Isn't marketing fun?
This is how we end up with hundreds of products that provide "solutions" to your business problems and "retain customers" and upwards of a dozen other similar phrases they all slather on their frontpages, even though one is a distributed database, one is a metrics analysis system, one handles usage-based billing, one is a consulting service, one is a hosted provider for authentication... so frustrating trying to figure out just what a product is sometimes with naming conventions that make "Windows Subsystem for Linux" look like a paragon of clarity. At least "Linux" was directly referenced and it wasn't Windows Subsystem for Alternate Binary Formats or something.
Especially since the other subsystems were referred to as the OS/2 subsystem, Posix subsystem, Win32 subsystem, Security subsystem, etc
5 replies →
The NT kernel (used in NT 3.1 through 2000, XP, and eventually backported to Windows 10/11's WSL) was designed from scratch in 1993 with a POSIX subsystem from day one. The whole design philosophy was "multiple personalities" - handle syscalls from different environments by translating them to native NT kernel calls. WSL1 in 2016 essentially reimplemented that same trick for Linux.
Windows 9x, by contrast, was DOS-derived. Running Linux inside it would require fundamentally different (and messier) hacks - which is probably why nobody did it at the time. The very fact that this works at all is a testament to how ahead-of-its-time NT's architecture was.
For a practical answer: you'd need something like this for legacy locked-in situations. Old medical or industrial software that only runs on Windows 98, or specialized hardware without modern drivers. That said, if you have a 486 handy in 2026, running Linux natively is almost certainly more useful than running it inside a 30-year-old DOS derivative.
All of this is true, but this is not unprecedented: after all Windows 9x was able to run DOS, and that took no shortage of wizardry
Some interesting reading:
1. What was the role of MS-DOS in Windows 95? (https://devblogs.microsoft.com/oldnewthing/20071224-00/?p=24...)
2. Why doesn’t Windows 95 format floppy disks smoothly? (https://devblogs.microsoft.com/oldnewthing/20090102-00/?p=19...)
3. Running MS-DOS programs in a window alongside other Windows programs (https://devblogs.microsoft.com/oldnewthing/20231127-00/?p=10...)
I guess easier than https://github.com/haileys/doslinux
Well it did take me 6 years to follow that up!
Can we get an official statement on which OS your project runs inside which OS? It's left slightly unclear, for the uninitiated!
1 reply →
Modern linux kernel running cooperatively inside the Windows 9x kernel, sick!
I remember running CoLinux back in my training days ~2005-2006. It seemed a bit like black magic to me at the time, but it worked quite well for my needs.
But CoLinux - IIRC - required the NT branch of Windows. I can only imagine the level of hackery it takes to make this happen on Windows 9x.
Part of me wants to weep at the sheer perversity, part of me wants to burst into manic laughter. It is indeed a world of endless wonders.
Little late but would this have actually allowed running early Linux under Windows when Windows 95 came out in the 90s? I remember only dual booting being available at that time.
This is genius! Now I hope to run all my childhood games on a modern Ubuntu.
Hmm I wonder how stable it is.. It cannot render correctly Window control buttons (Minimize, Maximize, Close). If it fails on such basic task, I wonder where it crashes...
That's a graphics driver problem. Fairly common to see when running Windows 9x/Me under QEMU.
If I can get this to work (haven't tried yet) it directly solves a problem I have right now this week right here in 2026, 30 years after Windows 95 was even a thing.
Yes, I have weird problems. I get to look after some very weird shit.
Old still running 24/7 industrial processing circuit with oddball bespoke addons based on DOS / early windows ??
Still got those in this part of the world sharing space with state of the art autonomous 100+ tonne robo trucks.
If you're dealing with weird legacy 9x systems in 2026, another headache you've probably run into is getting them to talk to the modern web (since modern TLS and JS completely break old browsers).
I actually built a win9x compatibility mode into BrowserBox specifically for this kind of weirdness. You run the server on a modern system and launch it with bbx win9x-run, and it proxies the modern web to legacy clients. It works surprisingly well with IE5, IE6, and old Netscape on Windows 95/98/NT. Might be a fun addition to your retro utility belt!
2 replies →
Similar, radio transmitter stuff.
There is a section of the Forties Pipeline where they have a huge amount of gas handling plant in central Scotland. Last time I was on site (admittedly 15 years ago but I don't see this changing soon) the SCADA outstations were run by absolutely minty box fresh VAXStation 3100s. Plastic not even peeled off the front panel badges fresh.
When backward compatibility used to mean something man!
Tell us more!
Specialised radio transmitter stuff, involving paging. One manufacturer, still producing turnkey systems that run on Windows 95.
Probably works for a bank.
2 replies →
I want a Linux Subsystem for Windows 9x or MS-DOS :P
Isn't this exactly that but just named incorrectly?
That's called wine and dosbox.
Wouldn't that be WINE?
Everytime I see something like this, I'm like, how in the hell did they learn and then figure this out? Congrats on this!!!! I will definitely have to play with this for some of that sweet nostalga.
@haileys I would love to see that on ArcaOS! I bet it can't be done.
from the same commenter who effused
Humans are weird and can loath and desire a thing at the same time; the success of Brutalism for example.
/off to fire up Windows95 on the Octane2 and get me some hot Linux action ..
Wait until you find IE was released for Unix, using some Win32 shims. And... die hard Unix sysadmin ran it under FVWM and compared to Netscape wasn't half bad. Both propietary, but sadly NScape didn't open Mozilla yet, and the rest of the alternatives such as Arena/Amaya coudn't compete with 'modern' CSS features and the like.
Speaking of vintage IE and Netscape on old Win, it's actually still possible to use them to browse the modern web if you proxy it.
I built a Win9x compatibility mode for BrowserBox that does exactly this (https://github.com/BrowserBox/BrowserBox/blob/main/readme-fi...). Ur modern server does all the rendering, and it outputs a client link specifically designed for legacy browsers like IE5, IE6, and Netscape running on Windows 95/98/NT, streaming them the pixels. It's definitely an abomination, but there's something magical and retro that I like about viewing the 2026 internet through an IE6 window ;) ;p xx
1 reply →
> "no hardware virtualisation"
> looks inside
> virtual 8086 mode
that’s virtualization, not virtualisation
I thought this was about running windows 9x within linux. Is there such thing without virtualisation?
You can setup handlers to automatically launch windows executables using wine/proton .
This trickery is called binfmt_misc , which is a linux kernel system to associate random binary files with custom userspace 'interpreters'
I have had it working in the past. And while it is kinda neat I prefer manually running 'wine program.exe' to have a bit more control.
I have seen reports that a binfmt_misc setup + wine is good enough to get infected by certain windows viruses ;-P
Is wine compatible enough with Iloveyou.vbs?
Is this Win4Lin resurrected?
This. The post immediately reminded me of Win4Lin 9x (the version before it became just another boring VM) and SCO Merge. It was insanely fast, even on the hardware of the day.
The Wikipedia page is not verify informative and presents it as a regular VM (possibly mixing up 9x and later versions that run the NT line of kernels). The manual is a bit more informative about the tech:
ilab.usc.edu/packages/special/Win4Lin-3.0.1-manual.pdf
I’m a bit surprised it hasn’t been mentioned a lot in the comments. Maybe it’s a bit too old for most people here (Linux in the late 90ies/early 00s was a much smaller community)?
No, this runs Linux within Windows, so rather a “Lin4Win”.
Incredible that current Linux kernels still have 486 support!
Which is really weird because I thought it didn't, per https://www.theregister.com/2025/05/07/linux_kernel_drops_48...
Maybe there's some detail I don't quite follow, like is has support for 486, but only those with a built in FPU?
pretty sure 486 support only _just_ got disabled, and will be gone with 7.1: https://www.phoronix.com/news/Linux-7.1-Phasing-Out-i486
Not for long anymore, apparently.
Brilliant! Bye bye M$
Sidebar: does anyone else find the naming of this super confusing—does this mean embedding windows in linux or linux in windows? Surely we could find a way to refer to composing operating systems that isn't inherently ambiguous. Say, "linux inside of windows" would be less ambiguous.
Edit: to the people who downvoted, I corrected my spelling mistake. I will perform due penance.
Shouldn’t it be called Linux Subsystem for Windows 9x - LSW9x?
If you run it in qemu, all good.
Interesting idea. Does it actually work? If so, didn't the guy kind of simplified WSL here?
I have not tested this yet, so I have no idea - but if he managed to pull this off then this may be one of the greatest achievements this year. Or perhaps there are some restrictions to it? Does compiling stuff work in it? So many questions ... who has the answers?
Does this mean it runs on Linux or runs on Windows. I can never tell with this MS "subsystem" naming.
WSL was a subsystem to run Linux under Windows 10 without an explicit VM host. It was an Ubuntu Linux version. Later MS released WSL2, complete redesign, still for Windows 10. With Windows 11 the WSL2 also supported GUI programs.
I think the answer is "yes"
Can someone explain me the so what? Like it is impressive, but why do we need it?
Sometimes people do cool things for fun, without the express intent of maximizing their BALANCE integer in their bank's SQL table.
integer? what is this, the IRS?
Not everything needs to be "needed".
This could prompt me to finally assemble the Pentium desktop I have in storage in parts.
lol, if you do assemble that Pentium desktop, one of the first things you'll notice is that the modern web is completely unusable on it natively.
To get around that, I recently added a legacy compatibility mode to BrowserBox (bbx win9x-run). It basically lets you run the server on your modern daily driver, and access it via IE 5, IE 6, or Netscape on the Pentium box. It strips away the modern TLS/JS rendering issues and lets you actually browse the modern web from Windows 9x. Highly recommend giving it a spin if you get that machine built!
Oddly enough, I could kind of use this right now. I have some software which used SCSI (Adaptec WNASPI32.dll) calls to administer a device over the SCSI bus .. would this Subsystem be usable for that, or does it still require I build a WNASP32.dll shim to do translation?
So, you have Windows software. This "Windows 9x Subsystem for Linux" just boots Windows 95. I don't know what you would use the Linux part for. Care to explain more what you want to do?
If you want to run your windows software in Linux, you could try Wine. Wine seems to have support for WNASPI so it's possible your software would just work. (You might have to run Wine as root I guess, to get access to the SCSI devices.)
If Wine doesn't work, Windows in QEMU with PCI passthrough to the SCSI controller might have better chances to work.
I need raw SCSI I/O to be virtualizable in the linux context, so I could run a Windows app (yes it already works in Wine), and have it 'see' a SCSI device as if it were real hardware.
Wines WNASPI32.dll is really just a facade - it doesn't provide actual SCSI services, its just there for SCSI-using apps to think they have ASPI onboard - so for my case I would need to write a shim to pass through SCSI IO requests to a Linux service - or loopback file? - to actually process the requests. I've been meaning to do this for a long time, but if there is some way I can set up a loopback file under Linux to 'pretend' to be a SCSI block device for a Windows app, I'd sure like to know if its possible ..
Okay what is it with WSL naming, this always confuses me. Shouldn't it be Linux subsystem for Windows?
If you google there are many reasonable reasons for it. But the most straight forward is:
> Because we cannot name something leading with a trademark owned by someone else.
https://xcancel.com/richturn_ms/status/1245481405947076610?s...
> Because we cannot name something leading with a trademark owned by someone else.
And this WSL project is going to run into the same problem.
Should have called it LINE.
1 reply →
The core of the software is a subsystem, specifically a Windows subsystem; you're not running this subsystem on macOS or FreeBSD.
The "for Linux" is added because it's a subsystem for Linux applications (originally not leveraging a VM).
Microsoft also had the "Microsoft POSIX subsystem" (1993) and "Windows Services for UNIX" (1999) which were built on the "Subsystem for Unix-based Applications" (rather than "Unix-based Application Subsystem"). That chain of subsystems died at the end of Windows 8, though.
There are many reasons not to put "Linux" in front, but the naming is consistent with Microsoft's naming inconsistencies. It's not the first time they used "subsystem for" and it's not the first time they used "Windows x for y" either.
The naming is ambiguous, you could interpret the Windows subsystem for Linux as a subsystem of Linux (if it had such a thing) that runs Windows, or as a Windows subsystem for use with Linux. Swapping the order doesn't change that.
In other languages, the difference would be clearer.
To me, it sounds like a subsystem that provides Windows Compability for the Linux host.
I do agree it's an issue of English being an imprecise language.
2 replies →
"Windows subsystem" was an existing term of art on the NT architecture.
https://en.wikipedia.org/wiki/Windows_NT_3.1#Architecture
It’s a sub-system of Windows that is used for Linux.
It can work either way though.
My personal experience with our legal department on naming is that if your product name includes someone else's trademark, you have to say "Our Thing for Their Thing", exactly like that. I was involved in a product that did this, and we came up with some better names, but legal said no, it must be named with "for Their Thing" at the end. Those were the magic words so we don't get sued, and indeed, we weren't sued. Our legal was non-technical and never heard of WSL; they came to this conclusion independently.
The name we shipped was even worse than Windows Subsystem for Linux, honestly. At least Microsoft spent some time on it.
I always have the same problem myself. Same as I had with version naming of old programs like "Microsoft Word for Windows 2.0" instead of the easier "Microsoft Word 2.0 for Windows".
The problem is Word 2.0 for Dos was released in 1985, and Word for Windows 2.0 was released in 1991. Calling it Word 2.0 for Windows wouldn't make sense, because it wasn't the 1985 release with a new coat of paint, Word for Windows was its own thing, and this was the second version. Word for Mac was also separate, but eventually Word 6 was a common code base and it made sense to have Word 6.0 for [whatever]
Other people already answered but windows was just another personality on the original idea that cutler had for WNT. It just took a while for it to get implemented as a linux
The Showstoppers book by G. Pascal Zachary is an entertaining account of NT uprising.
To reciprocate the naming of Wine, maybe it could have been named Line. Also, both have this positive clang, being associated with "having a good time".
Windows' subsystem for Linux
(Windows 9x) (Subsystem for Linux)
It's a dominance thing. Classic abuser behaviour.
Yeah, you'd think from this that it is running Linux on Windows 9x.
Microsoft names of products turn around likes, e.g.
OpenOffice XML [1] -> Office Open XML [2]
[1] https://www.openoffice.org/xml/general.html
[2] https://en.wikipedia.org/wiki/Office_Open_XML
That's cool
I mean it's like trying to balance a cybetruck into 4 skateboards and flunging it over a hill cool