diff --git a/hikaru.cabal b/hikaru.cabal
index 482b7a16f77fee7f55f4af31c414cdebfe022c04..82c6fe4b57a8dbc94ea2ba35d61cb45b44a26ee4 100644
--- a/hikaru.cabal
+++ b/hikaru.cabal
@@ -67,7 +67,7 @@ common common
         -Wredundant-constraints
 
     build-depends:
-        aeson              >=1.4  && <1.6
+      , aeson              >=1.4  && <1.6
       , base               >=4.13 && <4.16
       , binary             >=0.8  && <0.9
       , bytestring         >=0.10 && <0.12
@@ -80,7 +80,7 @@ common common
       , lucid              >=2.9  && <2.10
       , memory             >=0.15 && <0.16
       , mtl                >=2.2  && <2.3
-      , relude             >=0.7  && <1.1
+      , praha              >=0.1  && <0.2
       , resourcet          >=1.2  && <1.3
       , string-conversions >=0.4  && <0.5
       , text               >=1.2  && <1.3
diff --git a/lib/Hikaru/Action.hs b/lib/Hikaru/Action.hs
index 3ffc0386bdf67ba4122f6b4ee8a1c85b6b86f28f..1d7edbd515855db0ae993a5431c3844fd16982a4 100644
--- a/lib/Hikaru/Action.hs
+++ b/lib/Hikaru/Action.hs
@@ -113,7 +113,7 @@ module Hikaru.Action
   , FilePath
   )
 where
-  import Relude hiding (writeIORef, readIORef, modifyIORef', newIORef)
+  import Praha
 
   import qualified Data.ByteString as BS
   import qualified Data.ByteString.Lazy as LBS
@@ -126,8 +126,7 @@ where
   import Data.Aeson
   import Data.Binary.Builder
   import Data.Dynamic
-  import Data.List (lookup, deleteBy)
-  import Data.String.Conversions
+  import Data.List (deleteBy, lookup, map, filter)
   import Hikaru.Config
   import Hikaru.Media
   import Hikaru.Types
@@ -556,7 +555,7 @@ where
     where
       throwLimitIO :: Int64 -> IO a
       throwLimitIO n = throwIO (PayloadTooLarge, msg :: Text)
-        where msg = "Limit is " <> show n <> " bytes."
+        where msg = "Limit is " <> tshow n <> " bytes."
 
 
   -- |
diff --git a/lib/Hikaru/CSRF.hs b/lib/Hikaru/CSRF.hs
index d5904faa94d1845a84dbddcf6a468b1048c2e9f9..d7ceacbceb9e3a2baefec719b682e4b8f3280f94 100644
--- a/lib/Hikaru/CSRF.hs
+++ b/lib/Hikaru/CSRF.hs
@@ -15,11 +15,10 @@ module Hikaru.CSRF
   , isTokenValid
   )
 where
-  import Relude
+  import Praha
 
   import Crypto.Hash
   import Crypto.MAC.HMAC
-  import Data.String.Conversions
   import Data.Text (splitOn)
   import Data.Time.Clock.POSIX (getPOSIXTime)
 
@@ -37,7 +36,7 @@ where
     secret <- getConfigDefault "CSRF_SECRET" ""
 
     let signature = sign now secret
-     in return $ mconcat [ show now, ":", signature ]
+     in return $ mconcat [ tshow now, ":", signature ]
 
 
   -- |
@@ -73,11 +72,11 @@ where
 
 
   sign :: Int64 -> Text -> Text
-  sign timestamp secret = show $ hmacGetDigest digest
+  sign timestamp secret = tshow $ hmacGetDigest digest
     where
       digest      = hmac timeBytes secretBytes :: HMAC SHA256
       secretBytes = cs secret :: ByteString
-      timeBytes   = show timestamp :: ByteString
+      timeBytes   = cs (show timestamp) :: ByteString
 
 
 -- vim:set ft=haskell sw=2 ts=2 et:
diff --git a/lib/Hikaru/Config.hs b/lib/Hikaru/Config.hs
index 312c2531e8d5870a0b8b4c3ba00efdb58de3901d..a52c981b4d35a54f9665996e0b1bac2f09c11bbd 100644
--- a/lib/Hikaru/Config.hs
+++ b/lib/Hikaru/Config.hs
@@ -1,24 +1,23 @@
-{-|
-Module      :  Hikaru.Config
-Copyright   :  Jan Hamal Dvořák
-License     :  AGPL-3.0-or-later
-
-Maintainer  :  mordae@anilinux.org
-Stability   :  unstable
-Portability :  non-portable (ghc)
-
-This module provides means to read configuration from environment and files.
-
-Example:
-
-@
-base <- 'configDefault'
-file <- 'configFromFile' \"site.env\"
-env  <- 'configFromEnv'
-
-let cfg = env <> file <> base
-@
--}
+--
+-- Module      :  Hikaru.Config
+-- Copyright   :  Jan Hamal Dvořák
+-- License     :  AGPL-3.0-or-later
+--
+-- Maintainer  :  mordae@anilinux.org
+-- Stability   :  unstable
+-- Portability :  non-portable (ghc)
+--
+-- This module provides means to read configuration from environment and files.
+--
+-- Example:
+--
+-- @
+-- base <- 'configDefault'
+-- file <- 'configFromFile' \"site.env\"
+-- env  <- 'configFromEnv'
+--
+-- let cfg = env <> file <> base
+-- @
 
 module Hikaru.Config
   ( Config
@@ -35,13 +34,17 @@ module Hikaru.Config
   , generateSecret
   )
 where
-  import Relude hiding (drop, lines, isPrefixOf, length, span)
+  import Praha
+
+  import Hikaru.Types
+
   import UnliftIO.Environment
   import Crypto.Random.Entropy
   import Data.ByteArray.Encoding
-  import Data.String.Conversions
-  import Data.Text hiding (map)
-  import Hikaru.Types
+
+  import Data.Text (lines, strip, drop, span, isPrefixOf)
+  import Data.Text.IO (readFile)
+  import Data.List (map)
 
   import qualified Data.Map as Map
 
@@ -84,8 +87,9 @@ where
   -- @
   --
   configFromFile :: (MonadIO m) => FilePath -> m Config
-  configFromFile path = Map.fromList <$> parseFile <$> readFileText path
+  configFromFile path = Map.fromList <$> parseFile <$> contents
     where
+      contents    = liftIO (readFile path)
       parseFile   = mapMaybe parseLine . lines
       parseLine   = fmap tidy . fmap parseKV . reject . strip
       parseKV     = fmap (drop 1) . span (/= '=')
@@ -114,7 +118,7 @@ where
   configGet :: (Param a) => Text -> Config -> a
   configGet name cfg = case configGetMaybe name cfg of
                          Just value -> value
-                         Nothing -> error (name <> " not set!")
+                         Nothing -> error (cs name <> " not set!")
 
 
   -- |
diff --git a/lib/Hikaru/Develop.hs b/lib/Hikaru/Develop.hs
index cd48833bc6be9e14afef7a32a1ba86fcc6b6a200..0ba78b363ed8af53ad16dab871632d5c5980bca6 100644
--- a/lib/Hikaru/Develop.hs
+++ b/lib/Hikaru/Develop.hs
@@ -14,7 +14,9 @@ module Hikaru.Develop
   ( developWith
   )
 where
-  import Relude
+  import Praha
+
+  import UnliftIO.MVar
 
   import Control.Concurrent (killThread, forkFinally)
   import Foreign.Store
diff --git a/lib/Hikaru/Dispatch.hs b/lib/Hikaru/Dispatch.hs
index c969f10c0fcf6305ea689092047d25f2817a6091..ec0e1aff3c5bf15c7e11b3979ad4ff58cb00e6b4 100644
--- a/lib/Hikaru/Dispatch.hs
+++ b/lib/Hikaru/Dispatch.hs
@@ -32,15 +32,16 @@ module Hikaru.Dispatch
   , TopLevel
   )
 where
-  import Relude
+  import Praha
 
-  import Control.Exception (catch)
+  import Control.Monad.State
   import Data.CaseInsensitive (original)
-  import Data.List (lookup, deleteBy)
+  import Data.List (lookup, deleteBy, intersperse, reverse, map)
   import Hikaru.Route
   import Hikaru.Types
   import Network.HTTP.Types.Header
   import Network.Wai
+  import UnliftIO.Exception
 
   import qualified Data.Map.Strict as Map
 
diff --git a/lib/Hikaru/Form.hs b/lib/Hikaru/Form.hs
index e57b93602e3a861a7e9f12708c5f3b2511686cb7..a467a0bc37018d9cff0a6a11062ecb894e14390c 100644
--- a/lib/Hikaru/Form.hs
+++ b/lib/Hikaru/Form.hs
@@ -96,15 +96,17 @@ module Hikaru.Form
   , FromFormMessage(..)
   )
 where
-  import Relude hiding (Option, show, elem)
+  import Praha hiding (show, elem)
 
+  import Control.Monad.State
   import Data.Dynamic
-  import Data.List (elem, lookup)
+  import Data.List (elem, map, lookup, filter)
   import Data.Text (strip)
   import Hikaru.Action
   import Hikaru.CSRF
   import Hikaru.Localize
   import Hikaru.Types
+  import System.IO
   import Text.Show
 
 
diff --git a/lib/Hikaru/Link.hs b/lib/Hikaru/Link.hs
index f9ef96691646f1e8700313a88d7e76bc027b864b..d41017cb44178fcaf373d98e172d9f9a253548a9 100644
--- a/lib/Hikaru/Link.hs
+++ b/lib/Hikaru/Link.hs
@@ -25,13 +25,13 @@ module Hikaru.Link
   , isActivePrefix
   )
 where
-  import Relude
+  import Praha
 
   import Data.Binary.Builder
-  import Data.String.Conversions
   import Lucid
   import Network.HTTP.Types.URI
   import Hikaru.Action
+  import Data.List (isPrefixOf, map, filter)
 
 
   -- |
diff --git a/lib/Hikaru/Localize.hs b/lib/Hikaru/Localize.hs
index 209131351e0ce36d9b11e59c89744bd85b4e06d8..b61cdbda55cf9a6513564fe58e1ce09a31380166 100644
--- a/lib/Hikaru/Localize.hs
+++ b/lib/Hikaru/Localize.hs
@@ -64,10 +64,9 @@ module Hikaru.Localize
   , selectLanguages
   )
 where
-  import Relude
+  import Praha
 
-  import Data.List (nub)
-  import Data.String.Conversions
+  import Data.List (filter, map, nub)
   import Hikaru.Action
   import Hikaru.Media
   import Lucid
@@ -129,7 +128,7 @@ where
     langs <- getLanguages
 
     case mapMaybe (flip localize msg) langs of
-      []  -> return $ show msg
+      []  -> return $ tshow msg
       x:_ -> return x
 
 
@@ -142,7 +141,7 @@ where
     langs <- getLanguages
 
     case mapMaybe (flip localizeHtml msg) langs of
-      []  -> toHtml $ (show msg :: Text)
+      []  -> toHtml $ tshow msg
       x:_ -> x
 
 
diff --git a/lib/Hikaru/Media.hs b/lib/Hikaru/Media.hs
index 1f7dcb2035552e0bcaf9ccc80c9317fa60c6224e..c34b1aea7c3cb5156c276579b2c9ec5838d20e7a 100644
--- a/lib/Hikaru/Media.hs
+++ b/lib/Hikaru/Media.hs
@@ -25,12 +25,12 @@ module Hikaru.Media
   , selectMedia
   )
 where
-  import Relude hiding (head, get, many)
-  import Relude.Unsafe (head)
-  import Text.ParserCombinators.ReadP
-  import Data.String.Conversions
+  import Praha hiding (many)
+
   import Data.Text (toLower)
-  import Data.List (lookup)
+
+  import Data.List (filter, lookup, head, sortOn)
+  import Text.ParserCombinators.ReadP
   import Data.Char (isControl, isSpace)
 
 
@@ -70,7 +70,7 @@ where
   --
   parseMedia :: Text -> [Media]
   parseMedia text = case readP_to_S pMediaList (cs (toLower text)) of
-                      (m, ""):_ -> sortWith (negate . mediaQuality) m
+                      (m, ""):_ -> sortOn (negate . mediaQuality) m
                       _else     -> []
 
 
@@ -163,7 +163,7 @@ where
                         [ ]      -> Nothing
                         (l, r):_ -> Just $ l { mediaQuality = mediaQuality r }
     where
-      best = sortWith (negate . mediaQuality . snd) good
+      best = sortOn (negate . mediaQuality . snd) good
       good = filter (uncurry matchMedia) prod
       prod = [(l, r) | l <- ls, r <- rs]
 
diff --git a/lib/Hikaru/Route.hs b/lib/Hikaru/Route.hs
index 63b4d0c8f12401c1b42d2371166322da86acb128..4a04c4103a6bb0a42cec1240679fc0d88dce5c72 100644
--- a/lib/Hikaru/Route.hs
+++ b/lib/Hikaru/Route.hs
@@ -59,10 +59,9 @@ module Hikaru.Route
   , Route
   )
 where
-  import Relude hiding (get, put, head)
+  import Praha
 
-  import Data.List (lookup)
-  import Data.String.Conversions
+  import Data.List (lookup, map)
   import Hikaru.Media
   import Hikaru.Types
   import Network.HTTP.Types.Header
diff --git a/lib/Hikaru/Types.hs b/lib/Hikaru/Types.hs
index fbed52f3c677f7b49400cfd53c12d8595e7bc9f4..29522700f9fa0dea47dc113cd5d3e749f3d9e3f9 100644
--- a/lib/Hikaru/Types.hs
+++ b/lib/Hikaru/Types.hs
@@ -17,10 +17,9 @@ module Hikaru.Types
   , defaultHandler
   )
 where
-  import Relude
+  import Praha
 
   import Data.ByteString (ByteString)
-  import Data.String.Conversions
   import Data.Text (pack, unpack)
   import Network.HTTP.Types.Header
   import Network.HTTP.Types.Status
diff --git a/lib/Hikaru/Widget.hs b/lib/Hikaru/Widget.hs
index bd1a456ddd3c4dd968ee7b5dbcfa5b73ed94be6e..60906b8f4d534e3768eab003233ac2529b13be6c 100644
--- a/lib/Hikaru/Widget.hs
+++ b/lib/Hikaru/Widget.hs
@@ -63,9 +63,9 @@ module Hikaru.Widget
   , Render(..)
   )
 where
-  import Relude
+  import Praha
   import Data.Text (stripPrefix)
-  import Data.List (lookup)
+  import Data.List (lookup, filter)
   import Lucid
   import Hikaru.Types
   import Hikaru.Action
diff --git a/test/Hikaru/Demo.hs b/test/Hikaru/Demo.hs
index 45df6ee02e26f33fec11926ad60c0df2c7698b32..3ad20233e1579fe5aba312708f74f19072dc7f71 100644
--- a/test/Hikaru/Demo.hs
+++ b/test/Hikaru/Demo.hs
@@ -12,15 +12,16 @@ module Hikaru.Demo
   ( makeDemo
   )
 where
-  import Relude hiding (for_, Option, get)
+  import Praha hiding (for_)
 
-  import Control.Concurrent.MVar (modifyMVar_)
+  import UnliftIO.MVar
   import Data.Aeson (Value)
   import Hikaru
   import Lucid
   import Network.HTTP.Types.Header
   import Network.HTTP.Types.Status
   import Network.Wai
+  import Data.Text (unlines)
 
 
   -- Action ------------------------------------------------------------------
@@ -72,7 +73,7 @@ where
   countVisitor = do
     counter <- modelCounter <$> getModelEnv
     liftIO do
-      modifyMVar_ counter (return . succ)
+      modifyMVar_ counter (return . (+ 1))
       readMVar counter
 
 
@@ -150,7 +151,7 @@ where
     -- Present fancy HTML result.
     sendHTML do
       h1_ "Welcome!"
-      p_ $ "You are " >> toHtml (show n :: Text) >> ". visitor!"
+      p_ $ "You are " >> toHtml (tshow n) >> ". visitor!"
 
 
   getRootTextR :: Action ()
@@ -160,7 +161,7 @@ where
 
     -- Present a plain textual result.
     sendText $ unlines [ "Welcome!"
-                       , "You are " <> show n <> ". visitor!"
+                       , "You are " <> tshow n <> ". visitor!"
                        ]
 
 
@@ -219,11 +220,11 @@ where
 
         forM cases \Case{..} -> do
           tr_ do
-            td_ $ toHtml $ (show caseId :: Text)
+            td_ $ toHtml $ tshow caseId
             td_ $ toHtml $ caseName
             td_ $ toHtml $ caseRecNo
-            td_ $ toHtml $ (show caseMode :: Text)
-            td_ $ toHtml $ (show caseActive :: Text)
+            td_ $ toHtml $ tshow caseMode
+            td_ $ toHtml $ tshow caseActive
 
 
   -- Forms -------------------------------------------------------------------
diff --git a/test/Hikaru/DemoSpec.hs b/test/Hikaru/DemoSpec.hs
index 6af5b775d4c8898e2b1776b0b507bb481b699e99..981fd061c7ecd4d8253f3ef1d6855e270c06009e 100644
--- a/test/Hikaru/DemoSpec.hs
+++ b/test/Hikaru/DemoSpec.hs
@@ -14,7 +14,7 @@ module Hikaru.DemoSpec
   ( spec
   )
 where
-  import Relude hiding (get)
+  import Praha
 
   import Hikaru.Demo
   import Hikaru.Test
diff --git a/test/Hikaru/FormSpec.hs b/test/Hikaru/FormSpec.hs
index 26ad2ce5da255ed2e9356e31260b5c163fd7b3fe..72c678a8c066233798faeea276cb4d05e5a4661c 100644
--- a/test/Hikaru/FormSpec.hs
+++ b/test/Hikaru/FormSpec.hs
@@ -12,7 +12,7 @@ module Hikaru.FormSpec
   ( spec
   )
 where
-  import Relude
+  import Praha
 
   import Hikaru ()
   import Hikaru.Test
diff --git a/test/Hikaru/Test.hs b/test/Hikaru/Test.hs
index 56cff5f7b9096b6f90b6ca03d84a915c5463558d..64b42bb7bb24414e9046e193bc077212a3a68ade 100644
--- a/test/Hikaru/Test.hs
+++ b/test/Hikaru/Test.hs
@@ -21,7 +21,7 @@ module Hikaru.Test
   , module Test.Hspec
   )
 where
-  import Relude hiding (get)
+  import Praha
 
   import qualified Data.ByteString.Lazy as LBS