diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -3,6 +3,11 @@
 
 * Latest Hackage released version: 3.15, 2024-11-09
 
+### Version 3.16, 2026-07-24
+
+  * Add the `--gui` option, launching a graphical interface (macOS) for
+    interactively encoding/decoding values.
+
 ### Version 3.15, 2024-11-09
 
   * Bump up SBV dependence to >= 11.0
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -115,6 +115,36 @@
              Hex: 0x1.f18p-8
 ```
 
+### Graphical interface (macOS, optional)
+
+Optionally, crackNum comes with a native macOS GUI: pick a format on the left,
+type a value, and see the encoding/decoding in detail. It is entirely optional —
+crackNum is fully functional as a command-line tool without it. The GUI is just
+a thin front-end that calls the `crackNum` binary underneath, so it supports
+exactly the same formats.
+
+![crackNum macOS GUI](https://raw.githubusercontent.com/LeventErkok/crackNum/master/crackNumGUI.png)
+
+Building it requires the Swift compiler that comes with the Xcode Command Line
+Tools (`xcode-select --install`). From a checkout of this repository:
+
+```
+$ cd gui
+$ make install      # builds CrackNum.app and copies it into /Applications
+```
+
+Once installed, launch it from Spotlight/Launchpad, or straight from the
+command line via the `--gui` option, which forwards any format/rounding flags
+and value to the app:
+
+```
+$ crackNum --gui                 -- open the graphical interface
+$ crackNum --gui -fsp 2.5        -- open it with single-precision selected, and 2.5 cracked
+$ crackNum --gui 0xdeadbeef      -- open it pre-filled with a value to decode
+```
+
+See [`gui/README.md`](gui/README.md) for more details and other build targets.
+
 ### Usage info
 ```
 Usage: crackNum value OR binary/hex-pattern
@@ -126,6 +156,7 @@
   -h, -?    --help     print help, with examples
   -v        --version  print version info
   -d        --debug    debug mode, developers only
+            --gui      launch the graphical interface (macOS)
 
 Examples:
  Encoding:
@@ -147,6 +178,10 @@
    crackNum -fdp     0x8000000000000000    -- decode as a double-precision float
    crackNum -fhp     0x8000                -- decode as a half-precision float
    crackNum -l4 -fhp 64\'hbdffaaffdc71fc60 -- decode as half-precision float over 4 lanes using verilog notation
+
+ GUI (macOS):
+   crackNum --gui                     -- launch the graphical interface
+   crackNum --gui 0xdeadbeef          -- launch the GUI, pre-filled with the given value
 
  Notes:
    - For encoding:
diff --git a/crackNum.cabal b/crackNum.cabal
--- a/crackNum.cabal
+++ b/crackNum.cabal
@@ -1,6 +1,6 @@
 Cabal-version      : 2.2
 Name               : crackNum
-Version            : 3.15
+Version            : 3.16
 Synopsis           : Crack various integer and floating-point data formats
 Description        : Crack IEEE-754 float formats and arbitrary sized words and integers, showing the layout.
                      .
@@ -15,11 +15,9 @@
 Build-type         : Simple
 Extra-Source-Files : README.md, COPYRIGHT, CHANGES.md
 
-Tested-With       : GHC==9.10.1
-
 source-repository head
     type:       git
-    location:   git://github.com/LeventErkok/crackNum.git
+    location:   https://github.com/LeventErkok/crackNum.git
 
 Executable crackNum
    main-is         : CrackNum/Main.hs
diff --git a/src/CrackNum/Main.hs b/src/CrackNum/Main.hs
--- a/src/CrackNum/Main.hs
+++ b/src/CrackNum/Main.hs
@@ -30,10 +30,12 @@
 import qualified Control.Exception as C
 
 import Text.Read             (readMaybe)
-import System.Environment    (getArgs, getProgName, withArgs)
+import System.Environment    (getArgs, getProgName, withArgs, lookupEnv)
 import System.Console.GetOpt (ArgOrder(Permute), getOpt, ArgDescr(..), OptDescr(..), usageInfo)
-import System.Exit           (exitFailure)
+import System.Exit           (exitFailure, ExitCode(..))
 import System.IO             (hPutStr, stderr)
+import System.Process        (rawSystem)
+import qualified System.Info as Info
 
 import LibBF
 import Numeric
@@ -116,6 +118,7 @@
           | BadFlag  [String]  -- ^ Bad input
           | Version            -- ^ Version
           | Debug              -- ^ Run in debug mode. Debugging only.
+          | GUI                -- ^ Launch the graphical interface
           | Help               -- ^ Show help
           deriving (Show, Eq)
 
@@ -221,6 +224,7 @@
     , Option "h?" ["help"]    (NoArg Help)                             "print help, with examples"
     , Option "v"  ["version"] (NoArg Version)                          "print version info"
     , Option "d"  ["debug"]   (NoArg Debug)                            "debug mode, developers only"
+    , Option ""   ["gui"]     (NoArg GUI)                              "launch the graphical interface (macOS)"
     ]
 
 -- | Help info
@@ -251,6 +255,10 @@
                             , "   " ++ pn ++ " -fhp     0x8000                -- decode as a half-precision float"
                             , "   " ++ pn ++ " -l4 -fhp 64\\'hbdffaaffdc71fc60 -- decode as half-precision float over 4 lanes using verilog notation"
                             , ""
+                            , " GUI (macOS):"
+                            , "   " ++ pn ++ " --gui                     -- launch the graphical interface"
+                            , "   " ++ pn ++ " --gui 0xdeadbeef          -- launch the GUI, pre-filled with the given value"
+                            , ""
                             , " Notes:"
                             , "   - For encoding:"
                             , "       - Use -- to separate your argument if it's a negative number."
@@ -269,6 +277,38 @@
 die xs = do hPutStr stderr $ unlines $ "ERROR:" : map ("  " ++) xs
             exitFailure
 
+-- | Launch the graphical interface (macOS only), forwarding all remaining arguments
+-- (format flags, rounding mode, and/or the value to crack) so the GUI can preselect
+-- them. The GUI itself calls back into this executable to do the actual cracking. The
+-- location of the app can be overridden with the CRACKNUM_GUI environment variable
+-- (pointing at the .app bundle); otherwise we ask LaunchServices to find it by name.
+launchGUI :: [String] -> IO ()
+launchGUI vals
+  | Info.os /= "darwin"
+  = die [ "The --gui option is only available on macOS."
+        , "On other platforms, use crackNum directly from the command line."
+        ]
+  | True
+  = do mbApp <- lookupEnv "CRACKNUM_GUI"
+       let args = case mbApp of
+                    Just p  -> ["-n", p,                "--args"] ++ vals
+                    Nothing -> ["-n", "-a", "CrackNum", "--args"] ++ vals
+       ec <- rawSystem "open" args
+       case ec of
+         ExitSuccess   -> pure ()
+         ExitFailure _ -> die [ "Unable to launch the CrackNum GUI application."
+                              , ""
+                              , "The CrackNum GUI app does not seem to be installed. To install it,"
+                              , "get the crackNum sources and build the GUI (macOS 13+, Swift toolchain):"
+                              , ""
+                              , "    git clone http://github.com/LeventErkok/crackNum.git"
+                              , "    cd crackNum/gui"
+                              , "    make install       # builds and copies CrackNum.app into /Applications"
+                              , ""
+                              , "Then re-run: crackNum --gui" ++ (if null vals then "" else ' ' : unwords vals)
+                              ]
+
+
 -- | main entry point to crackNum
 crack :: String -> [String] -> IO ()
 crack pn argv = case getOpt Permute pgmOptions argv of
@@ -276,6 +316,7 @@
                   (os, rs, [])
                     | Version `elem` os -> putStrLn $ pn ++ " v" ++ showVersion version ++ ", " ++ copyRight
                     | Help    `elem` os -> usage pn
+                    | GUI     `elem` os -> launchGUI (filter (/= "--gui") argv)
                     | True              -> do let rm = case reverse [r | RMode r <- os] of
                                                          (r:_) -> r
                                                          _     -> RNE
