Mac maintenance
How to Check Your Exact macOS Build Number From the Terminal
Get the exact macOS version, build number, and kernel info from the Terminal — for support tickets, version checks, and scripting compatibility.
You’re filing a Radar with Apple. The bug only happens on certain builds. The “About This Mac” window says “Sequoia 15.3” but Apple’s build numbers look like “24D60.” You need the actual build to make the bug report useful.
Or you’re writing a script that has to behave differently between Sonoma and Sequoia. The major version isn’t enough — sometimes you need to gate on the patch version or even the specific build.
The Terminal commands for this are tiny. Here are the four worth knowing.
sw_vers — the basic info
sw_vers
Output:
ProductName: macOS
ProductVersion: 15.3.2
BuildVersion: 24D81
That’s the canonical “what version is this” command. Three fields:
ProductName— alwaysmacOSon a Mac. (WasMac OS Xuntil Big Sur.)ProductVersion— the marketing version: 15.3.2 = Sequoia 15.3.2.BuildVersion— the internal build identifier. Apple uses these in release notes, support docs, and bug reports.
To extract a single field:
sw_vers -productVersion
sw_vers -buildVersion
sw_vers -productName
Each returns just one value, no label. Useful for scripts:
if [[ $(sw_vers -productVersion) == 15.* ]]; then
echo "Running Sequoia"
fi
Decoding build numbers
Apple’s build numbers follow a pattern: <major><minor letter><build number>[<release suffix>].
- Major number: the macOS Darwin major. Sequoia is 24, Sonoma is 23, Ventura is 22.
- Letter: the minor version.
Ais the initial release,Bthe first dot-release,Cthe next, and so on. - Number: the build of that release.
- Optional letter at the end: lowercase letters indicate special builds.
ais a security update, others are betas or other variants.
Example: 24D81 = Sequoia (24), fourth update letter (D), build 81. So roughly the 81st version of macOS 15.3.
24A335 was the original Sequoia release.
This isn’t documented officially, but it’s stable enough across decades that you can rely on it for sorting and comparison.
uname — kernel info
uname -a
Output:
Darwin MacBook-Pro.local 24.3.0 Darwin Kernel Version 24.3.0: Wed Mar 27 10:23:47 PDT 2025; root:xnu-11215.81.4~1/RELEASE_ARM64_T6020 arm64
Reading left to right:
Darwin— the OS family. macOS’s Unix layer.- The hostname.
- Kernel version: 24.3.0. Roughly tracks the macOS version (Sequoia 15.3 → kernel 24.3).
- Kernel build date.
- The xnu (kernel) release.
- The architecture:
arm64for Apple Silicon,x86_64for Intel.
Individual flags:
uname -s # Kernel name (Darwin)
uname -r # Kernel release (24.3.0)
uname -m # Architecture (arm64 or x86_64)
uname -p # Processor type (often the same as -m on macOS)
uname -v # Full kernel version string
uname -n # Hostname
The architecture check is the one you’ll script most often:
if [[ $(uname -m) == arm64 ]]; then
brew_prefix=/opt/homebrew
else
brew_prefix=/usr/local
fi
That’s the standard “is this Apple Silicon?” check. Homebrew lives in different places on the two architectures, and a lot of scripts have to branch on it.
Architecture: detecting Rosetta
Just running uname -m on Apple Silicon returns arm64. But if you’re running inside a Terminal launched with Rosetta (right-click → Get Info → “Open using Rosetta”), uname -m returns x86_64. The shell is being emulated.
To know whether you’re on a Mac that can run arm64, regardless of what the current process sees:
sysctl -n hw.optional.arm64
Returns 1 on Apple Silicon, 0 on Intel. This goes through the kernel directly and isn’t affected by Rosetta.
Combined check:
NATIVE_ARCH=$(sysctl -n hw.optional.arm64)
RUNNING_ARCH=$(uname -m)
if [[ $NATIVE_ARCH == 1 && $RUNNING_ARCH == x86_64 ]]; then
echo "Apple Silicon Mac running this shell under Rosetta"
fi
Useful when something keeps installing the wrong architecture’s binaries.
system_profiler — the full picture
For more than the basics:
system_profiler SPSoftwareDataType
Returns:
Software:
System Software Overview:
System Version: macOS 15.3.2 (24D81)
Kernel Version: Darwin 24.3.0
Boot Volume: Macintosh HD
Boot Mode: Normal
Computer Name: My MacBook Pro
User Name: you (you)
Secure Virtual Memory: Enabled
System Integrity Protection: Enabled
Time since boot: 14 days, 3 hours, 25 minutes
That’s the whole picture in one command — version, build, kernel, SIP status, uptime. Useful when filing a bug or just doing a one-shot health check.
For the same in JSON:
system_profiler -json SPSoftwareDataType
Pipe through jq to extract specific fields:
system_profiler -json SPSoftwareDataType | \
jq '.SPSoftwareDataType[0].os_version'
Returns the version string with quotes. Add -r to jq for unquoted.
Comparing versions in scripts
The naive string comparison breaks for versions with multiple parts:
[[ "15.3.10" > "15.3.9" ]] # FALSE in lexical comparison
(Because 1 < 9 lexically.)
The cleanest solution is sort -V:
if printf '%s\n%s\n' "15.3.9" "$(sw_vers -productVersion)" | sort -V -C; then
echo "Current macOS is at least 15.3.9"
fi
sort -V -C returns 0 (success) if the input is already sorted in version order. So if our threshold version comes first and the current version comes after, the test passes.
A simpler form for “is it 15 or higher”:
MAJOR=$(sw_vers -productVersion | cut -d. -f1)
if (( MAJOR >= 15 )); then
echo "Sequoia or later"
fi
That’s enough for most “is it new enough to have feature X” checks.
When the version isn’t enough
For Mac admins managing fleets, you sometimes need more granular state:
diskutil info / | grep "Mount Point"
diskutil info / | grep "OS Version"
Returns the OS version of the boot volume. On a Mac that booted from an external drive, this can differ from the running OS — useful sanity check.
spctl --status
Tells you whether Gatekeeper is enabled.
csrutil status
System Integrity Protection status. enabled means SIP is on (default and recommended). disabled means someone turned it off, usually for development.
fdesetup status
FileVault encryption status.
These aren’t version info per se, but they’re the same kind of “what’s the state of this Mac” data that often gets bundled with the version when you’re filing a support ticket.
A summary one-liner
A handy combo for “give me everything for the support ticket”:
echo "macOS: $(sw_vers -productVersion) ($(sw_vers -buildVersion))"
echo "Kernel: $(uname -r)"
echo "Arch: $(uname -m)"
echo "Native: $(sysctl -n hw.optional.arm64 | sed 's/0/Intel/;s/1/Apple Silicon/')"
echo "SIP: $(csrutil status | awk '{print $5}' | tr -d '.')"
echo "FV: $(fdesetup status | head -1)"
echo "Uptime: $(uptime | awk -F'up ' '{print $2}' | awk -F',' '{print $1}')"
Output:
macOS: 15.3.2 (24D81)
Kernel: 24.3.0
Arch: arm64
Native: Apple Silicon
SIP: enabled
FV: FileVault is On.
Uptime: 14 days
Drop that in ~/bin/macinfo and run it before every support thread.
What about XPI/Beta channels?
If you’re on a developer beta, the build number’s release suffix changes. A regular release is 24D81. A developer beta might be 24E5212a or similar. The lowercase letter at the end is the marker.
sw_vers -buildVersion | grep -q '[a-z]$' && echo "Beta build"
That’s a quick check. Useful when troubleshooting “is this bug because I’m on a beta?”
Checking against a known release matrix
For scripts that need feature gating:
MACOS_VERSION=$(sw_vers -productVersion)
case "$MACOS_VERSION" in
15.*)
echo "Sequoia"
;;
14.*)
echo "Sonoma"
;;
13.*)
echo "Ventura"
;;
12.*)
echo "Monterey"
;;
*)
echo "Older or unknown: $MACOS_VERSION"
;;
esac
Apple has a stable mapping of major version to marketing name; you can hardcode this in setup scripts.
When sw_vers is wrong
Almost never, but: if you’ve been migrating between Macs and the system has gotten confused, sw_vers reads from /System/Library/CoreServices/SystemVersion.plist. On a healthy system this matches the running OS. If it’s been corrupted, a reinstall is the fix — manually editing isn’t worth the headache.
A quick sanity check:
plutil -p /System/Library/CoreServices/SystemVersion.plist
If this disagrees with sw_vers (it shouldn’t), there’s a deeper problem.
Why this matters
A surprising amount of Mac troubleshooting comes down to “are you on the version where this bug was fixed?” The answer is often no, and the cure is softwareupdate --install -a followed by a reboot. But you have to know your starting point.
For scripting: the rule “test the OS version, not the feature” applies on Mac like everywhere else, but the corollary is “don’t gate on marketing version when you can gate on a real capability.” A script that says “if macOS 15+, use the new tmutil flag” will eventually break if Apple changes the flag again. A script that asks “does tmutil --help mention this option?” stays accurate.
The cheat sheet
sw_vers # full version info
sw_vers -productVersion # just the version (15.3.2)
sw_vers -buildVersion # just the build (24D81)
uname -m # arm64 or x86_64
uname -r # kernel version
sysctl -n hw.optional.arm64 # is the hardware Apple Silicon?
system_profiler SPSoftwareDataType # everything at once
Six commands. With those, you can answer any “what version is this Mac running?” question, including the ones the Settings app doesn’t bother to show you.