diff --git a/System/FilePath/Internal.hs b/System/FilePath/Internal.hs
--- a/System/FilePath/Internal.hs
+++ b/System/FilePath/Internal.hs
@@ -129,10 +129,10 @@
 #define STRING String
 #define FILEPATH FilePath
 #else
-import Prelude (fromIntegral)
-import Control.Exception ( SomeException, evaluate, try, displayException )
+import Prelude (fromIntegral, return, IO, Either(..))
+import Control.Exception ( catch, displayException, evaluate, fromException, toException, throwIO, Exception, SomeAsyncException(..), SomeException )
 import Control.DeepSeq (force)
-import GHC.IO (unsafePerformIO)
+import System.IO.Unsafe (unsafePerformIO)
 import qualified Data.Char as C
 #ifdef WINDOWS
 import GHC.IO.Encoding.Failure ( CodingFailureMode(..) )
@@ -1270,15 +1270,31 @@
 snoc str = \c -> str <> [c]
 
 #else
+-- | Like 'try', but rethrows async exceptions.
+trySafe :: Exception e => IO a -> IO (Either e a)
+trySafe ioA = catch action eHandler
+ where
+  action = do
+    v <- ioA
+    return (Right v)
+  eHandler e
+    | isAsyncException e = throwIO e
+    | otherwise = return (Left e)
+
+isAsyncException :: Exception e => e -> Bool
+isAsyncException e =
+    case fromException (toException e) of
+        Just (SomeAsyncException _) -> True
+        Nothing -> False
 #ifdef WINDOWS
 fromString :: P.String -> STRING
 fromString str = P.either (P.error . P.show) P.id $ unsafePerformIO $ do
-  r <- try @SomeException $ GHC.withCStringLen (mkUTF16le ErrorOnCodingFailure) str $ \cstr -> packCStringLen cstr
+  r <- trySafe @SomeException $ GHC.withCStringLen (mkUTF16le ErrorOnCodingFailure) str $ \cstr -> packCStringLen cstr
   evaluate $ force $ first displayException r
 #else
 fromString :: P.String -> STRING
 fromString str = P.either (P.error . P.show) P.id $ unsafePerformIO $ do
-  r <- try @SomeException $ GHC.withCStringLen (mkUTF8 ErrorOnCodingFailure) str $ \cstr -> packCStringLen cstr
+  r <- trySafe @SomeException $ GHC.withCStringLen (mkUTF8 ErrorOnCodingFailure) str $ \cstr -> packCStringLen cstr
   evaluate $ force $ first displayException r
 #endif
 
diff --git a/System/OsPath/Common.hs b/System/OsPath/Common.hs
--- a/System/OsPath/Common.hs
+++ b/System/OsPath/Common.hs
@@ -124,20 +124,34 @@
 import Data.Bifunctor ( bimap )
 import qualified System.OsPath.Windows.Internal as C
 import GHC.IO.Encoding.UTF16 ( mkUTF16le )
-import Language.Haskell.TH.Quote
+#if __GLASGOW_HASKELL__ >= 914
+import Language.Haskell.TH.Lift
+    ( Lift(..), lift )
+import Language.Haskell.TH.QuasiQuoter
     ( QuasiQuoter (..) )
+#else
 import Language.Haskell.TH.Syntax
-    ( Lift (..), lift )
+    ( Lift(..), lift )
+import Language.Haskell.TH.Quote
+    ( QuasiQuoter (..) )
+#endif
 import GHC.IO.Encoding.Failure ( CodingFailureMode(..) )
 import Control.Monad ( when )
 
 #elif defined(POSIX)
 import GHC.IO.Encoding.Failure ( CodingFailureMode(..) )
 import Control.Monad ( when )
-import Language.Haskell.TH.Quote
+#if __GLASGOW_HASKELL__ >= 914
+import Language.Haskell.TH.Lift
+    ( Lift(..), lift )
+import Language.Haskell.TH.QuasiQuoter
     ( QuasiQuoter (..) )
+#else
 import Language.Haskell.TH.Syntax
-    ( Lift (..), lift )
+    ( Lift(..), lift )
+import Language.Haskell.TH.Quote
+    ( QuasiQuoter (..) )
+#endif
 
 import GHC.IO.Encoding.UTF8 ( mkUTF8 )
 import System.OsPath.Types
diff --git a/System/OsPath/Internal.hs b/System/OsPath/Internal.hs
--- a/System/OsPath/Internal.hs
+++ b/System/OsPath/Internal.hs
@@ -15,17 +15,28 @@
     ( MonadThrow )
 import Data.ByteString
     ( ByteString )
-import Language.Haskell.TH.Quote
+#if __GLASGOW_HASKELL__ >= 914
+import Language.Haskell.TH.Lift
+    ( Lift(..), lift )
+import Language.Haskell.TH.QuasiQuoter
     ( QuasiQuoter (..) )
+#else
 import Language.Haskell.TH.Syntax
-    ( Lift (..), lift )
+    ( Lift(..), lift )
+import Language.Haskell.TH.Quote
+    ( QuasiQuoter (..) )
+#endif
 import GHC.IO.Encoding.Failure ( CodingFailureMode(..) )
 
 import System.OsString.Internal.Types
 import System.OsPath.Encoding
 import Control.Monad (when)
+#if !defined(__MHS__)
 import System.IO
     ( TextEncoding )
+#else
+import GHC.IO.Encoding.Types ( TextEncoding )
+#endif
 
 #if defined(mingw32_HOST_OS) || defined(__MINGW32__)
 import qualified System.OsPath.Windows as PF
@@ -124,6 +135,7 @@
 
 
 
+#if defined(MIN_VERSION_template_haskell) || defined(MIN_VERSION_template_haskell_quasiquoter)
 -- | QuasiQuote an 'OsPath'. This accepts Unicode characters
 -- and encodes as UTF-8 on unix and UTF-16LE on windows. Runs 'isValid'
 -- on the input. If used as a pattern, requires turning on the @ViewPatterns@
@@ -159,6 +171,10 @@
       fail "illegal QuasiQuote (allowed as expression or pattern only, used as a declaration)"
   }
 #endif
+#else
+osp :: a
+osp = error "System.OsPath.Internal.ostr: no Template Haskell"
+#endif /* defined(MIN_VERSION_template_haskell) || defined(MIN_VERSION_template_haskell_quasiquoter) */
 
 
 -- | Unpack an 'OsPath' to a list of 'OsChar'.
diff --git a/System/OsPath/Posix.hs b/System/OsPath/Posix.hs
--- a/System/OsPath/Posix.hs
+++ b/System/OsPath/Posix.hs
@@ -11,6 +11,7 @@
 
 #include "Common.hs"
 
+#if defined(MIN_VERSION_template_haskell) || defined(MIN_VERSION_template_haskell_quasiquoter)
 -- | QuasiQuote a 'PosixPath'. This accepts Unicode characters
 -- and encodes as UTF-8. Runs 'isValid' on the input.
 pstr :: QuasiQuoter
@@ -29,3 +30,8 @@
   , quoteDec  = \_ ->
       fail "illegal QuasiQuote (allowed as expression or pattern only, used as a declaration)"
   }
+#else
+pstr :: a
+pstr = error "System.OsPath.Posix.pstr: no Template Haskell"
+#endif /* defined(MIN_VERSION_template_haskell) || defined(MIN_VERSION_template_haskell_quasiquoter) */
+
diff --git a/System/OsPath/Windows.hs b/System/OsPath/Windows.hs
--- a/System/OsPath/Windows.hs
+++ b/System/OsPath/Windows.hs
@@ -11,7 +11,7 @@
 
 #include "Common.hs"
 
-
+#if defined(MIN_VERSION_template_haskell) || defined(MIN_VERSION_template_haskell_quasiquoter)
 -- | QuasiQuote a 'WindowsPath'. This accepts Unicode characters
 -- and encodes as UTF-16LE. Runs 'isValid' on the input.
 pstr :: QuasiQuoter
@@ -30,3 +30,7 @@
   , quoteDec  = \_ ->
       fail "illegal QuasiQuote (allowed as expression or pattern only, used as a declaration)"
   }
+#else
+pstr :: a
+pstr = error "Systen.OsPath.Windows.pstr: no Template Haskell"
+#endif /* defined(MIN_VERSION_template_haskell) || defined(MIN_VERSION_template_haskellquasi_quoter) */
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -2,6 +2,15 @@
 
 _Note: below all `FilePath` values are unquoted, so `\\` really means two backslashes._
 
+## 1.5.5.0 *Jan 2026*
+
+* support MicroHS wrt [#257](https://github.com/haskell/filepath/pull/257)
+* Switch from template-haskell to template-haskell-quasiquoter and -lift wrt [#258](https://github.com/haskell/filepath/pull/258)
+
+## 1.5.4.0 *Nov 2024*
+
+* Don't catch async exceptions in internal functions wrt https://github.com/haskell/os-string/issues/22
+
 ## 1.5.3.0 *Jun 2024*
 
 * Adjust for `encodeFS`/`decodedFS` deprecation in os-string
diff --git a/filepath.cabal b/filepath.cabal
--- a/filepath.cabal
+++ b/filepath.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.2
 name:               filepath
-version:            1.5.3.0
+version:            1.5.5.0
 
 -- NOTE: Don't forget to update ./changelog.md
 license:            BSD-3-Clause
@@ -91,12 +91,20 @@
 
   default-language: Haskell2010
   build-depends:
-    , base              >=4.12.0.0      && <4.21
+    , base              >=4.12.0.0      && <4.23
     , bytestring        >=0.11.3.0
     , deepseq
     , exceptions
-    , template-haskell
     , os-string         >=2.0.1
+  -- template-haskell-lift was added as a boot library in GHC-9.14
+  -- once we no longer wish to backport releases to older major releases,
+  -- this conditional can be dropped
+  if impl(ghc < 9.14)
+      build-depends: template-haskell
+  elif impl(ghc)
+      build-depends:
+        , template-haskell-lift >=0.1 && <0.2
+        , template-haskell-quasiquoter >=0.1 && <0.2
 
   ghc-options:      -Wall
 
@@ -145,6 +153,7 @@
     , os-string   >=2.0.1
     , tasty
     , tasty-quickcheck
+    , QuickCheck
 
 test-suite abstract-filepath
   default-language: Haskell2010
diff --git a/tests/filepath-equivalent-tests/Gen.hs b/tests/filepath-equivalent-tests/Gen.hs
--- a/tests/filepath-equivalent-tests/Gen.hs
+++ b/tests/filepath-equivalent-tests/Gen.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE OverlappingInstances #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE DeriveGeneric #-}
@@ -196,7 +197,8 @@
   arbitrary = listOf' arbitrary
   shrink = genericShrink
 
+#if !MIN_VERSION_QuickCheck(2,17,0)
 instance Arbitrary a => Arbitrary (NonEmpty a) where
   arbitrary = NE.fromList <$> listOf1' arbitrary
   shrink = genericShrink
-
+#endif
