diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,10 +2,19 @@
 
 Version history.
 
+## 0.0.9 released 2022-08-10
+
+- New option `--tab` to set tab-size or keep tabs
+  [#31](https://github.com/agda/fix-whitespace/issues/31).
+- Tested with GHC 8.0.2 - 9.4.1.
+
 ## 0.0.8 released 2022-05-29
 
-- New option `--version` displaying program version.
-- Tested with GHC 8.0.2 - 9.4.1 alpha.
+- New option `--version` displaying program version
+  [#33](https://github.com/agda/fix-whitespace/pull/33).
+- Skip files that are not UTF8 encoded, rather than crashing
+  [#29](https://github.com/agda/fix-whitespace/issues/29).
+- Tested with GHC 8.0.2 - 9.2.2 and 9.4.1 alpha.
 
 ## 0.0.7 released 2021-09-07
 
diff --git a/FixWhitespace.hs b/FixWhitespace.hs
--- a/FixWhitespace.hs
+++ b/FixWhitespace.hs
@@ -12,15 +12,17 @@
 import qualified Data.Text as Text
 import qualified Data.Text.IO as Text  -- Strict IO.
 
-import System.Directory ( getCurrentDirectory, doesFileExist)
+import System.Directory (getCurrentDirectory, doesFileExist)
 import System.Environment
 import System.Exit
 -- import System.FilePath
 -- import System.FilePattern
-import System.FilePattern.Directory
+import System.FilePattern.Directory (getDirectoryFiles, getDirectoryFilesIgnore)
 import System.IO
 import System.Console.GetOpt
 
+import Text.Read (readMaybe)
+
 import ParseConfig
 import qualified Paths_fix_whitespace as PFW (version)
 
@@ -29,6 +31,11 @@
 defaultConfigFile :: String
 defaultConfigFile = "fix-whitespace.yaml"
 
+-- | Default tab size.
+
+defaultTabSize :: String
+defaultTabSize = "8"
+
 -- Modes.
 data Mode
   = Fix    -- ^ Fix whitespace issues.
@@ -36,6 +43,7 @@
     deriving (Show, Eq)
 
 type Verbose = Bool
+type TabSize = Int
 
 data Options = Options
   { optVerbose :: Verbose
@@ -47,6 +55,8 @@
   , optMode    :: Mode
   , optConfig  :: FilePath
   -- ^ The location to the configuration file.
+  , optTabSize :: String
+  -- ^ The number of spaces to expand a tab character to.  @"0"@ for keeping tabs.
   }
 
 defaultOptions :: Options
@@ -56,6 +66,7 @@
   , optVersion = False
   , optMode    = Fix
   , optConfig  = defaultConfigFile
+  , optTabSize = defaultTabSize
   }
 
 options :: [OptDescr (Options -> Options)]
@@ -69,6 +80,12 @@
   , Option ['v']     ["verbose"]
       (NoArg (\opts -> opts { optVerbose = True }))
       "Show files as they are being checked."
+  , Option ['t']     ["tab"]
+      (ReqArg (\ts opts -> opts { optTabSize = ts }) "TABSIZE")
+      (unlines
+        [ "Expand tab characters to TABSIZE (default: " ++ defaultTabSize ++ ") many spaces."
+        , "Keep tabs if 0 is given as TABSIZE."
+        ])
   , Option []        ["config"]
       (ReqArg (\loc opts -> opts { optConfig = loc }) "CONFIG")
       (concat ["Override the project configuration ", defaultConfigFile, "."])
@@ -77,7 +94,7 @@
       (unlines
         [ "With --check the program does not change any files,"
         , "it just checks if any files would have been changed."
-        , "In this case it returns with a non-zero exit code."
+        , "In the latter case it returns with a non-zero exit code."
         ])
   ]
 
@@ -90,8 +107,11 @@
 
 
 shortUsageHeader :: String -> String
-shortUsageHeader progName =
-  "Usage: " ++ progName ++ " [-h|--help] [-v|--verbose] [--check] [--config CONFIG] [FILES]"
+shortUsageHeader progName = unwords
+  [ "Usage:"
+  , progName
+  , "[-h|--help] [-v|--verbose] [--check] [--config CONFIG] [-t|--tab TABSIZE] [FILES]"
+  ]
 
 usageHeader :: String -> String
 usageHeader progName = unlines
@@ -102,11 +122,11 @@
   , "  * Removes trailing whitespace."
   , "  * Removes trailing lines containing nothing but whitespace."
   , "  * Ensures that the file ends in a newline character."
-  , "  * Convert tabs to spaces, assuming a tab-size of 8."
+  , "  * Convert tabs to TABSIZE (default: " ++ defaultTabSize ++ ") spaces, unless TABSIZE is set to 0."
   , ""
   , "for files specified in [FILES] or"
   , ""
-  , "\t" ++ optConfig defaultOptions
+  , "\t" ++ defaultConfigFile
   , ""
   , "under the current directory."
   , ""
@@ -141,6 +161,9 @@
       verbose = optVerbose opts
       config  = optConfig  opts
 
+  tabSize <- maybe (die "Error: Illegal TABSIZE, must be an integer.") return $
+    readMaybe $ optTabSize opts
+
   base <- getCurrentDirectory
 
   files <- if not $ null nonOpts
@@ -180,13 +203,13 @@
       files1 <- getDirectoryFilesIgnore base incPatterns excPatterns
       return (nubOrd (files0 ++ files1))
 
-  changes <- mapM (fix mode verbose) files
+  changes <- mapM (fix mode verbose tabSize) files
 
   when (or changes && mode == Check) exitFailure
 
-fix :: Mode -> Verbose -> FilePath -> IO Bool
-fix mode verbose f =
-  checkFile f >>= \case
+fix :: Mode -> Verbose -> TabSize -> FilePath -> IO Bool
+fix mode verbose tabSize f =
+  checkFile tabSize f >>= \case
 
     CheckOK -> do
       when verbose $
@@ -223,19 +246,22 @@
 -- | Check a file against the whitespace policy,
 --   returning a fix if violations occurred.
 
-checkFile :: FilePath -> IO CheckResult
-checkFile f =
+checkFile :: TabSize -> FilePath -> IO CheckResult
+checkFile tabSize f =
   handle (\ (e :: IOException) -> return $ CheckIOError e) $
     withFile f ReadMode $ \ h -> do
       hSetEncoding h utf8
       s <- Text.hGetContents h
-      let s' = transform s
+      let s' = transform tabSize s
       return $ if s' == s then CheckOK else CheckViolation s'
 
 -- | Transforms the contents of a file.
 
-transform :: Text -> Text
-transform =
+transform
+  :: TabSize   -- ^ Expand tab characters to so many spaces.  Keep tabs if @<= 0@.
+  -> Text      -- ^ Text before transformation.
+  -> Text      -- ^ Text after transformation.
+transform tabSize =
   Text.unlines .
   removeFinalEmptyLinesExceptOne .
   map (removeTrailingWhitespace .  convertTabs) .
@@ -247,12 +273,12 @@
   removeTrailingWhitespace =
     Text.dropWhileEnd ((`elem` [Space,Format]) . generalCategory)
 
-  convertTabs =
+  convertTabs = if tabSize <= 0 then id else
     Text.pack . reverse . fst . foldl convertOne ([], 0) . Text.unpack
 
   convertOne (a, p) '\t' = (addSpaces n a, p + n)
                            where
-                             n = 8 - p `mod` 8
+                             n = tabSize - p `mod` tabSize  -- Here, tabSize > 0 is guaranteed
   convertOne (a, p) c = (c:a, p+1)
 
   addSpaces :: Int -> String -> String
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@
   * Remove trailing whitespace.
   * Remove trailing lines containing nothing but whitespace.
   * Ensure that the file ends in a newline character.
+  * Expand tabs to spaces (optionally).
 
 Available options:
 
@@ -38,10 +39,15 @@
 
    Override the project configuration `fix-whitespace.yaml`.
 
+*  `--tab=TABSIZE`
+
+   Expand tab characters to TABSIZE (default: 8) many spaces.
+   Keep tabs if 0 is given as TABSIZE.  _(Option available since 0.0.9.)_
+
 *  `--check`
 
    With `--check` the program does not change any files,
    it just checks if any files would have been changed.
-   In this case it returns with a non-zero exit code.
+   In the latter case, it returns with a non-zero exit code.
 
 For an example configuration file see [the one of Agda](https://github.com/agda/agda/blob/f9a181685397517b5d14943ca88a1c0acacc2075/fix-whitespace.yaml).
diff --git a/fix-whitespace.cabal b/fix-whitespace.cabal
--- a/fix-whitespace.cabal
+++ b/fix-whitespace.cabal
@@ -1,8 +1,9 @@
 name:            fix-whitespace
-version:         0.0.8
+version:         0.0.9
 cabal-version:   1.24
 build-type:      Simple
-description:     Removes trailing whitespace, lines containing only whitespace and ensure that every file ends in a newline character.
+description:     Removes trailing whitespace, lines containing only whitespace, expands tabs,
+                 and ensures that every file ends in a newline character.
 license:         OtherLicense
 license-file:    LICENSE
 author:          fix-whitespace was originally written by Nils Anders Danielsson as part of Agda 2 with contributions from Ulf Norell, Andrés Sicard-Ramírez, Andreas Abel, Philipp Hausmann, Jesper Cockx, Vlad Semenov, and Liang-Ting Chen.
@@ -13,7 +14,7 @@
 Synopsis:        Fixes whitespace issues.
 tested-with:
   GHC == 9.4.1
-  GHC == 9.2.3
+  GHC == 9.2.4
   GHC == 9.0.2
   GHC == 8.10.7
   GHC == 8.8.4
@@ -33,7 +34,7 @@
   stack-8.8.4.yaml
   stack-8.10.7.yaml
   stack-9.0.2.yaml
-  stack-9.2.2.yaml
+  stack-9.2.4.yaml
 
 source-repository head
   type: git
diff --git a/stack-9.2.2.yaml b/stack-9.2.2.yaml
deleted file mode 100644
--- a/stack-9.2.2.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-resolver: nightly-2022-05-28
-compiler: ghc-9.2.2
-compiler-check: match-exact
diff --git a/stack-9.2.4.yaml b/stack-9.2.4.yaml
new file mode 100644
--- /dev/null
+++ b/stack-9.2.4.yaml
@@ -0,0 +1,3 @@
+resolver: nightly-2022-08-04
+compiler: ghc-9.2.4
+compiler-check: match-exact
