diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -1,16 +1,41 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE RecordWildCards #-}
 module Main where
 
-import           System.Environment (getArgs, getProgName)
+import           System.Environment             ( getArgs
+                                                , getProgName
+                                                )
 import           Templating
+import           System.Console.CmdArgs.Implicit
+import           Data.Maybe                     ( fromMaybe )
 
+data HifiArgs = HifiArgs { filename :: Maybe String
+                         , interface :: Maybe Interface
+                         , ssid :: Maybe SSID
+                         , passphrase :: Maybe Passphrase
+                         } deriving (Show, Data, Typeable)
+
+hifiArgs =
+  HifiArgs
+      { filename   = def
+        &= help "What the script and data files should be called."
+        &= typ "FILENAME"
+      , interface  = def
+        &= help "Which interface should be used in the connect script."
+        &= typ "INTERFACE"
+      , ssid = def &= help "Which SSID the network you want to connect to has."
+      , passphrase = def &= help
+        "What the passphrase for the network you want to connect to is."
+      }
+    &= summary "Hifi"
+
 main :: IO ()
 main = do
-  args <- getArgs
-  progName <- getProgName
-  case args of
-    [filename, iface, ssid, passphrase] -> do
-      (scriptFile, dataFile) <- createFiles filename iface ssid passphrase
+  HifiArgs {..} <- cmdArgs hifiArgs
+  case sequence [filename, interface, ssid, passphrase] of
+    Just [filename, interface, ssid, passphrase] -> do
+      (scriptFile, dataFile) <- createFiles filename interface ssid passphrase
       putStrLn $ "Created " ++ scriptFile ++ " and " ++ dataFile
-    _ ->
-      putStrLn $
-      "Usage:\n\t" ++ progName ++ " <filename> <interface> <ssid> <passphrase>"
+
+    Nothing -> print
+      "pass the '--help' flag to hifi to see which arguments are required"
diff --git a/hifi.cabal b/hifi.cabal
--- a/hifi.cabal
+++ b/hifi.cabal
@@ -1,5 +1,5 @@
 name:                hifi
-version:             0.1.3.1
+version:             0.1.4.0
 synopsis:            WiFi connection script generator
 description:         A CLI tool generating scripts for connecting to WiFi, circumventing big WiFi management tools.
 homepage:            https://gitlab.com/gonz/hifi
@@ -34,6 +34,7 @@
   ghc-options:         -threaded -rtsopts -with-rtsopts=-N
   build-depends:       base
                      , hifi
+                     , cmdargs >= 0.10.20 && < 0.11
   default-language:    Haskell2010
 
 test-suite hifi-test
diff --git a/src/Config.hs b/src/Config.hs
--- a/src/Config.hs
+++ b/src/Config.hs
@@ -9,7 +9,8 @@
   ( templateDirectory
   , dataDirectory
   , scriptDirectory
-  ) where
+  )
+where
 
 import           Paths_hifi
 import           System.Directory
diff --git a/src/Templating.hs b/src/Templating.hs
--- a/src/Templating.hs
+++ b/src/Templating.hs
@@ -4,16 +4,21 @@
 -- compilation and substitution.
 module Templating
   ( createFiles
-  ) where
+  , Interface
+  , SSID
+  , Passphrase
+  )
+where
 
 import qualified Config
-import qualified Data.Text.IO       as TextIO
-import           System.FilePath    ((</>))
-import qualified System.IO          as IO
+import qualified Data.Text.IO                  as TextIO
+import           System.FilePath                ( (</>) )
+import qualified System.IO                     as IO
 import           System.Posix.Files
 import           System.Process
 import           Text.Mustache
-import           Text.Parsec.Error  (ParseError)
+import           Text.Parsec.Error              ( ParseError )
+import           Control.Monad                  ( liftM2 )
 
 data ScriptSpec = ScriptSpec
   { interface    :: String
@@ -42,34 +47,35 @@
 type WPAPassphraseOutput = String
 
 createScript :: FilePath -> Interface -> FilePath -> IO FileResult
-createScript filename iface dataFile =
-  createFile filename Config.scriptDirectory scriptSpec "script.mustache"
-  where
-    scriptSpec = ScriptSpec {interface = iface, dataFilename = dataFile}
+createScript filename iface dataFile = createFile filename
+                                                  Config.scriptDirectory
+                                                  scriptSpec
+                                                  "script.mustache"
+  where scriptSpec = ScriptSpec {interface = iface, dataFilename = dataFile}
 
 runWPAPassphrase :: SSID -> Passphrase -> IO WPAPassphraseOutput
 runWPAPassphrase ssid passphrase = do
-  (_, Just hout, _, _) <-
-    createProcess wpa_passphrase_process {std_out = CreatePipe}
+  (_, Just hout, _, _) <- createProcess wpa_passphrase_process
+    { std_out = CreatePipe
+    }
   IO.hGetContents hout
-  where
-    wpa_passphrase_process = proc "wpa_passphrase" [ssid, passphrase]
+  where wpa_passphrase_process = proc "wpa_passphrase" [ssid, passphrase]
 
 createData :: FilePath -> WPAPassphraseOutput -> IO FileResult
-createData filename wpaPPoutput =
-  createFile filename Config.dataDirectory dataSpec "data.mustache"
-  where
-    dataSpec = DataSpec {wpaPassphraseOutput = wpaPPoutput}
+createData filename wpaPPoutput = createFile filename
+                                             Config.dataDirectory
+                                             dataSpec
+                                             "data.mustache"
+  where dataSpec = DataSpec {wpaPassphraseOutput = wpaPPoutput}
 
-createFile ::
-     ToMustache a => FilePath -> IO FilePath -> a -> FilePath -> IO FileResult
+createFile
+  :: ToMustache a => FilePath -> IO FilePath -> a -> FilePath -> IO FileResult
 createFile filename outputDirFunc spec templateFile = do
-  templateDir <- Config.templateDirectory
-  outputDir <- outputDirFunc
-  compiled <- automaticCompile [templateDir] templateFile
+  (templateDir, outputDir) <- liftM2 (,) Config.templateDirectory outputDirFunc
+  compiled                 <- automaticCompile [templateDir] templateFile
   let outputPath = outputDir </> filename
   case compiled of
-    Left err -> pure (Left err)
+    Left  err      -> pure (Left err)
     Right template -> do
       TextIO.writeFile outputPath $ substitute template spec
       pure (Right outputPath)
@@ -77,12 +83,12 @@
 -- | 'createFiles' creates both the script- and data-file for a 'FilePath',
 -- 'Interface', 'SSID' and 'Passphrase'. These filenames are then returned in a
 -- tuple so that they may be used to notify the user of their creation.
-createFiles ::
-     FilePath -> Interface -> SSID -> Passphrase -> IO (FilePath, FilePath)
+createFiles
+  :: FilePath -> Interface -> SSID -> Passphrase -> IO (FilePath, FilePath)
 createFiles filename iface ssid passphrase = do
-  wpaPPoutput <- runWPAPassphrase ssid passphrase
-  (Right dataFile) <- createData filename wpaPPoutput
+  wpaPPoutput        <- runWPAPassphrase ssid passphrase
+  (Right dataFile  ) <- createData filename wpaPPoutput
   (Right scriptFile) <- createScript filename iface dataFile
   setFileMode scriptFile ownerModes
-  setFileMode dataFile (unionFileModes ownerWriteMode ownerReadMode)
+  setFileMode dataFile   (unionFileModes ownerWriteMode ownerReadMode)
   pure (dataFile, scriptFile)
