diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
 # Changelog
 
+## 0.2.3.0 — 2026-02-23
+
+- Drop `unix` dependency — `checkExecutable` now uses cross-platform
+  `System.Directory.getPermissions` instead of `System.Posix.Files`
+- Fixes Windows build (the `unix` package is not available on Windows)
+- No API changes
+
 ## 0.2.2.0 — 2026-02-23
 
 - Gate `NovaCache.Compression` and `lzma` dependency behind a `compression`
diff --git a/nova-cache.cabal b/nova-cache.cabal
--- a/nova-cache.cabal
+++ b/nova-cache.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               nova-cache
-version:            0.2.2.0
+version:            0.2.3.0
 synopsis:           Pure Nix binary cache protocol library
 description:
   A focused, minimal, pure-first library implementing the full Nix binary
@@ -57,8 +57,8 @@
     , filepath            >= 1.4 && < 1.6
     , memory              >= 0.18 && < 1
     , text                >= 2.0 && < 2.2
-    , unix                >= 2.7 && < 2.9
     , vector              >= 0.12 && < 0.14
+
 
   hs-source-dirs:   src
   default-language:  Haskell2010
diff --git a/src/NovaCache/NAR.hs b/src/NovaCache/NAR.hs
--- a/src/NovaCache/NAR.hs
+++ b/src/NovaCache/NAR.hs
@@ -35,12 +35,13 @@
 import System.Directory
   ( doesDirectoryExist,
     doesFileExist,
+    executable,
+    getPermissions,
     getSymbolicLinkTarget,
     listDirectory,
     pathIsSymbolicLink,
   )
 import System.FilePath ((</>))
-import qualified System.Posix.Files as Posix
 
 -- ---------------------------------------------------------------------------
 -- Types
@@ -337,8 +338,8 @@
       pure (NarRegular isExec contents)
     else pure (NarRegular False BS.empty)
 
--- | Check whether a file has the owner-execute permission set.
+-- | Check whether a file has the executable permission set.
+-- Uses 'System.Directory.getPermissions' which is cross-platform:
+-- checks the user-execute bit on Unix, file extension on Windows.
 checkExecutable :: FilePath -> IO Bool
-checkExecutable path = do
-  status <- Posix.getFileStatus path
-  pure (Posix.fileMode status .&. Posix.ownerExecuteMode /= 0)
+checkExecutable path = executable <$> getPermissions path
