diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 _Interactive terminal prompt_
 
-[![Build Status][travis-image]][travis-url]
+[![Build Status][ci-image]][ci-url]
 [![MIT License][license-image]][license-url]
 
 ![fortytwo](https://github.com/GianlucaGuarini/fortytwo/raw/develop/fortytwo.jpg)
@@ -117,8 +117,8 @@
 
 This script is heavily inspired by [survey (golang)](https://github.com/AlecAivazis/survey)
 
-[travis-image]:https://img.shields.io/travis/GianlucaGuarini/fortytwo.svg?style=flat-square
-[travis-url]:https://travis-ci.org/GianlucaGuarini/fortytwo
+[ci-image]: https://img.shields.io/github/actions/workflow/status/GianlucaGuarini/fortytwo/ci.yml?style=flat-square
+[ci-url]: https://github.com/GianlucaGuarini/fortytwo/actions
 
 [license-image]:http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square
 [license-url]:LICENSE
diff --git a/fortytwo.cabal b/fortytwo.cabal
--- a/fortytwo.cabal
+++ b/fortytwo.cabal
@@ -1,13 +1,13 @@
 name:                fortytwo
-version:1.0.5
+version:2.0.0
 synopsis:            Interactive terminal prompt
 description:         List of Prompt helpers to pimp the UIs of your haskell programs
 homepage:            https://github.com/gianlucaguarini/fortytwo#readme
 license:             MIT
-license-file:        LICENSE
+license-file:         LICENSE
 author:              Gianluca Guarini
 maintainer:          gianluca.guarini@gmail.com
-copyright:           Gianlua Guarini
+copyright:           Gianluca Guarini
 category:            Prompt
 build-type:          Simple
 extra-source-files:  README.md
@@ -35,8 +35,8 @@
                        FortyTwo.Renderers.Select
                        FortyTwo.Renderers.Multiselect
   build-depends:       base >= 4.7 && < 5,
-                       text <= 1.3,
-                       ansi-terminal >= 0.6.0.0 && <= 0.8.2
+                       text < 2.1,
+                       ansi-terminal >= 0.6.0.0 && < 1.1
   default-language:    Haskell2010
 
 executable             demo
diff --git a/src/FortyTwo/Prompts/Confirm.hs b/src/FortyTwo/Prompts/Confirm.hs
--- a/src/FortyTwo/Prompts/Confirm.hs
+++ b/src/FortyTwo/Prompts/Confirm.hs
@@ -1,5 +1,6 @@
 module FortyTwo.Prompts.Confirm (confirm, confirmWithDefault) where
 
+import Control.Monad.IO.Class
 import qualified Data.Text as T
 
 import FortyTwo.Renderers.Confirm (renderConfirm)
@@ -14,15 +15,15 @@
 normalizeString s = take 1 $ T.unpack $ T.strip . T.toLower $ T.pack s
 
 -- | Get a clean user input string
-getCleanConfirm :: IO String
-getCleanConfirm = do s <- getLine; return $ normalizeString s
+getCleanConfirm :: MonadIO m => m String
+getCleanConfirm = do s <- liftIO getLine; return $ normalizeString s
 
 -- | Ask a confirm falling back to a default value if no answer will be provided
-confirmWithDefault :: String -> Bool -> IO Bool
-confirmWithDefault question defaultAnswer = do
+confirmWithDefault :: MonadIO m => String -> Bool -> m Bool
+confirmWithDefault question defaultAnswer = liftIO $ do
   putStrLn emptyString
   renderQuestion question defaultAnswerHumanized emptyString
-  renderConfirm
+  renderConfirm defaultAnswer
   flush
   answer <- getCleanConfirm
   clearLines 1
@@ -36,5 +37,5 @@
     defaultAnswerHumanized = if defaultAnswer then "yes" else "no"
 
 -- | Ask a confirm question by default it will be true
-confirm :: String -> IO Bool
+confirm :: MonadIO m => String -> m Bool
 confirm question = confirmWithDefault question False
diff --git a/src/FortyTwo/Prompts/Input.hs b/src/FortyTwo/Prompts/Input.hs
--- a/src/FortyTwo/Prompts/Input.hs
+++ b/src/FortyTwo/Prompts/Input.hs
@@ -1,13 +1,15 @@
 module FortyTwo.Prompts.Input (inputWithDefault, input) where
 
+import Control.Monad.IO.Class
+
 import FortyTwo.Renderers.Question (renderQuestion)
 import FortyTwo.Utils (clearLines, flush)
 import FortyTwo.Constants (emptyString)
 
 -- | Ask a simple input question falling back to a default value if no answer will be provided
 -- inputWithDefault "What is your name?" "The Dude"
-inputWithDefault :: String -> String -> IO String
-inputWithDefault question defaultAnswer = do
+inputWithDefault :: MonadIO m => String -> String -> m String
+inputWithDefault question defaultAnswer = liftIO $ do
   putStrLn emptyString
   renderQuestion question defaultAnswer emptyString
   putStr " "
@@ -24,5 +26,5 @@
 
 -- | Simple input question
 -- input "What is your name?"
-input :: String -> IO String
+input :: MonadIO m => String -> m String
 input question = inputWithDefault question emptyString
diff --git a/src/FortyTwo/Prompts/Multiselect.hs b/src/FortyTwo/Prompts/Multiselect.hs
--- a/src/FortyTwo/Prompts/Multiselect.hs
+++ b/src/FortyTwo/Prompts/Multiselect.hs
@@ -2,6 +2,8 @@
 
 module FortyTwo.Prompts.Multiselect (multiselect, multiselectWithDefault) where
 
+import Control.Monad.IO.Class
+
 import System.Console.ANSI (hideCursor, showCursor)
 import FortyTwo.Renderers.Multiselect (renderOptions)
 import FortyTwo.Renderers.Question (renderQuestion)
@@ -55,8 +57,8 @@
 
 -- | Multi Select prompt, falling back to a default list of values if no answer will be provided
 -- multiselectWithDefault "What's your favourite color?" ["Red", "Yellow", "Blue"] ["Red", "Blue"]
-multiselectWithDefault :: String -> [String] -> [String] -> IO [String]
-multiselectWithDefault question options defaultAnswer = do
+multiselectWithDefault :: MonadIO m => String -> [String] -> [String] -> m [String]
+multiselectWithDefault question options defaultAnswer = liftIO $ do
   putStrLn emptyString
   renderQuestion question (toCommaSeparatedString defaultAnswer) emptyString
   putStrLn emptyString
@@ -78,5 +80,5 @@
 
 -- | Multi Select prompt
 -- multiselect "What's your favourite color?" ["Red", "Yellow", "Blue"]
-multiselect :: String -> [String] -> IO [String]
+multiselect :: MonadIO m => String -> [String] -> m [String]
 multiselect question options = multiselectWithDefault question options []
diff --git a/src/FortyTwo/Prompts/Password.hs b/src/FortyTwo/Prompts/Password.hs
--- a/src/FortyTwo/Prompts/Password.hs
+++ b/src/FortyTwo/Prompts/Password.hs
@@ -1,5 +1,7 @@
 module FortyTwo.Prompts.Password (password) where
 
+import Control.Monad.IO.Class
+
 import System.Console.ANSI (cursorBackward, clearFromCursorToScreenEnd, setCursorColumn, clearFromCursorToLineEnd)
 import Control.Monad (unless)
 import FortyTwo.Renderers.Password (renderPassword, hideLetters)
@@ -9,8 +11,8 @@
 
 -- | Ask a user password
 -- password "What your secret password?"
-password :: String -> IO String
-password question = do
+password :: MonadIO m => String -> m String
+password question = liftIO $ do
   putStrLn emptyString
   renderQuestion question emptyString emptyString
   putStr " "
@@ -43,7 +45,7 @@
   return res
 
 -- | Handle a user event
-handleEvent :: String -> String -> IO String
+handleEvent ::String -> String -> IO String
 handleEvent pass key
   | key == enterKey = return pass
   | key == delKey =
diff --git a/src/FortyTwo/Prompts/Select.hs b/src/FortyTwo/Prompts/Select.hs
--- a/src/FortyTwo/Prompts/Select.hs
+++ b/src/FortyTwo/Prompts/Select.hs
@@ -2,6 +2,8 @@
 
 module FortyTwo.Prompts.Select (select, selectWithDefault) where
 
+import Control.Monad.IO.Class
+
 import System.Console.ANSI (hideCursor, showCursor)
 import FortyTwo.Renderers.Select (renderOptions)
 import FortyTwo.Renderers.Question (renderQuestion)
@@ -48,8 +50,8 @@
 
 -- | Select prompt from a list of options falling back to a default value if no answer will be provided
 -- selectWithDefault "What's your favourite color?" ["Red", "Yellow", "Blue"] "Red"
-selectWithDefault :: String -> [String] -> String -> IO String
-selectWithDefault question options defaultAnswer = do
+selectWithDefault :: MonadIO m => String -> [String] -> String -> m String
+selectWithDefault question options defaultAnswer = liftIO $ do
   putStrLn emptyString
   renderQuestion question defaultAnswer emptyString
   putStrLn emptyString
@@ -74,5 +76,5 @@
 
 -- | Select prompt from a list of options
 -- select "What's your favourite color?" ["Red", "Yellow", "Blue"]
-select :: String -> [String] -> IO String
+select :: MonadIO m => String -> [String] -> m String
 select question options = selectWithDefault question options emptyString
diff --git a/src/FortyTwo/Renderers/Confirm.hs b/src/FortyTwo/Renderers/Confirm.hs
--- a/src/FortyTwo/Renderers/Confirm.hs
+++ b/src/FortyTwo/Renderers/Confirm.hs
@@ -3,6 +3,11 @@
       renderConfirm
     ) where
 
+import Control.Monad.IO.Class
+
 -- | Render the helper text
-renderConfirm :: IO ()
-renderConfirm = putStr " (y/N) "
+renderConfirm :: MonadIO m => Bool -> m ()
+renderConfirm defaultAnswer = liftIO $ putStr $ " (" ++ msg ++ ") "
+  where
+    msg | defaultAnswer = "Y/n"
+        | otherwise = "y/N"
diff --git a/src/FortyTwo/Renderers/Multiselect.hs b/src/FortyTwo/Renderers/Multiselect.hs
--- a/src/FortyTwo/Renderers/Multiselect.hs
+++ b/src/FortyTwo/Renderers/Multiselect.hs
@@ -2,18 +2,20 @@
 
 module FortyTwo.Renderers.Multiselect (renderOptions, renderOption) where
 
+import Control.Monad.IO.Class
+
 import FortyTwo.Types (Option(..), Options)
 import FortyTwo.Utils (addBreakingLinesSpacing)
 import System.Console.ANSI
 import FortyTwo.Constants
 
 -- | Render all the options collection
-renderOptions :: Options -> IO ()
+renderOptions :: MonadIO m => Options -> m ()
 renderOptions = mapM_ renderOption
 
 -- | Render a single option items
-renderOption :: Option -> IO()
-renderOption Option { isSelected, isFocused, value } = do
+renderOption :: MonadIO m => Option -> m ()
+renderOption Option { isSelected, isFocused, value } = liftIO $ do
   if isFocused then do
     setSGR [SetColor Foreground Dull Cyan]
     putStr $ focusIcon : " "
diff --git a/src/FortyTwo/Renderers/Password.hs b/src/FortyTwo/Renderers/Password.hs
--- a/src/FortyTwo/Renderers/Password.hs
+++ b/src/FortyTwo/Renderers/Password.hs
@@ -1,10 +1,12 @@
 module FortyTwo.Renderers.Password (renderPassword, hideLetters) where
 
+import Control.Monad.IO.Class
+
 import FortyTwo.Constants (passwordHiddenChar)
 
 -- | Print the password value to the user hiding it
-renderPassword :: String -> IO ()
-renderPassword letters = putStr $ hideLetters letters
+renderPassword :: MonadIO m => String -> m ()
+renderPassword letters = liftIO $ putStr $ hideLetters letters
 
 -- | Hide any string replacing its letters with the passwordHiddenChar
 hideLetters :: String -> String
diff --git a/src/FortyTwo/Renderers/Question.hs b/src/FortyTwo/Renderers/Question.hs
--- a/src/FortyTwo/Renderers/Question.hs
+++ b/src/FortyTwo/Renderers/Question.hs
@@ -1,33 +1,35 @@
 module FortyTwo.Renderers.Question (renderQuestion, renderMessage) where
 
+import Control.Monad.IO.Class
+
 import FortyTwo.Types (Message(..))
 import System.Console.ANSI
 
 -- | Print any message depending on its type
-renderMessage :: Message -> String -> IO()
+renderMessage :: MonadIO m => Message -> String -> m ()
 renderMessage messageType message
-  | messageType == Question = do
+  | messageType == Question = liftIO $ do
       setSGR [SetColor Foreground Dull Green]
       putStr "? "
       setSGR [Reset]
       setSGR [SetConsoleIntensity BoldIntensity]
       putStr text
       setSGR [Reset]
-  | messageType == Answer = do
+  | messageType == Answer = liftIO $ do
       setSGR [SetColor Foreground Dull Cyan]
       putStr $ " " ++ text
       setSGR [Reset]
-  | messageType == DefaultAnswer = do
+  | messageType == DefaultAnswer = liftIO $ do
     setSGR [SetConsoleIntensity FaintIntensity]
     putStr $ " (" ++ text ++ ")"
     setSGR [Reset]
   | otherwise =
-      putStr text
+      liftIO $ putStr text
     where
       text = (unwords . lines) message
 
 -- | Print the question message
-renderQuestion :: String -> String -> String -> IO ()
+renderQuestion :: MonadIO m => String -> String -> String -> m ()
 renderQuestion question defaultAnswer answer
   | hasDefaultAnswer && hasAnswer = do
       renderMessage Question question
diff --git a/src/FortyTwo/Renderers/Select.hs b/src/FortyTwo/Renderers/Select.hs
--- a/src/FortyTwo/Renderers/Select.hs
+++ b/src/FortyTwo/Renderers/Select.hs
@@ -2,18 +2,20 @@
 
 module FortyTwo.Renderers.Select (renderOptions, renderOption) where
 
+import Control.Monad.IO.Class
+
 import FortyTwo.Types (Option(..), Options)
 import System.Console.ANSI
 import FortyTwo.Utils (addBreakingLinesSpacing)
 import FortyTwo.Constants
 
 -- | Render all the options collection
-renderOptions :: Options -> IO ()
+renderOptions :: MonadIO m => Options -> m ()
 renderOptions = mapM_ renderOption
 
 -- | Render a single option items
-renderOption :: Option -> IO()
-renderOption Option { isFocused, value } =
+renderOption :: MonadIO m => Option -> m ()
+renderOption Option { isFocused, value } = liftIO $ do
   if isFocused then do
     setSGR [SetColor Foreground Dull Cyan]
     putStrLn $ unwords [[focusIcon], text]
diff --git a/src/FortyTwo/Utils.hs b/src/FortyTwo/Utils.hs
--- a/src/FortyTwo/Utils.hs
+++ b/src/FortyTwo/Utils.hs
@@ -2,6 +2,8 @@
 
 module FortyTwo.Utils where
 
+import Control.Monad.IO.Class
+
 import System.Console.ANSI (cursorUpLine, clearFromCursorToScreenEnd)
 import System.IO (hSetBuffering, hFlush, hSetEcho, hReady, stdin, stdout, BufferMode(..))
 import Data.List (findIndex, findIndices, elemIndex, intercalate)
@@ -11,28 +13,28 @@
 import FortyTwo.Constants (emptyString)
 
 -- | Disable the stdin stdout output buffering
-noBuffering :: IO()
-noBuffering = do
+noBuffering :: MonadIO m => m ()
+noBuffering = liftIO $ do
   hSetBuffering stdin NoBuffering
   hSetBuffering stdout NoBuffering
 
 -- | Enaable the stdin stdout buffering
-restoreBuffering :: IO()
-restoreBuffering = do
+restoreBuffering :: MonadIO m => m ()
+restoreBuffering = liftIO $ do
   hSetBuffering stdin LineBuffering
   hSetBuffering stdout LineBuffering
 
 -- | Avoid echoing the user input
-noEcho :: IO ()
-noEcho = hSetEcho stdin False
+noEcho :: MonadIO m => m ()
+noEcho = liftIO $ hSetEcho stdin False
 
 -- | Restore the user input echos
-restoreEcho :: IO ()
-restoreEcho = hSetEcho stdin True
+restoreEcho :: MonadIO m => m ()
+restoreEcho = liftIO $ hSetEcho stdin True
 
 -- | Clear terminal lines from the current cursor position
-clearLines :: Int -> IO()
-clearLines l = do
+clearLines :: MonadIO m => Int -> m ()
+clearLines l = liftIO $ do
   -- move up of some lines...
   cursorUpLine l
   -- and clear them
