diff --git a/rosa.cabal b/rosa.cabal
--- a/rosa.cabal
+++ b/rosa.cabal
@@ -1,5 +1,5 @@
 name:                rosa
-version:             0.2.2.0
+version:             0.3.0.0
 synopsis:            Query the namecoin blockchain
 description:
 
@@ -31,5 +31,5 @@
   build-depends:       base >=4.8 && <5.0 , aeson, text,
                        vector, unordered-containers,
                        wreq, lens >=4.4, bytestring,
-                       argparser, process   
+                       optparse-applicative, process
   ghc-options:         -O2
diff --git a/src/Json.hs b/src/Json.hs
--- a/src/Json.hs
+++ b/src/Json.hs
@@ -1,3 +1,4 @@
+-- | JSON utilities
 module Json where
 
 import Data.Aeson
@@ -8,17 +9,19 @@
 import qualified Data.Vector         as V
 import qualified Data.HashMap.Strict as H
 
--- Get the JSON value of a key
+-- | Get the JSON value of a key
 (|.) :: Object -> Text -> Value
 obj |. key = case parse (.: key) obj of
   Success val -> val
   Error err -> toJSON err
 
--- Get the String value of a key
+
+-- | Get the String value of a key
 (|:) :: Object -> Text -> String
 obj |: key = repr (obj |. key)
 
--- Create a String representation of a JSON value
+
+-- | Create a String representation of a 'Value'
 repr :: Value -> String
 repr obj = repr' obj 0 where
   repr' val lev =
@@ -34,6 +37,7 @@
   indent l = '\n' : (concat . replicate l) "  "
   dump o l k = concat [indent l, unpack k, ": ", repr' (o |. k) (l+1)]
 
--- Pretty print a JSON value
+
+-- | Pretty print a JSON 'Value'
 pprint :: Value -> IO ()
 pprint = putStrLn . repr
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -1,4 +1,6 @@
 {-# LANGUAGE RecordWildCards, OverloadedStrings #-}
+-- | Main module
+module Main where
 
 import Json
 
@@ -9,41 +11,68 @@
 import Data.Maybe                  (fromJust)
 import Data.HashMap.Strict         (delete)
 import Data.ByteString.Lazy.Char8  (pack)
-import System.Console.ArgParser
+import Options.Applicative
 import System.Process
 
-data ProgArgs = ProgArgs
+
+-- * CLI interface
+
+-- | Program arguments record
+data Options = Options
   { name     :: String
   , url      :: String
   , dnschain :: Bool
   , block    :: Bool
   , raw      :: Bool
-  } deriving (Show)
+  }
 
-parser :: ParserSpec ProgArgs
-parser = ProgArgs
-  `parsedBy` reqPos   "name"     `Descr` "Namecoin name id"
-  `andBy`    optFlag  "http://dns.dnschain.net/" "url"
-                                 `Descr` "Use custom api url"
-  `andBy`    boolFlag "dnschain" `Descr` "Use dnschain api"
-  `andBy`    boolFlag "block"    `Descr` "Show blockchain data (require local connecton)"
-  `andBy`    boolFlag "raw"      `Descr` "Print raw JSON data"
+-- | Program arguments parser
+options :: Parser Options
+options = Options
+  <$> strArgument
+      ( metavar "NAME"
+     <> help "Namecoin name id" )
+  <*> strOption
+      ( long "url"
+     <> short 'u'
+     <> value "http://dns.dnschain.net/"
+     <> metavar "URL"
+     <> help "Use custom api url" )
+  <*> switch
+      ( long "dnschain"
+     <> short 'd'
+     <> help "Use dnschain api" )
+  <*> switch
+      ( long "block"
+     <> short 'b'
+     <> help "Show blockchain data (require local connection)" )
+  <*> switch
+      ( long "raw"
+     <> short 'r'
+     <> help "Print raw JSON data" )
 
-interface :: IO (CmdLnInterface ProgArgs)
-interface =
-  (`setAppDescr`  "Query the namecoin blockchain") .
-  (`setAppEpilog` "Stat rosa pristina nomine, nomina nuda tenemus.") <$>
-  mkApp parser
 
+-- | Program description
+description :: ParserInfo Options
+description = info (helper <*> options)
+  ( fullDesc
+ <> progDesc "Query the namecoin blockchain"
+ <> footer "Stat rosa pristina nomine, nomina nuda tenemus." )
+
+
+
+-- * Program
+
+-- | Main function
 main :: IO ()
-main = interface >>= flip runApp exec
+main = execParser description >>= exec where
+  exec Options{..} =
+    if dnschain
+      then doDnschain url name raw
+      else doLocal name block
 
-exec :: ProgArgs -> IO ()
-exec ProgArgs{..} =
-  if dnschain
-  then doDnschain url name raw
-  else doLocal name block
 
+-- | Connect to local namecoin node
 doLocal :: String -> Bool -> IO ()
 doLocal name block = do
   out <- readProcess "namecoin-cli" ["name_show", name] ""
@@ -56,12 +85,14 @@
         reparse = fromJust . decode . pack
         extra   = toJSON (delete "value" res)
 
+
+-- | Connect to dnschain api endpoint
 doDnschain :: String -> String -> Bool -> IO ()
 doDnschain url name raw = do
   body <- (^. responseBody) <$> get (url ++ name)
   if raw
-  then print body
-  else putStrLn $
-    case decode body of
-      Just res -> repr res
-      Nothing  -> "Error parsing data"
+    then print body
+    else putStrLn $
+      case decode body of
+        Just res -> repr res
+        Nothing  -> "Error parsing data"
