diff --git a/lib/System/Console/ListPrompt.hs b/lib/System/Console/ListPrompt.hs
--- a/lib/System/Console/ListPrompt.hs
+++ b/lib/System/Console/ListPrompt.hs
@@ -10,8 +10,12 @@
     )
   where
 
+import           Control.Concurrent.STM
 import           Control.Monad                      (forM_)
 import           Data.Default                       (Default (..), def)
+import           Graphics.Vty                       (Event (..), Key (..),
+                                                     Modifier (..))
+import qualified Graphics.Vty                       as Vty
 import           System.Console.ANSI
 import           System.IO                          (BufferMode (..), stdin)
 
@@ -19,35 +23,40 @@
 import           System.Console.ListPrompt.Internal
 import           System.Console.ListPrompt.Types
 
-simpleListPrompt :: ListPromptOptions -> Choices -> IO String
+simpleListPrompt :: ListPromptOptions -> Choices -> IO (Maybe String)
 simpleListPrompt options choices = setup $ do
-    dimensions <- getDimensionsIO numChoices
-    selection <- waitForSelection dimensions 0
+    inp <- Vty.inputForConfig =<< Vty.standardIOConfig
+    selection <- waitForSelection (Vty._eventChannel inp) 0
     setSGR []
     clearScreen
     setCursorPosition 0 0
+    Vty.shutdownInput inp
     return selection
   where
     setup = withNoBuffering stdin NoBuffering . withNoCursor . withNoEcho
     numChoices = length choices
 
-    waitForSelection dimensions currentIdx = do
+    waitForSelection ichan currentIdx = do
         clearScreen
-        renderListOptions options dimensions choices currentIdx
-        i <- getChar
-        case i of
-           '\n' -> return $ choices !! currentIdx
-           'j' -> waitForSelection
-                      dimensions
-                      ((currentIdx + 1) `rem` numChoices)
-           'k' -> waitForSelection
-                      dimensions
-                      currentIdx'
-             where
-               currentIdx' = if currentIdx == 0
-                                 then length choices - 1
-                                 else currentIdx - 1
-           _ -> waitForSelection dimensions currentIdx
+        renderListOptions options def choices currentIdx
+        e <- atomically $ readTChan ichan
+        case e of
+            EvKey KEnter _ -> return $ Just (choices !! currentIdx)
+            EvKey (KChar 'n') [MCtrl] -> onDown
+            EvKey (KChar 'j') _ -> onDown
+            EvKey KDown _ -> onDown
+            EvKey (KChar 'p') [MCtrl] -> onUp
+            EvKey (KChar 'k') _ -> onUp
+            EvKey KUp _ -> onUp
+            EvKey (KChar 'q') _ -> return Nothing
+            EvKey KEsc _ -> return Nothing
+            _ -> waitForSelection ichan currentIdx
+      where
+        onDown = waitForSelection ichan ((currentIdx + 1) `rem` numChoices)
+        onUp = let currentIdx' = if currentIdx == 0
+                                   then length choices - 1
+                                   else currentIdx - 1
+                 in waitForSelection ichan currentIdx'
 
 renderListOptions :: ListPromptOptions
                   -> ListPromptDimensions
diff --git a/lib/System/Console/ListPrompt/Internal.hs b/lib/System/Console/ListPrompt/Internal.hs
--- a/lib/System/Console/ListPrompt/Internal.hs
+++ b/lib/System/Console/ListPrompt/Internal.hs
@@ -1,17 +1,20 @@
 module System.Console.ListPrompt.Internal
   where
 
-import Control.Applicative ((<$>))
-import Control.Exception (bracket_)
-import System.Console.ANSI
-import System.Console.Terminal.Size (size, Window(..))
-import System.IO (hGetBuffering, hSetBuffering, hSetEcho, stdin)
+import           Control.Applicative             ((<$>))
+import           Control.Exception               (bracket_)
+import           Data.Default                    (def)
+import           System.Console.ANSI
+import           System.Console.Terminal.Size    (Window (..), size)
+import           System.IO                       (BufferMode, Handle,
+                                                  hGetBuffering, hSetBuffering,
+                                                  hSetEcho, stdin)
 
-import System.Console.ListPrompt.Types
+import           System.Console.ListPrompt.Types
 
 -- |
 -- Calculates the optimal position for the prompt optionally with the
--- terminal's size and -- the number of available choices
+-- terminal's size and the number of available choices
 getDimensions :: Int -> Maybe (Window Int) -> ListPromptDimensions
 getDimensions numChoices (Just (Window h w)) =
     ListPromptDimensions { targetCoordinate = tc
@@ -22,13 +25,18 @@
     padding = 3
     tc = ((h `div` 2 - numChoices `div` 2) - padding, padding)
     lps = (numChoices + margin, w - margin * 2)
+getDimensions _ Nothing = def
 
 getDimensionsIO :: Int -> IO ListPromptDimensions
 getDimensionsIO n = getDimensions n <$> size
 
+withNoCursor :: IO a -> IO a
 withNoCursor = bracket_ hideCursor showCursor
+
+withNoEcho :: IO a -> IO a
 withNoEcho = bracket_ (hSetEcho stdin False) (hSetEcho stdin True)
 
+withNoBuffering :: Handle -> BufferMode -> IO a -> IO a
 withNoBuffering handle newBuffering action = do
     originalBuffering <- hGetBuffering handle
     bracket_
diff --git a/lib/System/Console/ListPrompt/Types.hs b/lib/System/Console/ListPrompt/Types.hs
--- a/lib/System/Console/ListPrompt/Types.hs
+++ b/lib/System/Console/ListPrompt/Types.hs
@@ -1,11 +1,11 @@
 module System.Console.ListPrompt.Types
   where
 
-import Data.Default (Default(..))
-import System.Console.ANSI
+import           Data.Default        (Default (..))
+import           System.Console.ANSI
 
 data ListPromptOptions = ListPromptOptions { selectedItemSGR :: [SGR]
-                                           , normalItemSGR :: [SGR]
+                                           , normalItemSGR   :: [SGR]
                                            }
   deriving(Show, Ord, Eq)
 
@@ -20,12 +20,12 @@
 
 data ListPromptDimensions =
     ListPromptDimensions { targetCoordinate :: (Int, Int)
-                         , listPromptSize :: (Int, Int)
+                         , listPromptSize   :: (Int, Int)
                          }
   deriving(Show, Ord, Eq)
 
 instance Default ListPromptDimensions where
-    def = ListPromptDimensions { targetCoordinate = (0, 0)
+    def = ListPromptDimensions { targetCoordinate = (1, 2)
                                , listPromptSize = (80, 80)
                                }
 
diff --git a/list-prompt.cabal b/list-prompt.cabal
--- a/list-prompt.cabal
+++ b/list-prompt.cabal
@@ -1,5 +1,5 @@
 name:                list-prompt
-version:             0.1.0.0
+version:             0.1.1.0
 synopsis:            A simple list prompt UI for the terminal.
 description:         See https://github.com/yamadapc/list-prompt
 homepage:            https://github.com/yamadapc/list-prompt.git
@@ -30,7 +30,9 @@
   build-depends:       ansi-terminal
                      , base >=4.5 && <5
                      , data-default
+                     , stm >= 2.4.4
                      , terminal-size
+                     , vty
   hs-source-dirs:      lib
   default-language:    Haskell2010
 
@@ -45,20 +47,26 @@
   build-depends:       ansi-terminal
                      , base >=4.5 && <5
                      , data-default
+                     , list-prompt
+                     , stm >= 2.4.4
                      , terminal-size
+                     , vty
   hs-source-dirs:      bin
                      , lib
   main-is:             SimpleDemo.hs
   default-language:    Haskell2010
+  ghc-options:         -threaded -O2
 
 test-suite hspec
   type:                exitcode-stdio-1.0
   build-depends:       ansi-terminal
                      , base >=4.5 && <5
                      , data-default
-                     , terminal-size
-
                      , hspec
+                     , list-prompt
+                     , stm >= 2.4.4
+                     , terminal-size
+                     , vty
   hs-source-dirs:      bin
                      , lib
                      , test
