Map the system
Separate macOS, Darwin, and the kernel
Connect the macOS product version to the Darwin kernel version without treating their version numbers as interchangeable.
10 minute lesson
macOS is the complete operating system: the kernel, the UNIX layer, the frameworks, and everything you see on screen. Darwin is its open-source UNIX foundation, and XNU is the kernel that manages processes, memory, devices, and system calls.
You care about the split because different tools report different version numbers, and mixing them up sends a bug report or a web search in the wrong direction.
Two version schemes
Compare the product and kernel views:
sw_vers
ProductName: macOS
ProductVersion: 26.1
BuildVersion: 25B78
Read three fields. ProductVersion is the marketing version users talk about. BuildVersion identifies the exact build, which matters when a bug exists in one build and not the next.
Now ask the kernel:
uname -a
# Darwin studio.local 25.1.0 Darwin Kernel Version 25.1.0 ... RELEASE_ARM64_T6031 arm64
The first number after the hostname is the Darwin release. The macOS and Darwin version numbers follow different schemes: macOS 26 ships Darwin 25, and macOS 15 shipped Darwin 24. They move together but never match.
Why the layers matter when troubleshooting
When you read the unified log, kernel events come from the XNU layer. When you run ls or ps, you are using Darwin’s BSD userland. When an app misbehaves in System Settings, you are in the macOS product layer. Knowing which layer produced a message tells you which documentation to read.
One more kernel-adjacent fact worth knowing: modern macOS pushes most third-party drivers out of the kernel. System extensions run in user space, while legacy kernel extensions are being phased out. A misbehaving “driver” today is usually a user-space process you can inspect like any other.
The mistake to avoid
Record both versions when diagnosing low-level software, because a report that says only “version 25” is ambiguous. Is that Darwin 25 or a macOS release? You cannot tell, and neither can the person reading your report. Paste the output of sw_vers and uname -a verbatim and the ambiguity disappears.
Lesson completed