diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017-Present Gianluca Guarini
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,124 @@
+# fortytwo
+
+_Interactive terminal prompt_
+
+[![Build Status][travis-image]][travis-url]
+[![MIT License][license-image]][license-url]
+
+<img src="fortytwo.jpg" width="100%" />
+
+## Installation
+
+```sh
+cabal install fortytwo
+```
+
+## Demo
+
+<img src="demo.gif" />
+
+## API
+
+### Prompts
+
+#### Input
+Ask a simple question requiring the user to type any string. It returns always a `String`
+
+```hs
+import FortyTwo (input)
+
+main :: IO String
+main = input "What's your name?"
+```
+
+`inputWithDefault` will let you define a fallback answer if no answer will be provided
+```hs
+import FortyTwo (inputWithDefault)
+
+main :: IO String
+main = inputWithDefault "What's your name?" "Undefined"
+```
+
+#### Confirm
+Confirm prompt returning a boolean either `True` or `False`. If no answer will be provided it will return `False`
+
+```hs
+import FortyTwo (confirm)
+
+main :: IO Bool
+main = confirm "Are you old enough to see this?"
+```
+
+`confirmWithDefault` will let you define a fallback answer if no answer will be provided
+```hs
+import FortyTwo (confirmWithDefault)
+
+main :: IO Bool
+main = confirmWithDefault "What's your name?" "Undefined"
+```
+
+#### Password
+Password prompt hiding the values typed by the user. It will always return a `String`
+
+```hs
+import FortyTwo (password)
+
+main :: IO String
+main = password "What's your secret password?"
+```
+
+#### Select
+Select prompt letting users decide between one of many possible answers. It will always return a `String`
+
+```hs
+import FortyTwo (select)
+
+main :: IO Bool
+main = select
+         "What's your favourite color?"
+         ["Red", "Yellow", "Blue"]
+```
+
+`selectWithDefault` will let you define a fallback answer if no answer will be provided
+```hs
+import FortyTwo (selectWithDefault)
+
+main :: IO Bool
+main = selectWithDefault
+         "What's your favourite color?"
+         ["Red", "Yellow", "Blue"]
+         "Red"
+```
+
+#### Multiselect
+Multiselect prompt letting users decide between multiple possible choices. It will always return a collection `[String]`
+
+```hs
+import FortyTwo (multiselect)
+
+main :: IO Bool
+main = multiselect
+         "What are your favourite films?"
+         ["Titanic", "Matrix", "The Gladiator"]
+```
+
+`multiselectWithDefault` will let you define a fallback answer if no answer will be provided
+```hs
+import FortyTwo (multiselectWithDefault)
+
+main :: IO Bool
+main = multiselectWithDefault
+         "What are your favourite films?"
+         ["Titanic", "Matrix", "The Gladiator"]
+         ["The Gladiator"]
+```
+
+# Inspiration
+
+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
+
+[license-image]:http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square
+[license-url]:LICENSE
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/examples/ConfirmExample.hs b/examples/ConfirmExample.hs
new file mode 100644
--- /dev/null
+++ b/examples/ConfirmExample.hs
@@ -0,0 +1,9 @@
+module ConfirmExample where
+
+import FortyTwo (confirm, confirmWithDefault)
+
+main :: IO Bool
+main = do
+  confirm "Do you like music?"
+  confirmWithDefault "Do you like pop music?" False
+  confirmWithDefault "Do you play an instrument?" True
diff --git a/examples/InputExample.hs b/examples/InputExample.hs
new file mode 100644
--- /dev/null
+++ b/examples/InputExample.hs
@@ -0,0 +1,8 @@
+module InputExample where
+
+import FortyTwo (input, inputWithDefault)
+
+main :: IO String
+main = do
+  input "What's your name?"
+  inputWithDefault "How old are you?" "22"
diff --git a/examples/Main.hs b/examples/Main.hs
new file mode 100644
--- /dev/null
+++ b/examples/Main.hs
@@ -0,0 +1,16 @@
+module Main where
+
+import qualified InputExample
+import qualified ConfirmExample
+import qualified PasswordExample
+import qualified SelectExample
+import qualified MultiselectExample
+
+main :: IO()
+main = do
+  InputExample.main
+  ConfirmExample.main
+  MultiselectExample.main
+  SelectExample.main
+  PasswordExample.main
+  return ()
diff --git a/examples/MultiselectExample.hs b/examples/MultiselectExample.hs
new file mode 100644
--- /dev/null
+++ b/examples/MultiselectExample.hs
@@ -0,0 +1,11 @@
+module MultiselectExample where
+
+import FortyTwo (multiselect, multiselectWithDefault)
+
+main :: IO [String]
+main = do
+  multiselect "Which kind of sports do you like?" ["Soccer", "Tennis", "Golf"]
+  multiselectWithDefault
+    "What are your favourite books?"
+    ["1984", "Moby Dick", "The Hitchhiker's Guide to the Galaxy"]
+    ["1984", "The Hitchhiker's Guide to the Galaxy"]
diff --git a/examples/PasswordExample.hs b/examples/PasswordExample.hs
new file mode 100644
--- /dev/null
+++ b/examples/PasswordExample.hs
@@ -0,0 +1,6 @@
+module PasswordExample where
+
+import FortyTwo (password)
+
+main :: IO String
+main = password "What's your secret password?"
diff --git a/examples/SelectExample.hs b/examples/SelectExample.hs
new file mode 100644
--- /dev/null
+++ b/examples/SelectExample.hs
@@ -0,0 +1,8 @@
+module SelectExample where
+
+import FortyTwo (select, selectWithDefault)
+
+main :: IO String
+main = do
+  select "What's your favourite color?" ["Red", "Yellow", "Blue"]
+  selectWithDefault "What's your favourite film?" ["28 Days Later", "Blade Runner", "Matrix"] "28 Days Later"
diff --git a/fortytwo.cabal b/fortytwo.cabal
new file mode 100644
--- /dev/null
+++ b/fortytwo.cabal
@@ -0,0 +1,74 @@
+name:                fortytwo
+version:0.0.1
+synopsis:            Interactive terminal prompt
+homepage:            https://github.com/gianlucaguarini/fortytwo#readme
+license:             MIT
+license-file:        LICENSE
+author:              Gianluca Guarini
+maintainer:          gianluca.guarini@gmail.com
+copyright:           Gianlua Guarini
+category:            Web
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     FortyTwo,
+                       FortyTwo.Types,
+                       FortyTwo.Constants,
+                       FortyTwo.Utils,
+                       FortyTwo.TheAnswerToEverything,
+                       FortyTwo.Prompts.Input,
+                       FortyTwo.Prompts.Confirm,
+                       FortyTwo.Prompts.Password,
+                       FortyTwo.Prompts.Select,
+                       FortyTwo.Prompts.Multiselect,
+                       FortyTwo.Renderers.Question,
+                       FortyTwo.Renderers.Password,
+                       FortyTwo.Renderers.Confirm,
+                       FortyTwo.Renderers.Select
+                       FortyTwo.Renderers.Multiselect
+  build-depends:       base >= 4.7 && < 5,
+                       text <= 1.2.2.2,
+                       terminfo <= 0.4.1.0,
+                       ansi-terminal >= 0.6.0.0 && <= 0.7.1.1
+  default-language:    Haskell2010
+
+executable             examples
+  main-is:             Main.hs
+  other-modules:       InputExample,
+                       ConfirmExample,
+                       PasswordExample,
+                       SelectExample,
+                       MultiselectExample
+  hs-source-dirs:      examples
+  build-depends:       base >= 4.7 && < 5,
+                       fortytwo
+  default-language:    Haskell2010
+
+Test-Suite spec
+  type:              exitcode-stdio-1.0
+  default-language:  Haskell2010
+  main-is:           Main.hs
+  other-modules:     Specs.Core,
+                     Specs.Utils
+  hs-source-dirs:    test
+  build-depends:     fortytwo,
+                     base >=4.9 && <4.10,
+                     process >=1.4 && <1.5,
+                     async >=2.1 && <2.2,
+                     hspec >= 2.2
+
+Test-Suite doctest
+  type:              exitcode-stdio-1.0
+  default-language:  Haskell2010
+  main-is:           doctests.hs
+  hs-source-dirs:    test
+  build-depends:     fortytwo,
+                     base,
+                     doctest >= 0.8.0
+
+source-repository head
+  type:     git
+  location: https://github.com/gianlucaguarini/fortytwo
diff --git a/src/FortyTwo.hs b/src/FortyTwo.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo.hs
@@ -0,0 +1,20 @@
+module FortyTwo
+    (
+      theAnswerToEverything,
+      input,
+      inputWithDefault,
+      confirm,
+      confirmWithDefault,
+      password,
+      select,
+      selectWithDefault,
+      multiselect,
+      multiselectWithDefault
+    ) where
+
+import FortyTwo.Prompts.Input
+import FortyTwo.Prompts.Confirm
+import FortyTwo.Prompts.Password
+import FortyTwo.Prompts.Select
+import FortyTwo.Prompts.Multiselect
+import FortyTwo.TheAnswerToEverything
diff --git a/src/FortyTwo/Constants.hs b/src/FortyTwo/Constants.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Constants.hs
@@ -0,0 +1,41 @@
+module FortyTwo.Constants where
+
+upKey :: String
+upKey = "\ESC[A"
+
+downKey :: String
+downKey = "\ESC[B"
+
+rightKey :: String
+rightKey = "\ESC[C"
+
+leftKey :: String
+leftKey = "\ESC[D"
+
+delKey :: String
+delKey = "\DEL"
+
+enterKey :: String
+enterKey = "\n"
+
+spaceKey :: String
+spaceKey = " "
+
+emptyString :: String
+emptyString = ""
+
+-- | Char used to highlight a option
+focusIcon :: Char
+focusIcon = '❯'
+
+-- | Char to identify the options selected
+selectedIcon :: Char
+selectedIcon = '◉'
+
+-- | Char to identify the options not yet selected
+unselectedIcon :: Char
+unselectedIcon = '◯'
+
+-- | Char used to hide the password letters
+passwordHiddenChar :: Char
+passwordHiddenChar = '*'
diff --git a/src/FortyTwo/Prompts/Confirm.hs b/src/FortyTwo/Prompts/Confirm.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Prompts/Confirm.hs
@@ -0,0 +1,40 @@
+module FortyTwo.Prompts.Confirm (confirm, confirmWithDefault) where
+
+import qualified Data.Text as T
+
+import FortyTwo.Renderers.Confirm (renderConfirm)
+import FortyTwo.Renderers.Question (renderQuestion)
+import FortyTwo.Utils (clearLines, flush)
+import FortyTwo.Constants (emptyString)
+
+-- | Normalize a string transforming it to lowercase and trimming it and getting either n or y
+normalizeString :: String -> String
+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
+
+-- | Ask a confirm falling back to a default value if no answer will be provided
+-- confirmWithDefault "Do you like music?" True
+confirmWithDefault :: String -> Bool -> IO Bool
+confirmWithDefault question defaultAnswer = do
+  putStrLn emptyString
+  renderQuestion question defaultAnswerHumanized emptyString
+  renderConfirm
+  flush
+  answer <- getCleanConfirm
+  clearLines 1
+  if answer == "n" || (answer /= "y" && not defaultAnswer) then do
+    renderQuestion question emptyString "no"
+    return False
+  else do
+    renderQuestion question emptyString "yes"
+    return True
+  where
+    defaultAnswerHumanized = if defaultAnswer then "yes" else "no"
+
+-- | Ask a confirm question by default it will be true
+-- confirm "Do you like music?"
+confirm :: String -> IO Bool
+confirm question = confirmWithDefault question False
diff --git a/src/FortyTwo/Prompts/Input.hs b/src/FortyTwo/Prompts/Input.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Prompts/Input.hs
@@ -0,0 +1,28 @@
+module FortyTwo.Prompts.Input (inputWithDefault, input) where
+
+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
+  putStrLn emptyString
+  renderQuestion question defaultAnswer emptyString
+  putStr " "
+  flush
+  answer <- getLine
+  clearLines 1
+  -- return the default answer if no answer was given
+  if null answer then do
+    renderQuestion question emptyString defaultAnswer
+    return defaultAnswer
+  else do
+    renderQuestion question emptyString answer
+    return answer
+
+-- | Simple input question
+-- input "What is your name?"
+input :: String -> IO String
+input question = inputWithDefault question emptyString
diff --git a/src/FortyTwo/Prompts/Multiselect.hs b/src/FortyTwo/Prompts/Multiselect.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Prompts/Multiselect.hs
@@ -0,0 +1,81 @@
+{-# LANGUAGE NamedFieldPuns #-}
+
+module FortyTwo.Prompts.Multiselect (multiselect, multiselectWithDefault) where
+
+import System.Console.ANSI (hideCursor, showCursor)
+import FortyTwo.Renderers.Multiselect (renderOptions)
+import FortyTwo.Renderers.Question (renderQuestion)
+import FortyTwo.Types(Option(..), Options)
+import FortyTwo.Utils
+import FortyTwo.Constants
+
+-- | Loop to let the users select an single option
+loop :: Options -> IO [Int]
+loop options = do
+  noEcho
+  renderOptions options
+  key <- getKey
+  clearLines $ length options
+  res <- handleEvent options key
+  restoreEcho
+  return res
+
+-- | Handle a user event
+handleEvent :: Options -> String -> IO [Int]
+handleEvent options key
+  | key `elem` [upKey, leftKey]  = loop $ moveUp options $ getOptionsMeta options
+  | key `elem` [downKey, rightKey]  = loop $ moveDown options $ getOptionsMeta options
+  | key == spaceKey = loop $ toggle options $ getOptionsMeta options
+  | key == enterKey = return $ getSelecteOptionsIndexes options
+  | otherwise = loop options
+
+toggle :: Options -> (Int, Int, Maybe Int) -> Options
+toggle options (minVal, maxVal, focusedIndex) = case focusedIndex of
+  Just x -> toggleFocusedOption x options
+  Nothing -> options
+
+-- | Handle an arrow up event
+moveUp :: Options -> (Int, Int, Maybe Int) -> Options
+moveUp options (minVal, maxVal, focusedIndex) = case focusedIndex of
+  Just x -> if x == minVal then
+             focusOption x options
+            else
+             focusOption (x - 1) options
+  Nothing -> focusOption maxVal options
+
+-- | Handle an arrow down event
+moveDown :: Options -> (Int, Int, Maybe Int) -> Options
+moveDown options (minVal, maxVal, focusedIndex) = case focusedIndex of
+  Just x -> if x == maxVal then
+             focusOption x options
+            else
+             focusOption (x + 1) options
+  Nothing -> focusOption minVal options
+
+-- | 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
+  putStrLn emptyString
+  renderQuestion question (toCommaSeparatedString defaultAnswer) emptyString
+  putStrLn emptyString
+  hideCursor
+  flush
+  noBuffering
+  res <- loop $ stringsToOptions options
+  restoreBuffering
+  showCursor
+  clearLines 1
+
+  if null res then do
+    renderQuestion question emptyString (toCommaSeparatedString defaultAnswer)
+    return defaultAnswer
+  else do
+    let answer = filter' (\ i o -> elem i res) options
+    renderQuestion question emptyString (toCommaSeparatedString answer)
+    return answer
+
+-- | Multi Select prompt
+-- multiselect "What's your favourite color?" ["Red", "Yellow", "Blue"]
+multiselect :: String -> [String] -> IO [String]
+multiselect question options = multiselectWithDefault question options []
diff --git a/src/FortyTwo/Prompts/Password.hs b/src/FortyTwo/Prompts/Password.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Prompts/Password.hs
@@ -0,0 +1,52 @@
+module FortyTwo.Prompts.Password (password) where
+
+import System.Console.ANSI (cursorBackward, clearFromCursorToScreenEnd, setCursorColumn, clearFromCursorToLineEnd)
+import Control.Monad (unless)
+import FortyTwo.Renderers.Password (renderPassword, hideLetters)
+import FortyTwo.Renderers.Question (renderQuestion)
+import FortyTwo.Constants (emptyString, enterKey, delKey)
+import FortyTwo.Utils
+
+-- | Ask a user password
+-- password "What your secret password?"
+password :: String -> IO String
+password question = do
+  putStrLn emptyString
+  renderQuestion question emptyString emptyString
+  putStr " "
+  flush
+  noBuffering
+  answer <- loop emptyString
+  restoreBuffering
+  -- for the password prompt we need to clear the prompt a bit differently
+  setCursorColumn 0
+  clearFromCursorToLineEnd
+  renderQuestion question emptyString $ hideLetters answer
+  return answer
+
+-- | Loop to let the users select an single option
+loop :: String -> IO String
+loop pass = do
+  noEcho
+  renderPassword pass
+  key <- getKey
+
+  -- Cancel part of the password avoiding to cancel the question as well
+  -- the password and the question are located on the same line
+  unless (null pass) $ do
+    cursorBackward $ length pass
+    clearFromCursorToScreenEnd
+
+  -- Try to filter the control keys
+  res <- handleEvent pass (if length key > 1 then emptyString else key)
+  restoreEcho
+  return res
+
+-- | Handle a user event
+handleEvent :: String -> String -> IO String
+handleEvent pass key
+  | key == enterKey = return pass
+  | key == delKey =
+    if null pass then return loop emptyString pass
+    else return loop emptyString (init pass)
+  | otherwise = loop $ pass ++ key
diff --git a/src/FortyTwo/Prompts/Select.hs b/src/FortyTwo/Prompts/Select.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Prompts/Select.hs
@@ -0,0 +1,78 @@
+{-# LANGUAGE NamedFieldPuns #-}
+
+module FortyTwo.Prompts.Select (select, selectWithDefault) where
+
+import System.Console.ANSI (hideCursor, showCursor)
+import FortyTwo.Renderers.Select (renderOptions)
+import FortyTwo.Renderers.Question (renderQuestion)
+import FortyTwo.Types(Option(..), Options)
+import FortyTwo.Utils
+import FortyTwo.Constants
+
+-- | Loop to let the users select an single option
+loop :: Options -> IO (Maybe Int)
+loop options = do
+  noEcho
+  renderOptions options
+  key <- getKey
+  clearLines $ length options
+  res <- handleEvent options key
+  restoreEcho
+  return res
+
+-- | Handle a user event
+handleEvent :: Options -> String -> IO (Maybe Int)
+handleEvent options key
+  | key `elem` [upKey, leftKey]  = loop $ moveUp options $ getOptionsMeta options
+  | key `elem` [downKey, rightKey]  = loop $ moveDown options $ getOptionsMeta options
+  | key `elem` [enterKey, spaceKey] = return $ getFocusedOptionIndex options
+  | otherwise = loop options
+
+-- | Handle an arrow up event
+moveUp :: Options -> (Int, Int, Maybe Int) -> Options
+moveUp options (minVal, maxVal, focusedIndex) = case focusedIndex of
+  Just x -> if x == minVal then
+             focusOption x options
+            else
+             focusOption (x - 1) options
+  Nothing -> focusOption maxVal options
+
+-- | Handle an arrow down event
+moveDown :: Options -> (Int, Int, Maybe Int) -> Options
+moveDown options (minVal, maxVal, focusedIndex) = case focusedIndex of
+  Just x -> if x == maxVal then
+             focusOption x options
+            else
+             focusOption (x + 1) options
+  Nothing -> focusOption minVal options
+
+-- | 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
+  putStrLn emptyString
+  renderQuestion question defaultAnswer emptyString
+  putStrLn emptyString
+  hideCursor
+  flush
+  noBuffering
+  res <- loop $ stringsToOptions options
+  restoreBuffering
+  showCursor
+  clearLines 1
+
+  case res of
+    Just x  -> do
+      let answer = (!!) options x
+      renderQuestion question emptyString answer
+      return answer
+    -- If no user input will be provided..
+    Nothing -> do
+      -- ..let's return the default answer
+      renderQuestion question emptyString defaultAnswer
+      return defaultAnswer
+
+-- | Select prompt from a list of options
+-- select "What's your favourite color?" ["Red", "Yellow", "Blue"]
+select :: String -> [String] -> IO String
+select question options = selectWithDefault question options emptyString
diff --git a/src/FortyTwo/Renderers/Confirm.hs b/src/FortyTwo/Renderers/Confirm.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Renderers/Confirm.hs
@@ -0,0 +1,8 @@
+module FortyTwo.Renderers.Confirm
+    (
+      renderConfirm
+    ) where
+
+-- | Render the helper text
+renderConfirm :: IO ()
+renderConfirm = putStr " (y/N) "
diff --git a/src/FortyTwo/Renderers/Multiselect.hs b/src/FortyTwo/Renderers/Multiselect.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Renderers/Multiselect.hs
@@ -0,0 +1,29 @@
+{-# LANGUAGE NamedFieldPuns #-}
+
+module FortyTwo.Renderers.Multiselect (renderOptions, renderOption) where
+
+import FortyTwo.Types (Option(..), Options)
+import System.Console.ANSI
+import Control.Monad (when)
+import FortyTwo.Constants
+
+-- | Render all the options collection
+renderOptions :: Options -> IO ()
+renderOptions = mapM_ renderOption
+
+-- | Render a single option items
+renderOption :: Option -> IO()
+renderOption Option { isSelected, isFocused, value } = do
+  if isFocused then do
+    setSGR [SetColor Foreground Dull Cyan]
+    putStr $ focusIcon : " "
+    setSGR [Reset]
+  else
+    putStr "  "
+  if isSelected then do
+    setSGR [SetColor Foreground Dull Green]
+    putStr [selectedIcon]
+    setSGR [Reset]
+  else putStr [unselectedIcon]
+  putStr $ " " ++ value
+  putStrLn emptyString
diff --git a/src/FortyTwo/Renderers/Password.hs b/src/FortyTwo/Renderers/Password.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Renderers/Password.hs
@@ -0,0 +1,11 @@
+module FortyTwo.Renderers.Password (renderPassword, hideLetters) where
+
+import FortyTwo.Constants (passwordHiddenChar)
+
+-- | Print the password value to the user hiding it
+renderPassword :: String -> IO ()
+renderPassword letters = putStr $ hideLetters letters
+
+-- | Hide any string replacing its letters with the passwordHiddenChar
+hideLetters :: String -> String
+hideLetters letters = [passwordHiddenChar | x <- letters]
diff --git a/src/FortyTwo/Renderers/Question.hs b/src/FortyTwo/Renderers/Question.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Renderers/Question.hs
@@ -0,0 +1,41 @@
+module FortyTwo.Renderers.Question (renderQuestion, renderMessage) where
+
+import FortyTwo.Types (Message(..))
+import System.Console.ANSI
+
+-- | Print any message depending on its type
+renderMessage :: Message -> String -> IO()
+renderMessage messageType message
+  | messageType == Question = do
+      setSGR [SetColor Foreground Dull Green]
+      putStr "? "
+      setSGR [Reset]
+      setSGR [SetColor Foreground Dull White]
+      putStr message
+      setSGR [Reset]
+  | messageType == Answer = do
+      setSGR [SetColor Foreground Dull Cyan]
+      putStr $ " " ++ message
+      setSGR [Reset]
+  | messageType == DefaultAnswer = do
+    setSGR [SetColor Foreground Vivid Yellow]
+    putStr $ " (" ++ message ++ ")"
+    setSGR [Reset]
+
+-- | Print the question message
+renderQuestion :: String -> String -> String -> IO ()
+renderQuestion question defaultAnswer answer
+  | hasDefaultAnswer && hasAnswer = do
+      renderMessage Question question
+      renderMessage DefaultAnswer defaultAnswer
+      renderMessage Answer answer
+  | hasDefaultAnswer = do
+      renderMessage Question question
+      renderMessage DefaultAnswer defaultAnswer
+  | hasAnswer = do
+      renderMessage Question question
+      renderMessage Answer answer
+  | otherwise = renderMessage Question question
+  where
+      hasDefaultAnswer = not $ null defaultAnswer
+      hasAnswer = not $ null answer
diff --git a/src/FortyTwo/Renderers/Select.hs b/src/FortyTwo/Renderers/Select.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Renderers/Select.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE NamedFieldPuns #-}
+
+module FortyTwo.Renderers.Select (renderOptions, renderOption) where
+
+import FortyTwo.Types (Option(..), Options)
+import System.Console.ANSI
+import FortyTwo.Constants
+
+-- | Render all the options collection
+renderOptions :: Options -> IO ()
+renderOptions = mapM_ renderOption
+
+-- | Render a single option items
+renderOption :: Option -> IO()
+renderOption Option { isSelected, isFocused, value } =
+  if isFocused then do
+    setSGR [SetColor Foreground Dull Cyan]
+    putStrLn $ unwords [[focusIcon], value]
+    setSGR [Reset]
+  else
+    putStrLn $ "  " ++ value
diff --git a/src/FortyTwo/TheAnswerToEverything.hs b/src/FortyTwo/TheAnswerToEverything.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/TheAnswerToEverything.hs
@@ -0,0 +1,8 @@
+module FortyTwo.TheAnswerToEverything
+    (
+      theAnswerToEverything
+    ) where
+
+-- | The answer to everything in the universe
+theAnswerToEverything :: Int
+theAnswerToEverything = 42
diff --git a/src/FortyTwo/Types.hs b/src/FortyTwo/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Types.hs
@@ -0,0 +1,13 @@
+module FortyTwo.Types where
+
+-- | UI message types
+data Message = Question | DefaultAnswer | Answer deriving (Eq)
+
+-- | Struct needed for rendering the select prompts
+data Option = Option {
+  isSelected :: Bool,
+  isFocused :: Bool,
+  value :: String
+} deriving (Eq, Show)
+
+type Options = [Option]
diff --git a/src/FortyTwo/Utils.hs b/src/FortyTwo/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/FortyTwo/Utils.hs
@@ -0,0 +1,106 @@
+{-# LANGUAGE NamedFieldPuns #-}
+
+module FortyTwo.Utils where
+
+import System.Console.ANSI (cursorUpLine, clearFromCursorToScreenEnd)
+import System.IO (hSetBuffering, hFlush, hSetEcho, hReady, stdin, stdout, BufferMode(..))
+import Data.List (findIndex, findIndices, elemIndex, intercalate)
+import Control.Monad (when)
+import Data.Maybe (fromJust)
+import FortyTwo.Types(Option(..), Options)
+import FortyTwo.Constants (emptyString)
+
+noBuffering :: IO()
+noBuffering = do
+  hSetBuffering stdin NoBuffering
+  hSetBuffering stdout NoBuffering
+
+restoreBuffering :: IO()
+restoreBuffering = do
+  hSetBuffering stdin LineBuffering
+  hSetBuffering stdout LineBuffering
+
+noEcho :: IO ()
+noEcho = hSetEcho stdin False
+
+restoreEcho :: IO ()
+restoreEcho = hSetEcho stdin True
+
+clearLines :: Int -> IO()
+clearLines lines' = do
+  -- move up of 1 line...
+  cursorUpLine lines'
+  -- and clear them
+  clearFromCursorToScreenEnd
+
+-- | Map a collection with an index
+map' :: (Int -> a -> b) -> [a] -> [b]
+map' f = zipWith f [0..]
+
+-- | Filter a collection with index
+filter' :: Eq a => (Int -> a -> Bool) -> [a] -> [a]
+filter' f xs = [x | x <- xs, f (fromJust (elemIndex x xs)) x]
+
+getKey = reverse <$> getKey' emptyString
+  where
+    getKey' chars = do
+      char <- getChar
+      more <- hReady stdin
+      (if more then getKey' else return) (char:chars)
+
+-- | Get useful informations from the options collection, like minVal, maxVal, activeIndex
+getOptionsMeta :: Options -> (Int, Int, Maybe Int)
+getOptionsMeta options = (0, length options - 1, getFocusedOptionIndex options)
+
+-- | Convert a string array to
+stringsToOptions :: [String] -> Options
+stringsToOptions options = [
+    Option { value = o, isFocused = False, isSelected = False } | o <- options
+  ]
+
+-- | Give the focus to a single option in the collection
+focusOption :: Int -> Options -> Options
+focusOption focusedIndex = map' $ \ i o ->
+  Option {
+    value = getOptionValue o,
+    isSelected = getOptionIsSelected o,
+    isFocused = focusedIndex == i
+  }
+-- | Toggle the isSelected flag for a single option
+toggleFocusedOption :: Int -> Options -> Options
+toggleFocusedOption focusedIndex = map' $ \ i o ->
+  Option {
+    value = getOptionValue o,
+    isFocused = focusedIndex == i,
+    isSelected = if focusedIndex == i then
+      not $ getOptionIsSelected o
+      else getOptionIsSelected o
+  }
+
+-- | Print a list to comma separated
+toCommaSeparatedString :: [String] -> String
+toCommaSeparatedString = intercalate ", "
+
+-- | Flush the output buffer
+flush :: IO()
+flush = hFlush stdout
+
+-- | Get the value of any option
+getOptionValue :: Option -> String
+getOptionValue Option { value } = value
+
+-- | Get the is focused attribute of any option
+getOptionIsFocused :: Option -> Bool
+getOptionIsFocused Option { isFocused } = isFocused
+
+-- | Get the is selected attribute of any option
+getOptionIsSelected :: Option -> Bool
+getOptionIsSelected Option { isSelected } = isSelected
+
+-- | Get the index of the option selected
+getFocusedOptionIndex :: Options -> Maybe Int
+getFocusedOptionIndex = findIndex getOptionIsFocused
+
+-- | Filter the indexes of the options selected
+getSelecteOptionsIndexes :: Options -> [Int]
+getSelecteOptionsIndexes = findIndices getOptionIsSelected
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,11 @@
+module Main (main) where
+
+import qualified Specs.Core
+import qualified Specs.Utils
+import Test.Hspec
+
+main :: IO ()
+main = hspec $
+  describe "FortyTwo" $ do
+    Specs.Core.main
+    Specs.Utils.main
diff --git a/test/Specs/Core.hs b/test/Specs/Core.hs
new file mode 100644
--- /dev/null
+++ b/test/Specs/Core.hs
@@ -0,0 +1,9 @@
+module Specs.Core (main) where
+import FortyTwo
+import Test.Hspec
+
+main :: SpecWith ()
+main =
+  describe "theAnswerToEverything" $
+    it "Get the answer to everything" $
+      theAnswerToEverything `shouldBe` (42 :: Int)
diff --git a/test/Specs/Utils.hs b/test/Specs/Utils.hs
new file mode 100644
--- /dev/null
+++ b/test/Specs/Utils.hs
@@ -0,0 +1,22 @@
+module Specs.Utils (main) where
+
+import Data.Maybe
+import FortyTwo.Utils
+import FortyTwo.Types
+import Test.Hspec
+
+main :: SpecWith ()
+main =
+  describe "Utils" $ do
+    let list = ["one", "two", "three"]
+    it "It converts strings to valid options" $ do
+      let options = stringsToOptions list
+      getOptionValue ((!!) options 0) `shouldBe` (!!) list 0
+
+    it "Can update properly an options collection with a defined index" $ do
+      let selectedIndex = 1
+      let options = focusOption selectedIndex $ stringsToOptions list
+      fromJust (getFocusedOptionIndex options) `shouldBe` selectedIndex
+
+    it "Return 0 if no option will be selected" $
+        fromMaybe 0 (getFocusedOptionIndex $ stringsToOptions list) `shouldBe` 0
diff --git a/test/doctests.hs b/test/doctests.hs
new file mode 100644
--- /dev/null
+++ b/test/doctests.hs
@@ -0,0 +1,12 @@
+module Main where
+
+import Test.DocTest
+
+main :: IO ()
+main = doctest [
+    "src/FortyTwo.hs",
+    "src/FortyTwo/TheAnswerToEverything.hs",
+    "src/FortyTwo/Types.hs",
+    "src/FortyTwo/Prompts/Input.hs",
+    "src/FortyTwo/Renderers/Question.hs"
+  ]
