diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Changelog for Calamity
 
+## 0.1.20.1
+
+* Documentation improvements.
+
 ## 0.1.20.0
 
 * Migrate do di-polysemy 0.2, runBotIO no longer handles the Log effect.
diff --git a/calamity.cabal b/calamity.cabal
--- a/calamity.cabal
+++ b/calamity.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 0c8bab4fd581f5309d85bd6e640b7f1f3f953f8862ad5b5c607caabf95e1cb3e
+-- hash: 55bf5727de4e0d34fab772f8f03176d91db899e03912214153fdfd0bf161eedc
 
 name:           calamity
-version:        0.1.20.0
+version:        0.1.20.1
 synopsis:       A library for writing discord bots in haskell
 description:    Please see the README on GitHub at <https://github.com/nitros12/calamity#readme>
 category:       Network, Web
diff --git a/src/Calamity/Cache/Eff.hs b/src/Calamity/Cache/Eff.hs
--- a/src/Calamity/Cache/Eff.hs
+++ b/src/Calamity/Cache/Eff.hs
@@ -65,7 +65,7 @@
   SetDM :: DMChannel -> CacheEff m ()
   -- | Get a 'DMChannel' from the cache
   GetDM :: Snowflake DMChannel -> CacheEff m (Maybe DMChannel)
-  -- | Get all 'DM's from the cache
+  -- | Get all 'DMChannel's from the cache
   GetDMs :: CacheEff m [DMChannel]
   -- | Delete a 'DMChannel' from the cache
   DelDM :: Snowflake DMChannel -> CacheEff m ()
diff --git a/src/Calamity/Client.hs b/src/Calamity/Client.hs
--- a/src/Calamity/Client.hs
+++ b/src/Calamity/Client.hs
@@ -40,5 +40,5 @@
 --
 -- @
 -- 'Control.Monad.void' . 'Polysemy.runFinal' . 'Polysemy.embedToFinal' . 'Calamity.Cache.InMemory.runCacheInMemory' . 'Calamity.Metrics.Noop.runMetricsNoop' $ 'runBotIO' ('Calamity.Types.Token.BotToken' token) $ do
---   'react' \@\''MessageCreateEvt' (\msg -> 'Polysemy.embed' $ 'print' msg)
+--   'react' \@\''MessageCreateEvt' $ \\msg -> 'Polysemy.embed' $ 'print' msg
 -- @
diff --git a/src/Calamity/Commands.hs b/src/Calamity/Commands.hs
--- a/src/Calamity/Commands.hs
+++ b/src/Calamity/Commands.hs
@@ -1,5 +1,5 @@
 -- | Calamity commands
--- This module only exports the DSL and core types for using commands
+-- This module exports the DSL and core types for using commands
 module Calamity.Commands
     ( module Calamity.Commands.Dsl
     , module Calamity.Commands.Error
@@ -28,13 +28,13 @@
 -- support grouping, pre-invokation checks, and automatic argument parsing by
 -- using a type level list of parameter types.
 --
--- A DSL is provided in 'Calamity.Commands.Dsl' for constructing commands
+-- A DSL is provided in "Calamity.Commands.Dsl" for constructing commands
 -- declaratively.
 --
 -- You can implement 'Parser' for your own types to allow them to be used in the
 -- parameter list of commands.
 --
--- A default help command is provided in 'Calamity.Commands.Help' which can be
+-- A default help command is provided in "Calamity.Commands.Help" which can be
 -- added just by using 'helpCommand' inside the command declaration DSL.
 --
 --
@@ -69,10 +69,10 @@
 -- @
 -- 'addCommands' $ do
 --   'helpCommand'
---   'command' \@\'['Calamity.Types.Model.User.User'] "utest" $ \ctx u \-\> do
+--   'command' \@\'['Calamity.Types.Model.User.User'] "utest" $ \\ctx u \-\> do
 --     'Control.Monad.void' $ 'Calamity.Types.Tellable.tell' ctx $ "got user: " '<>' 'TextShow.showtl' u
 --   'group' "admin" $ do
---     'command' \@'[] "bye" $ \ctx -> do
+--     'command' \@'[] "bye" $ \\ctx -> do
 --       'Control.Monad.void' $ 'Calamity.Types.Tellable.tell' ctx "bye!"
 --       'Calamity.Client.stopBot'
 -- @
diff --git a/src/Calamity/Commands/CommandUtils.hs b/src/Calamity/Commands/CommandUtils.hs
--- a/src/Calamity/Commands/CommandUtils.hs
+++ b/src/Calamity/Commands/CommandUtils.hs
@@ -198,8 +198,15 @@
   ListToTup '[] = ()
   ListToTup (x ': xs) = (x, ListToTup xs)
 
--- | Transform a type level list of types implementing the parser typeclass into
+-- | Transform a type level list of types implementing the 'Parser' typeclass into
 -- the type a command callback matching those parameters should be.
+--
+-- As an example:
+--
+-- @
+-- 'CommandForParsers' [ 'L.Text', 'Calamity.Types.Snowflake' 'Calamity.Types.User', 'Calamity.Commands.Parser.Named' "something" 'L.Text' ] r ~
+--   ('L.Text' -> 'Calamity.Types.Snowflake' 'Calamity.Types.User' -> 'L.Text' -> 'P.Sem' r ('P.Fail' ': r) ())
+-- @
 type family CommandForParsers (ps :: [Type]) r where
   CommandForParsers '[] r = P.Sem (P.Fail ': r) ()
   CommandForParsers (x ': xs) r = ParserResult x -> CommandForParsers xs r
diff --git a/src/Calamity/Commands/Dsl.hs b/src/Calamity/Commands/Dsl.hs
--- a/src/Calamity/Commands/Dsl.hs
+++ b/src/Calamity/Commands/Dsl.hs
@@ -2,7 +2,9 @@
 
 -- | A DSL for generating commands and groups
 module Calamity.Commands.Dsl
-    ( command
+    ( -- * Commands DSL
+      -- $dslTutorial
+      command
     , command'
     , commandA
     , commandA'
@@ -40,6 +42,49 @@
 import qualified Polysemy.Reader               as P
 import Data.List.NonEmpty (NonEmpty(..))
 
+-- $dslTutorial
+--
+-- This module provides a way of constructing bot commands in a declarative way.
+--
+-- The main component of this is the 'command' function, which takes a
+-- type-level list of command parameters, the name, and the callback and
+-- produces a command. There are also the alternatives 'command'', 'commandA'
+-- and 'commandA'', for when you want to handle parsing of the input yourself,
+-- and/or want aliases of the command.
+--
+-- The functions: 'hide', 'help', 'requires', and 'group' can be used to change
+-- attributes of any commands declared inside the monadic action passed to them,
+-- for example:
+--
+-- @
+-- 'hide' '$' do
+--   'command' \@'[] "test" \ctx -> 'pure' ()
+-- @
+--
+-- In the above block, any command declared inside 'hide' will have it's
+-- \'hidden\' flag set and will not be shown by the default help command:
+-- 'Calamity.Commands.Help.helpCommand'
+--
+-- The 'Calamity.Commands.Help.helpCommand' function can be used to create a
+-- help command for the commands DSL action it is used in, read it's doc page
+-- for more information on how it functions.
+--
+-- The 'Calamity.Commands.Utils.addCommands' function creates the command
+-- handler for the commands registered in the passed action, it is what reads a
+-- message to determine what command was invoked. It should be used to register the
+-- commands with the bot by using it inside the setup action, for example:
+--
+-- @
+-- 'Calamity.Client.runBotIO' ('Calamity.BotToken' token)
+--   $ 'Calamity.Commands.Utils.addCommands' $ do
+--     'Calamity.Commands.Help.helpCommand'
+--     'Calamity.Commands.Dsl.command' \@'[] "test" \ctx ->
+--       'Control.Monad.void' $ 'Calamity.Types.Tellable.tell' \@'L.Text' ctx "hi"
+-- @
+--
+-- The above block will create a command with no parameters named \'test\',
+-- along with a help command.
+
 type DSLState r =
   ( LocalWriter (LH.HashMap S.Text (Command, AliasType))
       ': LocalWriter (LH.HashMap S.Text (Group, AliasType))
@@ -110,6 +155,11 @@
 -- The parent group, visibility, checks, and command help are drawn from the
 -- reader context.
 --
+-- Command parameters are parsed by first invoking
+-- 'Calamity.Commands.Parser.parse' for the first
+-- 'Calamity.Commands.Parser.Parser', then running the next parser on the
+-- remaining input, and so on.
+--
 -- ==== Examples
 --
 -- Building a command that bans a user by id.
@@ -117,7 +167,7 @@
 -- @
 -- 'command' \@\'['Calamity.Commands.Parser.Named' "user" ('Calamity.Types.Snowflake' 'Calamity.Types.Model.User'),
 --                'Calamity.Commands.Parser.Named' "reason" ('Calamity.Commands.Parser.KleeneStarConcat' 'S.Text')]
---    "ban" $ \ctx uid r -> case (ctx 'Control.Lens.^.' #guild) of
+--    "ban" $ \\ctx uid r -> case (ctx 'Control.Lens.^.' #guild) of
 --      'Just' guild -> do
 --        'Control.Monad.void' . 'Calamity.HTTP.invoke' . 'Calamity.HTTP.reason' r $ 'Calamity.HTTP.Guild.CreateGuildBan' guild uid
 --        'Control.Monad.void' $ 'Calamity.Types.Tellable.tell' ctx ("Banned user `" '<>' 'TextShow.showt' uid '<>' "` with reason: " '<>' r)
@@ -146,7 +196,7 @@
 -- @
 -- 'commandA' \@\'['Calamity.Commands.Parser.Named' "user" ('Calamity.Types.Snowflake' 'Calamity.Types.Model.User'),
 --                'Calamity.Commands.Parser.Named' "reason" ('Calamity.Commands.Parser.KleeneStarConcat' 'S.Text')]
---    "ban" [] $ \ctx uid r -> case (ctx 'Control.Lens.^.' #guild) of
+--    "ban" [] $ \\ctx uid r -> case (ctx 'Control.Lens.^.' #guild) of
 --      'Just' guild -> do
 --        'Control.Monad.void' . 'Calamity.HTTP.invoke' . 'Calamity.HTTP.reason' r $ 'Calamity.HTTP.Guild.CreateGuildBan' guild uid
 --        'Control.Monad.void' $ 'Calamity.Types.Tellable.tell' ctx ("Banned user `" '<>' 'TextShow.showt' uid '<>' "` with reason: " '<>' r)
diff --git a/src/Calamity/Commands/Help.hs b/src/Calamity/Commands/Help.hs
--- a/src/Calamity/Commands/Help.hs
+++ b/src/Calamity/Commands/Help.hs
@@ -105,7 +105,7 @@
     Just (Group' grp@Group { names } remainingPath) ->
       let failedMsg = if null remainingPath
             then ""
-            else "No command or group with the path: `" <> L.fromStrict (S.unwords path) <> "` exists for the group: `" <> L.fromStrict (NE.head names) <> "`\n"
+            else "No command or group with the path: `" <> L.fromStrict (S.unwords remainingPath) <> "` exists for the group: `" <> L.fromStrict (NE.head names) <> "`\n"
       in void $ tell @L.Text ctx $ failedMsg <> "Help for group `" <> L.fromStrict (NE.head names) <> "`: \n" <> helpForGroup ctx grp
     Nothing -> let failedMsg = if null path
                      then ""
@@ -121,6 +121,49 @@
 
 -- | Create and register the default help command for all the commands
 -- registered in the commands DSL this is used in.
+--
+-- The registered command will have the name \'help\', called with no parameters
+-- it will print the top-level groups and commands, for example:
+--
+-- @
+-- The following groups exist:
+-- - reanimate
+-- - prefix[prefixes]
+-- - alias[aliases]
+-- - remind[reminder|reminders]
+--
+-- The following commands exist:
+-- - help :[Text]
+-- @
+--
+-- Both commands and groups are listed in the form: @\<name\>[\<alias 0\>|\<alias 1\>]@,
+-- commands also have their parameter list shown.
+--
+-- If a path to a group is passed, the help, aliases, and pre-invokation checks
+-- will be listed, along with the subgroups and commands, For example:
+--
+-- @
+-- Help for group remind:
+-- Group: remind
+-- Aliases: reminder reminders
+-- Commands related to making reminders
+--
+-- The following child commands exist:
+-- - list
+-- - remove reminder_id:Text
+-- - add :KleenePlusConcat Text
+-- @
+--
+-- If a command path is passed, the usage, checks and help for the command are
+-- shown, for example:
+--
+-- @
+-- Help for command add:
+-- Usage: c!prefix add prefix:Text
+-- Checks: prefixLimit guildOnly
+--
+-- Add a new prefix
+-- @
 helpCommand :: BotC r => P.Sem (DSLState r) Command
 helpCommand = do
   handler <- P.ask @CommandHandler
diff --git a/src/Calamity/Commands/ParsePrefix.hs b/src/Calamity/Commands/ParsePrefix.hs
--- a/src/Calamity/Commands/ParsePrefix.hs
+++ b/src/Calamity/Commands/ParsePrefix.hs
@@ -16,6 +16,7 @@
 
 -- | An effect for parsing the prefix of a command.
 data ParsePrefix m a where
+  -- | Parse a prefix in a message, returning a tuple of @(prefix, remaining message)@
   ParsePrefix :: Message -> ParsePrefix m (Maybe (L.Text, L.Text))
 
 P.makeSem ''ParsePrefix
diff --git a/src/Calamity/Commands/Parser.hs b/src/Calamity/Commands/Parser.hs
--- a/src/Calamity/Commands/Parser.hs
+++ b/src/Calamity/Commands/Parser.hs
@@ -4,6 +4,7 @@
     , Named
     , KleeneStarConcat
     , KleenePlusConcat
+    , ParserEffs
     , runCommandParser ) where
 
 import           Calamity.Cache.Eff
@@ -150,7 +151,7 @@
 
 -- | A parser that consumes zero or more of @a@ then concatenates them together.
 --
--- @'KleeneStarConcat' 'L.Text'@ Is therefore consumes all remaining input.
+-- @'KleeneStarConcat' 'L.Text'@ therefore consumes all remaining input.
 data KleeneStarConcat (a :: Type)
 
 instance (Monoid (ParserResult a), Parser a r) => Parser (KleeneStarConcat a) r where
@@ -172,7 +173,7 @@
 
 -- | A parser that consumes one or more of @a@ then concatenates them together.
 --
--- @'KleenePlusConcat' 'L.Text'@ Is therefore consumes all remaining input.
+-- @'KleenePlusConcat' 'L.Text'@ therefore consumes all remaining input.
 data KleenePlusConcat (a :: Type)
 
 instance (Semigroup (ParserResult a), Parser a r) => Parser (KleenePlusConcat a) r where
diff --git a/src/Calamity/Commands/Utils.hs b/src/Calamity/Commands/Utils.hs
--- a/src/Calamity/Commands/Utils.hs
+++ b/src/Calamity/Commands/Utils.hs
@@ -54,8 +54,20 @@
 -- | Construct commands and groups from a command DSL, then registers an event
 -- handler on the bot that manages running those commands.
 --
+--
 -- Returns an action to remove the event handler, and the 'CommandHandler' that was constructed.
 --
+-- ==== Command Resolution
+--
+-- To determine if a command was invoked, and if so which command was invoked, the following happens:
+--
+--     1. 'parsePrefix' is invoked, if no prefix is found: stop here.
+--
+--     2. The input is read a word at a time until a matching command is found,
+--        fire the \"command-not-found\" event if not.
+--
+--     3. A 'Calamity.Commands.Context.Context' is built, and the command invoked.
+--
 -- ==== Custom Events
 --
 -- This will fire the following events:
@@ -130,7 +142,7 @@
           runLocalWriter @(LH.HashMap S.Text (Command, AliasType))
         defaultHelp = (const "This command or group has no help.")
 
-
+-- TODO: turn this into an effect
 -- | Attempt to build the context for a command
 buildContext :: BotC r => Message -> L.Text -> Command -> L.Text -> P.Sem r (Maybe Context)
 buildContext msg prefix command unparsed = (rightToMaybe <$>) . P.runFail $ do
diff --git a/src/Calamity/Utils/Permissions.hs b/src/Calamity/Utils/Permissions.hs
--- a/src/Calamity/Utils/Permissions.hs
+++ b/src/Calamity/Utils/Permissions.hs
@@ -23,7 +23,7 @@
 import qualified Polysemy                               as P
 import Data.Foldable (Foldable(foldl'))
 
--- | Calculate a 'Member''s 'Permissions' in a 'Guild'
+-- | Calculate a 'Member'\'s 'Permissions' in a 'Guild'
 basePermissions :: Guild -> Member -> Permissions
 basePermissions g m
   | (g ^. #ownerID == getID m) = allFlags
@@ -57,14 +57,14 @@
 
 -- | Things that 'Member's have 'Permissions' in
 class PermissionsIn a where
-  -- | Calculate a 'Member''s 'Permissions' in something
+  -- | Calculate a 'Member'\'s 'Permissions' in something
   permissionsIn :: a -> Member -> Permissions
 
--- | A 'Member''s 'Permissions' in a channel are their roles and overwrites
+-- | A 'Member'\'s 'Permissions' in a channel are their roles and overwrites
 instance PermissionsIn (Guild, GuildChannel) where
   permissionsIn (g, c) m = applyOverwrites c m $ basePermissions g m
 
--- | A 'Member''s 'Permissions' in a guild are just their roles
+-- | A 'Member'\'s 'Permissions' in a guild are just their roles
 instance PermissionsIn Guild where
   permissionsIn g m = basePermissions g m
 
@@ -89,7 +89,7 @@
       (Just m, Just g') -> pure $ permissionsIn (g', c) m
       _cantFind         -> pure noFlags
 
--- | A 'Member''s 'Permissions' in a guild are just their roles
+-- | A 'Member'\'s 'Permissions' in a guild are just their roles
 instance PermissionsIn' Guild where
   permissionsIn' g (getID @User -> uid) = do
     m <- upgrade (getID @Guild g, coerceSnowflake @_ @Member uid)
@@ -97,7 +97,7 @@
       Just m' -> pure $ permissionsIn g m'
       Nothing -> pure noFlags
 
--- | A 'Member''s 'Permissions' in a channel are their roles and overwrites
+-- | A 'Member'\'s 'Permissions' in a channel are their roles and overwrites
 --
 -- This will fetch the guild and channel from the cache or http as needed
 instance PermissionsIn' (Snowflake GuildChannel) where
@@ -107,7 +107,7 @@
       Just c'  -> permissionsIn' c' u
       Nothing  -> pure noFlags
 
--- | A 'Member''s 'Permissions' in a guild are just their roles
+-- | A 'Member'\'s 'Permissions' in a guild are just their roles
 --
 -- This will fetch the guild from the cache or http as needed
 instance PermissionsIn' (Snowflake Guild) where
