diff --git a/eve.cabal b/eve.cabal
--- a/eve.cabal
+++ b/eve.cabal
@@ -1,5 +1,5 @@
 name:                eve
-version:             0.1.1
+version:             0.1.2
 synopsis: An extensible event framework
 description: An extensible event-driven application framework in haskell for building embarassingly modular software.
 homepage:            https://github.com/ChrisPenner/eve#readme
diff --git a/src/Eve.hs b/src/Eve.hs
--- a/src/Eve.hs
+++ b/src/Eve.hs
@@ -1,34 +1,36 @@
 module Eve
-  ( eve
-  , eveT
+  (
+  -- * Running your App
+  eve
 
+  -- * Working with Actions
   , App
   , Action
   , AppT
   , ActionT
-  , liftAction
-  , AppState
+  , liftApp
+  , runAction
+  , exit
 
-  -- * Events
+  -- * Dispatching Events
   , dispatchEvent
   , dispatchEvent_
   , dispatchEventAsync
   , dispatchActionAsync
 
+  -- * Event Listeners
   , addListener
   , addListener_
   , removeListener
+  , Listener
+  , ListenerId
 
-  -- * Working with Async Events/Actions
+  -- * Asynchronous Helpers
   , asyncActionProvider
   , asyncEventProvider
   , Dispatcher
 
-  , Listener
-  , ListenerId
-
   -- * Built-in Event Listeners
-  , onInit
   , afterInit
   , beforeEvent
   , beforeEvent_
@@ -79,9 +81,7 @@
   , States
   , HasEvents
   , stateLens
-
-  , runAction
-  , exit
+  , AppState
   ) where
 
 import Eve.Internal.Run
diff --git a/src/Eve/Internal/Actions.hs b/src/Eve/Internal/Actions.hs
--- a/src/Eve/Internal/Actions.hs
+++ b/src/Eve/Internal/Actions.hs
@@ -6,101 +6,76 @@
 {-# language TypeFamilies #-}
 {-# language UndecidableInstances #-}
 {-# language ScopedTypeVariables #-}
-{-# language TemplateHaskell #-}
 module Eve.Internal.Actions
-  ( ActionF(..)
+  ( AppF(..)
   , ActionT(..)
   , AppT
+
   , runApp
   , evalApp
   , execApp
 
-  , liftAction
+  , liftApp
   , runAction
-
-  , exit
-  , isExiting
-  , asyncQueue
-  , Exiting(..)
   ) where
 
-import Eve.Internal.States
-
 import Control.Monad.State
 import Control.Monad.Trans.Free
 import Control.Lens
-import Data.Default
-import Data.Typeable
 
-import Pipes.Concurrent
-
+-- | An 'App' has the same base and zoomed values.
 type AppT s m a = ActionT s s m a
 
-newtype ActionF base m next =
-  LiftAction (StateT base m next)
+-- | A Free Functor for storing lifted App actions.
+newtype AppF base m next =
+  LiftApp (StateT base m next)
   deriving (Functor, Applicative)
 
+-- | Base Action type. Allows paramaterization over application state, zoomed state
+-- and underlying monad.
 newtype ActionT base zoomed m a = ActionT
-  { getAction :: FreeT (ActionF base m) (StateT zoomed m) a
+  { getAction :: FreeT (AppF base m) (StateT zoomed m) a
   } deriving (Functor, Applicative, Monad, MonadIO, MonadState zoomed)
 
-instance Monad n => MonadFree (ActionF base n) (ActionT base zoomed n) where
-  wrap (LiftAction act) = join . ActionT . liftF . LiftAction $ act
+instance Monad n => MonadFree (AppF base n) (ActionT base zoomed n) where
+  wrap (LiftApp act) = join . ActionT . liftF . LiftApp $ act
 
 instance MonadTrans (ActionT base zoomed) where
   lift = ActionT . lift . lift
 
-unLift :: Monad m => FreeT (ActionF base m) (StateT base m) a -> StateT base m a
+-- | Helper method to run FreeTs.
+unLift :: Monad m => FreeT (AppF base m) (StateT base m) a -> StateT base m a
 unLift m = do
   step <- runFreeT m
   case step of
     Pure a -> return a
-    Free (LiftAction next) -> next >>= unLift
-
-liftAction :: Monad m => AppT base m a -> ActionT base zoomed m a
-liftAction = liftF .  LiftAction . unLift . getAction
-
-runApp :: Monad m => base -> AppT base m a -> m (a, base)
-runApp baseState = flip runStateT baseState . unLift . getAction
-
-evalApp :: Monad m => base -> AppT base m a -> m a
-evalApp baseState = fmap fst . runApp baseState
-
-execApp :: Monad m => base -> AppT base m a -> m base
-execApp baseState = fmap snd . runApp baseState
+    Free (LiftApp next) -> next >>= unLift
 
-type instance Zoomed (ActionT base zoomed m) = Zoomed (FreeT (ActionF base m) (StateT zoomed m))
+-- | Allows 'zoom'ing 'Action's.
+type instance Zoomed (ActionT base zoomed m) = Zoomed (FreeT (AppF base m) (StateT zoomed m))
 instance Monad m => Zoom (ActionT base s m) (ActionT base t m) s t where
   zoom l (ActionT action) = ActionT $ zoom l action
 
+-- | Given a 'Lens' or 'Traversal' or something similar from "Control.Lens"
+-- which focuses the state (t) of an 'Action' from a base state (s),
+-- this will convert @Action t a -> Action s a@.
+--
+-- Given a lens @HasStates s => Lens' s t@ it can also convert @Action t a -> App a@
 runAction :: Zoom m n s t => LensLike' (Zoomed m c) t s -> m c -> n c
 runAction = zoom
 
-newtype Exiting =
-  Exiting Bool
-  deriving (Show, Eq)
-
-instance Default Exiting where
-  def = Exiting False
-
-exit :: (Monad m, HasStates s) => ActionT s zoomed m ()
-exit = liftAction $ stateLens .= Exiting True
-
-isExiting :: (Monad m, HasStates s) => ActionT s zoomed m Bool
-isExiting = liftAction $ do
-  Exiting b <- use stateLens
-  return b
-
-newtype AsyncQueue base m = AsyncQueue
-  { _asyncQueue' :: Maybe (Output (AppT base m ()))
-  } deriving Typeable
-makeLenses ''AsyncQueue
+-- | Allows you to run an 'App' or 'AppM' inside of an 'Action' or 'ActionM'
+liftApp :: Monad m => AppT base m a -> ActionT base zoomed m a
+liftApp = liftF .  LiftApp . unLift . getAction
 
-instance Show (AsyncQueue base m) where
-  show _ = "Async Queue"
+-- | Runs an application and returns the value and state.
+runApp :: Monad m => base -> AppT base m a -> m (a, base)
+runApp baseState = flip runStateT baseState . unLift . getAction
 
-instance Default (AsyncQueue base m) where
-  def = AsyncQueue Nothing
+-- | Runs an application and returns the resulting value.
+evalApp :: Monad m => base -> AppT base m a -> m a
+evalApp baseState = fmap fst . runApp baseState
 
-asyncQueue :: (HasStates s, Typeable m, Typeable base) => Lens' s (Maybe (Output (AppT base m ())))
-asyncQueue = stateLens.asyncQueue'
+-- | Runs an application and returns the resulting state.
+execApp :: Monad m => base -> AppT base m a -> m base
+execApp baseState = fmap snd . runApp baseState
diff --git a/src/Eve/Internal/AppState.hs b/src/Eve/Internal/AppState.hs
--- a/src/Eve/Internal/AppState.hs
+++ b/src/Eve/Internal/AppState.hs
@@ -3,13 +3,23 @@
   ( AppState(..)
   , App
   , Action
+  , ActionM
+  , AppM
+
+  , exit
+  , isExiting
+
+  , asyncQueue
   ) where
 
 import Eve.Internal.Actions
 import Eve.Internal.States
 import Control.Lens
 import Data.Default
+import Data.Typeable
+import Pipes.Concurrent
 
+-- | A basic default state which underlies 'App' Contains only a map of 'States'.
 data AppState = AppState
   { _baseStates :: States
   }
@@ -23,5 +33,54 @@
 
 instance HasEvents AppState where
 
+newtype AsyncQueue base m = AsyncQueue
+  { _asyncQueue' :: Maybe (Output (AppT base m ()))
+  } deriving Typeable
+makeLenses ''AsyncQueue
+
+instance Show (AsyncQueue base m) where
+  show _ = "Async Queue"
+
+instance Default (AsyncQueue base m) where
+  def = AsyncQueue Nothing
+
+-- | Accesses a queue for dispatching async actions.
+asyncQueue :: (HasStates s, Typeable m, Typeable base) => Lens' s (Maybe (Output (AppT base m ())))
+asyncQueue = stateLens.asyncQueue'
+
+newtype Exiting =
+  Exiting Bool
+  deriving (Show, Eq)
+
+instance Default Exiting where
+  def = Exiting False
+
+-- | Tells the application to quit. This triggers 'onExit' listeners
+-- following the current event loop.
+exit :: (Monad m, HasStates s) => ActionT s zoomed m ()
+exit = liftApp $ stateLens .= Exiting True
+
+-- | Checks whether we're in the process of exiting.
+isExiting :: (Monad m, HasStates s) => ActionT s zoomed m Bool
+isExiting = liftApp $ do
+  Exiting b <- use stateLens
+  return b
+
+
+-- | An App is a base level monad which operates over your main application
+-- state. You may call 'runAction' inside an app to run 'Action's over other states.
+-- need to specify your own custom base state.
 type App a = AppT AppState IO a
-type Action s a = ActionT AppState s IO a
+
+-- | An Action is a monad over some zoomed in state, they are run inside 'App' using
+-- 'runAction'. For example an Action which operates over a String somewhere in your app state
+-- would be written as:
+--
+-- alterString :: Action String ()
+type Action state a = ActionT AppState state IO a
+
+-- | A more general version of 'App' which lets you specify the underlying monad.
+type AppM m a = AppT AppState m a
+
+-- | A more general version of 'Action' which lets you to specify the underlying monad.
+type ActionM s m a = ActionT AppState s m a
diff --git a/src/Eve/Internal/Async.hs b/src/Eve/Internal/Async.hs
--- a/src/Eve/Internal/Async.hs
+++ b/src/Eve/Internal/Async.hs
@@ -9,6 +9,7 @@
   ) where
 
 import Eve.Internal.Actions
+import Eve.Internal.AppState
 import Eve.Internal.States
 
 import Control.Monad
@@ -19,9 +20,11 @@
 import Pipes
 import Pipes.Concurrent
 
+-- | Dispatch an action which is generated by some IO. Note that state of the application may have changed
+-- between calling 'dispatchActionAsync' and running the resulting 'Action'
 dispatchActionAsync
   :: (MonadIO m, HasStates base, Typeable m, Typeable base) => IO (AppT base m ()) -> ActionT base zoomed m ()
-dispatchActionAsync asyncAction = liftAction $ do
+dispatchActionAsync asyncAction = liftApp $ do
   mQueue <- use asyncQueue
   case mQueue of
     Nothing -> return ()
@@ -29,8 +32,18 @@
       let effect = (liftIO asyncAction >>= yield) >-> toOutput queue
       liftIO . void . forkIO $ runEffect effect >> performGC
 
+-- | This allows long-running IO processes to provide 'Action's to the application asyncronously.
+--
+-- Don't let the type signature confuse you; it's much simpler than it seems.
+--
+-- Let's break it down:
+--
+-- When you call 'asyncActionProvider' you pass it a function which accepts a @dispatch@ function as an argument
+-- and then calls it with various 'Action's within the resulting 'IO'.
+--
+-- Note that this function calls forkIO internally, so there's no need to do that yourself.
 asyncActionProvider :: (MonadIO m, HasStates base, Typeable m, Typeable base) => ((AppT base m () -> IO ()) -> IO ()) -> ActionT base zoomed m ()
-asyncActionProvider provider = liftAction $ do
+asyncActionProvider provider = liftApp $ do
   mQueue <- use asyncQueue
   case mQueue of
     Nothing -> return ()
diff --git a/src/Eve/Internal/Listeners.hs b/src/Eve/Internal/Listeners.hs
--- a/src/Eve/Internal/Listeners.hs
+++ b/src/Eve/Internal/Listeners.hs
@@ -14,7 +14,6 @@
   , removeListener
   , asyncEventProvider
 
-  , onInit
   , afterInit
   , beforeEvent
   , beforeEvent_
@@ -40,36 +39,55 @@
 import Data.Maybe
 import qualified Data.Map as M
 
-
--- | Registers an action to be performed during the Initialization phase.
+-- | Registers an action to be performed directly following the Initialization phase.
 --
--- This phase occurs exactly ONCE when the app starts up.
--- Though arbitrary actions may be performed in the configuration block;
--- it's recommended to embed such actions in the onInit event listener
--- so that all event listeners are registered before any dispatches occur.
-onInit :: forall base zoomed m result. (Monad m, HasEvents zoomed, Typeable m, Typeable base) => ActionT base zoomed m result -> ActionT base zoomed m ()
-onInit action = void $ addListener (const (void action) :: Init -> ActionT base zoomed m ())
-
+-- At this point any listeners in the initialization block have run, so you may 'dispatchEvent's here.
 afterInit :: forall base zoomed m a. (Monad m, HasEvents zoomed, Typeable m, Typeable base) => ActionT base zoomed m a -> ActionT base zoomed m ()
 afterInit action = void $ addListener (const (void action) :: AfterInit -> ActionT base zoomed m ())
 
--- | Registers an action to be performed BEFORE each event phase.
+-- | Registers an action to be performed BEFORE each async event is processed phase.
 beforeEvent :: forall base zoomed m a. (Monad m, HasEvents zoomed, Typeable m, Typeable base) => ActionT base zoomed m a -> ActionT base zoomed m ListenerId
 beforeEvent action = addListener (const (void action) :: BeforeEvent -> ActionT base zoomed m ())
 
 beforeEvent_ :: (Monad m, HasEvents zoomed, Typeable m, Typeable base) => ActionT base zoomed m a -> ActionT base zoomed m ()
 beforeEvent_ = void . beforeEvent
 
--- | Registers an action to be performed BEFORE each event phase.
+-- | Registers an action to be performed AFTER each event phase.
 afterEvent :: forall base zoomed m a. (Monad m, HasEvents zoomed, Typeable m, Typeable base) => ActionT base zoomed m a -> ActionT base zoomed m ListenerId
 afterEvent action = addListener (const (void action) :: AfterEvent -> ActionT base zoomed m ())
 
 afterEvent_ :: (Monad m, HasEvents zoomed, Typeable m, Typeable base) => ActionT base zoomed m a -> ActionT base zoomed m ()
 afterEvent_ = void . afterEvent
 
+-- | Registers an action to be run before shutdown. Any asynchronous combinators used in this block will NOT be run.
 onExit :: forall base zoomed m a. (HasEvents zoomed, Typeable m, Typeable base, Monad m) => ActionT base zoomed m a -> ActionT base zoomed m ()
 onExit action = void $ addListener (const $ void action :: Exit -> ActionT base zoomed m ())
 
+-- | Given an Event of any type, this runs any listeners registered for that event type with the provided event.
+-- Events may also contain data pertaining to the event and it will be passed to the listeners.
+--
+-- You can also 'query' listeners and receive a ('Monoid'al) result.
+--
+-- > data RequestNames = GetFirstName | GetLastName
+-- > provideName1, provideName2 :: RequestNames -> App [String]
+-- > provideName1 GetFirstNames = return ["Bob"]
+-- > provideName1 GetLastNames = return ["Smith"]
+-- > provideName2 GetFirstNames = return ["Sally"]
+-- > provideName2 GetLastNames = return ["Jenkins"]
+-- >
+-- > -- Note that if we registered an action of type 'GetFirstName -> ()' it would NOT
+-- > -- be run in response to the following 'dispatchEvent', since it's type doesn't match.
+-- >
+-- > greetNames :: App [String]
+-- > greetNames = do
+-- >   addListener_ provideName1
+-- >   addListener_ provideName2
+-- >   firstNames <- dispatchEvent GetFirstName
+-- >   lastNames <- dispatchEvent GetLastName
+-- >   liftIO $ print firstNames
+-- >   -- ["Bob", "Sally"]
+-- >   liftIO $ print lastNames
+-- >   -- ["Smith", "Jenkins"]
 dispatchEvent
   :: forall result eventType m s.
      (MonadState s m
@@ -94,7 +112,13 @@
   => eventType -> m ()
 dispatchEvent_ = dispatchEvent
 
-
+-- | Registers an 'Action' or 'App' to respond to an event.
+--
+-- For a given use: @addListener myListener@, @myListener@ might have the type @MyEvent -> App a@
+-- it will register the function @myListener@ to be run in response to a @dispatchEvent (MyEvent eventInfo)@
+-- and will be provided @(MyEvent eventInfo)@ as an argument.
+--
+-- This returns a 'ListenerId' which corresponds to the registered listener for use with 'removeListener'
 addListener
   :: forall result eventType m s.
      (MonadState s m
@@ -132,6 +156,7 @@
   => (eventType -> m result) -> m ()
 addListener_ = void . addListener
 
+-- | Unregisters a listener referred to by the provided 'ListenerId'
 removeListener
   :: (MonadState s m, HasEvents s)
   => ListenerId -> m ()
@@ -144,9 +169,9 @@
     notMatch idA (Listener _ idB _) = idA /= idB
 
 -- | This function takes an IO which results in some event, it runs the IO
--- asynchronously and dispatches the event. Note that any listeners which are
--- registered for the resulting event will still be run syncronously, only the
--- code which generates the event is asynchronous.
+-- asynchronously, THEN dispatches the event. Note that only the
+-- code which generates the event is asynchronous, not any responses to the event
+-- itself.
 dispatchEventAsync
   :: (Typeable event
      ,MonadIO m
@@ -216,7 +241,7 @@
 type Dispatcher = forall event. Typeable event =>
                                 event -> IO ()
 
--- | This allows long-running IO processes to provide Events to the ActionT base zoomed m asyncronously.
+-- | This allows long-running IO processes to provide Events to the application asyncronously.
 --
 -- Don't let the type signature confuse you; it's much simpler than it seems.
 --
@@ -239,8 +264,8 @@
 -- > myTimer :: Dispatcher -> IO ()
 -- > myTimer dispatch = forever $ dispatch Timer >> threadDelay 1000000
 -- >
--- > myAction :: Action s ()
--- > myAction = onInit $ asyncEventProvider myTimer
+-- > myInit :: App ()
+-- > myInit = asyncEventProvider myTimer
 asyncEventProvider
   :: (HasEvents base, MonadIO m, Typeable m) => (Dispatcher -> IO ()) -> ActionT base zoomed m ()
 asyncEventProvider asyncEventProv = asyncActionProvider $ eventsToActions asyncEventProv
diff --git a/src/Eve/Internal/Run.hs b/src/Eve/Internal/Run.hs
--- a/src/Eve/Internal/Run.hs
+++ b/src/Eve/Internal/Run.hs
@@ -1,13 +1,13 @@
 module Eve.Internal.Run
   ( eve
-  , eveT
+  , eve_
   ) where
 
 import Eve.Internal.Actions
-import Eve.Internal.AppState
 import Eve.Internal.Listeners
 import Eve.Internal.Events
 import Eve.Internal.States()
+import Eve.Internal.AppState
 
 import Control.Monad
 import Control.Monad.State
@@ -20,19 +20,41 @@
 import Pipes.Concurrent
 import qualified Pipes.Parse as PP
 
-eve :: App () -> IO ()
-eve = void . eveT def
-
-eveT :: (MonadIO m, Typeable m, HasEvents base) => base -> AppT base m () -> m base
-eveT startState initialize = do
+-- | This runs your application. It accepts an initialization block (which
+-- is the same as any other 'App' or 'Action' block, which
+-- registers event listeners and event providers. Note that nothing in this
+-- block should use 'dispatchEvent' since it is possible that not all listeners
+-- have yet been registered. You can use the 'afterInit' trigger to dispatch
+-- any events you'd like to run at start-up.
+--
+-- It is polymorphic in the Monad it operates over, so you may use it with any 
+-- custom base monad which implements 'MonadIO'.
+--
+-- If you don't need this functionality; the easiest way to get started is to simply
+-- cally it like so:
+--
+-- > import Eve
+-- >
+-- > initialize = App ()
+-- > initialize = do
+-- >   addListener ...
+-- >   ...
+-- >
+-- > startApp :: IO ()
+-- > startApp = eve_ initialize
+eve :: (MonadIO m, Typeable m) => AppT AppState m () -> m AppState
+eve initialize = do
   (output, input) <- liftIO $ spawn unbounded
-  execApp (startState & asyncQueue .~ Just output) $ do
+  execApp (def & asyncQueue .~ Just output) $ do
     initialize
     dispatchEvent_ Init
     dispatchEvent_ AfterInit
     eventLoop $ fromInput input
     dispatchEvent_ Exit
-    get
+
+-- | 'eve' with '()' as its return value.
+eve_ :: (MonadIO m, Typeable m) => AppT AppState m () -> m ()
+eve_ = void . eve
 
 -- | This is the main event loop, it runs recursively forever until something
 -- sets the exit status. It runs the pre-event listeners, then checks if any
diff --git a/src/Eve/Internal/States.hs b/src/Eve/Internal/States.hs
--- a/src/Eve/Internal/States.hs
+++ b/src/Eve/Internal/States.hs
@@ -27,8 +27,8 @@
 type States = Map TypeRep StateWrapper
 
 -- | Represents a state which can itself store more states.
+-- 'states' is a lens which points to a given state's 'States' map.
 class HasStates s  where
--- | This lens points to a given state's 'States' map.
   states :: Lens' s States
 
 -- | A typeclass to ensure people don't dispatch events to states which shouldn't
diff --git a/src/Eve/Testing.hs b/src/Eve/Testing.hs
--- a/src/Eve/Testing.hs
+++ b/src/Eve/Testing.hs
@@ -3,7 +3,6 @@
   ) where
 
 import Eve.Internal.Actions
-import Eve.Internal.Run
 import Eve.Internal.AppState
 
 import Control.Monad.Identity
diff --git a/test/Eve/Internal/ActionsSpec.hs b/test/Eve/Internal/ActionsSpec.hs
--- a/test/Eve/Internal/ActionsSpec.hs
+++ b/test/Eve/Internal/ActionsSpec.hs
@@ -4,7 +4,7 @@
 
 import Fixtures
 import Eve
-import Eve.Internal.Actions
+import Eve.Internal.AppState
 
 import Control.Lens
 import Control.Monad.State
@@ -12,10 +12,10 @@
 appendEx  :: Monad m => ActionT AppState String m ()
 appendEx  = modify (++ "!!")
 
-liftActionTest :: Monad m => ActionT AppState String m String
-liftActionTest = do
+liftAppTest :: Monad m => ActionT AppState String m String
+liftAppTest = do
   put "new"
-  liftAction $ runAction stateLens appendEx
+  liftApp $ runAction stateLens appendEx
   get
 
 spec :: Spec
@@ -34,8 +34,8 @@
       let (traversalResult, _) = noIOTest $ runAction stateLens (put $ Just "new") >> runAction (stateLens._Just) (appendEx >> get)
        in traversalResult `shouldBe` "new!!"
 
-  describe "liftAction" $ do
+  describe "liftApp" $ do
     it "runs lifted actions to zoomed monad" $
-      let (liftActionResult, _) = noIOTest (runAction stateLens liftActionTest :: AppT AppState Identity String)
-       in liftActionResult `shouldBe` "new!!"
+      let (liftAppResult, _) = noIOTest (runAction stateLens liftAppTest :: AppT AppState Identity String)
+       in liftAppResult `shouldBe` "new!!"
 
diff --git a/test/Fixtures.hs b/test/Fixtures.hs
--- a/test/Fixtures.hs
+++ b/test/Fixtures.hs
@@ -33,4 +33,4 @@
 data CustomEvent = CustomEvent
 
 ioTest :: App () -> SpecM m AppState
-ioTest = runIO . eveT def
+ioTest = runIO . eve
