diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,3 @@
+## 0.0.4
+
+* Support `--help` on subcommands
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,37 @@
+optparse-simple
+=====
+
+Simple interface to optparse-applicative
+
+## Usage
+
+Typical usage with no commands:
+
+``` haskell
+do (opts,()) <-
+     simpleOptions "ver"
+                   "header"
+                   "desc"
+                   (flag () () (long "some-flag"))
+                   empty
+   doThings opts
+```
+
+Typical usage with commands:
+
+``` haskell
+do (opts,runCmd) <-
+     simpleOptions "ver"
+                   "header"
+                   "desc"
+                   (pure ()) $
+     do addCommand "delete"
+                   "Delete the thing"
+                   (const deleteTheThing)
+                   (pure ())
+        addCommand "create"
+                   "Create a thing"
+                   createAThing
+                   (strOption (long "hello"))
+   runCmd
+```
diff --git a/optparse-simple.cabal b/optparse-simple.cabal
--- a/optparse-simple.cabal
+++ b/optparse-simple.cabal
@@ -1,5 +1,5 @@
 name:                optparse-simple
-version:             0.0.3
+version:             0.0.4
 synopsis:            Simple interface to optparse-applicative
 description:         Simple interface to optparse-applicative
 license:             BSD3
@@ -10,10 +10,11 @@
 category:            Options
 build-type:          Simple
 cabal-version:       >=1.8
+extra-source-files:  README.md ChangeLog.md
 
 library
   hs-source-dirs:    src/
-  ghc-options:       -Wall -O2
+  ghc-options:       -Wall
   exposed-modules:   Options.Applicative.Simple
   build-depends:     base >= 4 && <5
                    , template-haskell
@@ -21,3 +22,18 @@
                    , optparse-applicative
                    , gitrev
                    , either
+
+test-suite test
+  type:              exitcode-stdio-1.0
+  main-is:           Main.hs
+  build-depends:
+                     base -any
+                   , optparse-simple
+                   , directory -any
+                   , bytestring -any
+  hs-source-dirs:    test
+  ghc-options:       -Wall
+
+source-repository head
+  type:              git
+  location:          https://github.com/fpco/optparse-simple
diff --git a/src/Options/Applicative/Simple.hs b/src/Options/Applicative/Simple.hs
--- a/src/Options/Applicative/Simple.hs
+++ b/src/Options/Applicative/Simple.hs
@@ -101,7 +101,7 @@
            -> EitherT b (Writer (Mod CommandFields b)) ()
 addCommand cmd title constr inner =
   lift (tell (command cmd
-                      (info (constr <$> inner)
+                      (info (constr <$> (helper <*> inner))
                             (progDesc title))))
 
 -- | Add a command that takes sub-commands to the options dispatcher.
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,142 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+import Options.Applicative.Simple hiding(action)
+import GHC.IO.Handle
+import System.IO
+import System.Environment
+import Control.Exception
+import Control.Monad
+import System.Directory
+import System.Exit
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as BS
+import Data.Monoid ((<>))
+
+
+shouldBe :: (Show a, Eq a) => a -> a -> IO ()
+shouldBe actual expected
+  | expected == actual = return ()
+  | otherwise = do
+    putStrLn $ "expected: " ++ show expected
+    putStrLn $ "actual  : " ++ show actual
+    exitFailure
+
+catchReturn :: Exception e => IO e -> IO e
+catchReturn io = io `catch` return
+
+catchExitCode :: IO () -> IO ExitCode
+catchExitCode action = catchReturn $ do
+  action
+  return ExitSuccess
+
+data FakeHandles = FakeHandles
+  { fakeIn  :: Handle
+  , fakeOut :: Handle
+  , fakeErr :: Handle
+  , realIn  :: Handle
+  , realOut :: Handle
+  , realErr :: Handle
+  }
+
+openFile' :: FilePath -> IO Handle
+openFile' path = do
+  removeIfExists path
+  openFile path ReadWriteMode
+
+removeIfExists :: FilePath -> IO ()
+removeIfExists path = do
+  exists <- doesFileExist path
+  when exists $ do
+    removeFile path
+
+stdinFile :: FilePath
+stdinFile = ".tmp.stdin"
+
+stdoutFile :: FilePath
+stdoutFile = ".tmp.stdout"
+
+stderrFile :: FilePath
+stderrFile = ".tmp.stderr"
+
+beforeFH :: IO FakeHandles
+beforeFH = do
+  realIn <- hDuplicate stdin
+  realOut <- hDuplicate stdout
+  realErr <- hDuplicate stderr
+
+  fakeIn <- openFile stdinFile ReadWriteMode
+  fakeOut <- openFile' stdoutFile
+  fakeErr <- openFile' stderrFile
+
+  hDuplicateTo fakeIn stdin
+  hDuplicateTo fakeOut stdout
+  hDuplicateTo fakeErr stderr
+
+  return FakeHandles{..}
+
+afterFH :: FakeHandles -> IO ()
+afterFH FakeHandles{..} = do
+  hDuplicateTo realIn stdin
+  hDuplicateTo realOut stdout
+  hDuplicateTo realErr stderr
+
+  hClose fakeIn
+  hClose fakeOut
+  hClose fakeErr
+
+withFakeHandles :: IO a -> IO a
+withFakeHandles = bracket beforeFH afterFH . const
+
+withStdIn :: ByteString -> IO ()
+  -> IO (ByteString, ByteString, ExitCode)
+withStdIn inBS action = do
+  BS.writeFile stdinFile inBS
+  withFakeHandles $ do
+    _ <- catchExitCode action
+    hFlush stdout
+    hFlush stderr
+  out <- BS.readFile stdoutFile
+  err <- BS.readFile stderrFile
+
+  removeIfExists stdinFile
+  removeIfExists stdoutFile
+  removeIfExists stderrFile
+
+  return (out, err, ExitSuccess)
+
+
+main :: IO ()
+main = do
+  (out, err, exitCode) <- withStdIn ""
+    $ withArgs ["--version"]
+    $ simpleProg
+  exitCode `shouldBe` ExitSuccess
+  err `shouldBe` ""
+  out `shouldBe` "version\n"
+
+  (out', err', exitCode') <- withStdIn ""
+    $ withArgs ["--summary"]
+    $ summaryProg
+  exitCode' `shouldBe` ExitSuccess
+  err' `shouldBe` ""
+  out' `shouldBe` "A program summary\n"
+
+  return ()
+
+
+simpleProg :: IO ()
+simpleProg = do
+  ((), ()) <- simpleOptions "version" "header" "desc" (pure ()) empty
+  return ()
+
+parserWithSummary :: Parser ()
+parserWithSummary = summaryOption <*> pure () where
+  summaryOption = infoOption "A program summary"
+    $ long "summary"
+   <> help "Show program summary"
+
+summaryProg :: IO ()
+summaryProg = do
+  ((), ()) <- simpleOptions "version" "header" "desc" parserWithSummary empty
+  return ()
