diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,84 @@
+# Scoped sessions
+
+This snaplet provides a convenient way to handle typed sessions in your snap application.
+
+It uses lenses to separate your session state into smaller parts which can then be individually managed by nested snaplets.
+The session state is therefore separated and subsnaplets have no access to the full global session state.
+
+## Session management
+
+Session management inside your application is done by a session `Snaplet`. The Snaplet is created using `initSessionSnaplet` and it expects a `Manager` as an argument.
+Usually you won't have to create this manager yourself, simply find a library function which provides you with one that suits your needs and drop it in there.
+As an example there is a in memory which you can create with the function `initMemoryManager` from `Snap.Snaplet.Session.Scoped.InMemory`. You can find more information on this particular manager in the section [The InMemory Manager](#the-inmemory-manager)
+
+### The Manager typeclass
+
+`Manager`s are responsible for persisting the session state in whichever way he sees fit. Depending on your choice of manager therefore your session can be kept in memory or a database or persistent in files on the server.
+Furthermore the manager handles the connection to the client, which in most cases will be a session cookie.
+
+Managers are parameterised by the state they can manage. It uses the TypeInType extension to define the internal state.
+
+
+For some Managers this may be any type
+
+```Haskell
+instance Manager (MyManager a) where
+    type Manages (MyManager a) = a -- any state
+```
+
+or a constrained type
+
+```Haskell
+instance Serialize a => Manager (MySerializingManager a) where
+    type Manages (MySerializingManager a) = a
+```
+
+or even a concrete type
+
+```Haskell
+instance Manager MyCountingManager where
+    type Manages MyCountingManager = Int
+```
+
+#### The InMemory Manager
+
+`Snap.Snaplet.Session.Scoped.InMemory` defines a `Manager` which stores arbitrary server side session state in the form of in-memory Haskell data. Session tracking is done using a configurable cookie and sessions are automatically expired to free memory by a concurrent worker which cleans the session state.
+
+An example of the configuration can be found in `resources/devel.cfg`. All values are optional.
+
+
+## Wiring the Application
+
+In order to give your snaplets access to the session manager you have to specify how the manager snaplet can be reached from inside your application.
+This is done by implementing a typeclass called `HasManager`.
+
+```Haskell
+data MyApp = MyApp { _sessionSnaplet :: Snaplet MyManager, ... }
+
+makeLenses ''MyApp
+
+instance HasManager MyApp where
+    type TheManager MyApp = MyManager
+    toManager = subSnaplet sessionSnaplet
+```
+
+Then, for each subsnaplet which is to have access to a part of the state you have to implement `AccessSession` to define the substate a Snaplet has access to.
+
+```Haskell
+data Session = Session
+    { _snapletA :: SnapletASession
+    , _snapletB :: SnapletBSession
+    }
+
+makeLenses SessionState
+
+instance AccessSession SnapletA where
+    type GlobalSession SnapletA = SessionState
+    type LocalSession SnapletA = SnapletASession
+    accessSession = mkAccessSessionLens snapletA
+
+instance AccessSession SnapletB where
+    type GlobalSession SnapletB = SessionState
+    type LocalSession SnapletB = SnapletBSession
+    accessSession = mkAccessSessionLens snapletB
+```
diff --git a/snaplet-scoped-session.cabal b/snaplet-scoped-session.cabal
--- a/snaplet-scoped-session.cabal
+++ b/snaplet-scoped-session.cabal
@@ -1,6 +1,6 @@
 name:                snaplet-scoped-session
-version:             0.1.0.0
-synopsis:            Initial project template from stack
+version:             0.1.1
+synopsis:            Modularised session state for Snaplets, in a Snaplet
 description:         Please see README.md
 homepage:            https://github.com/JustusAdam/snaplet-scoped-session#readme
 license:             BSD3
@@ -8,10 +8,11 @@
 author:              JustusAdam
 maintainer:          dev@justus.science
 copyright:           Copyright: (c) 2016 Justus Adam
-category:            Development
+category:            Web, Snap
 build-type:          Simple
-extra-source-files:  resources/devel.cfg
+extra-source-files:  resources/devel.cfg, README.md
 cabal-version:       >=1.10
+stability:           Experimental
 
 library
   hs-source-dirs:      src
diff --git a/src/Snap/Snaplet/Session/Scoped.hs b/src/Snap/Snaplet/Session/Scoped.hs
--- a/src/Snap/Snaplet/Session/Scoped.hs
+++ b/src/Snap/Snaplet/Session/Scoped.hs
@@ -1,3 +1,12 @@
+{-|
+Module      : $Header$
+Description : Abstract Manager class and Session Snaplet
+Copyright   : (c) Justus Adam, 2016
+License     : BSD3
+Maintainer  : dev@justus.science
+Stability   : experimental
+Portability : POSIX
+-}
 {-# LANGUAGE ConstraintKinds     #-}
 {-# LANGUAGE ExplicitForAll      #-}
 {-# LANGUAGE FlexibleContexts    #-}
@@ -25,21 +34,42 @@
 -- optionally persistent
 --
 -- It should be noted that although an implementation for 'managerCommit' and
--- 'managerLoad' is not required it is useful for efficiancy reasons.
+-- 'managerLoad' is not required it is useful for efficiency reasons.
 --
 -- The state of the manager is mutable within one request but reset for new requests.
--- Therefore managers whould use mutable or persistent data structures like 'IORef' internally.
+-- Therefore managers should use mutable or persistent data structures like 'IORef' internally.
 class Manager manager where
+    -- | Type of the session state inside the manager. In most cases this will
+    -- either be any type or a type constrained by some serialisation typeclass like
+    --
+    -- @
+    --  instance Serialize a => Manager (WritesToFileManager a) where
+    --      type Manages (WritesToFileManager a) = a
+    -- @
     type Manages manager
+    -- | Obtain the full session state for the current client.
     managerGetSession :: Handler v manager (Manages manager)
     managerGetSession = managerModifySession id
+    -- | Replace the state of the current sessio with the provided one
     managerSetSession :: Manages manager -> Handler v manager ()
     managerSetSession = managerModifySession . const >=> const (return ())
+
+    -- | Indicate to the manager that cached mutations on state should be persisted.
+    --
+    -- This method is entirely optional, however it is recommended
+    -- for managers where mutating the persistent state is expensive to
+    -- cache mutations in the manager data structure and persist them once commit
+    -- is called.
     managerCommit :: Handler v manager ()
     managerCommit = return ()
+
+    -- | Again optional. Users can use this method to indicate to the manager that
+    -- the session should be established (cookie read for instance) and the state
+    -- cached into the manager data structure.
     managerLoad :: Handler v manager ()
     managerLoad = return ()
 
+    -- | Applies a function to the (cached) session state
     managerModifySession :: (Manages manager -> Manages manager) -> Handler v manager (Manages manager)
     managerModifySession f = managerGetSession >>= \sess -> managerSetSession (f sess) >> return sess
 
@@ -48,25 +78,40 @@
 
 -- | Class providing access to a Snaplet managing session state
 class Manager (TheManager a) => HasManager a where
+    -- | Type of the manager, since this is defined in terms of the 'Manager' typeclass
     type TheManager a
+    -- | Like 'HasHeist', a lens to get to the manager snaplet.
     toManager :: SnapletLens (Snaplet a) (TheManager a)
 
 
-type CanAccessSubsession a b = (HasManager a, AccessSession (Manages (TheManager a)) b)
+-- | This is provided for convenience. Snaplets which use part of the state can
+-- use this shorthand in the type signature.
+--
+--      * 'base' is the (internal) type of your root snaplet
+--      * 'snaplet' is the (internal) type of the snaplet that wants to access the session
+--      * 't' is the type the (local) session data
+--
+-- If, for instance, our Snaplet was called 'Files' and it needed a HashSet as state
+-- and the global Snaplet type was unknown you could write the following:
+--
+-- @
+--  initFiles :: (CanAccessSubsession b Files HashSet) => SnapletInit b Files
+-- @
+type CanAccessSubsession base snaplet t = (HasManager base, AccessSession (Manages (TheManager base)) snaplet, LocalSession snaplet ~ t)
 
 
--- | Type magic
-type AccessSessionLens t a b = t -> Lens' a b
+-- | This is just type hacking to line up lenses. Use 'mkAccessSessionLens'
+-- to turn a regular lens into this type.
+newtype AccessSessionLens t a b = ASLens { getASLens :: t -> Lens' a b }
 
 
--- | You should use this function to create a 'AccessSessionLens'. It ignores
--- the 't' argument. The 't' ergument is only used to line up types.
+-- | Use this function to create an 'AccessSessionLens'. 't' is only used to line up types.
 mkAccessSessionLens :: Lens' a b -> AccessSessionLens t a b
-mkAccessSessionLens = const
+mkAccessSessionLens = ASLens . const
 
 
--- | A reference to a LocalSession session state from the GlobalSession session state
--- You have to implement this class for your subsnaplet to get access to a part of the GlobalSession session state.
+-- | A reference to a LocalSession session state from the global session state ('base').
+-- You have to implement this class for your subsnaplet ('t') to get access to a part of the global session state.
 class AccessSession base t where
     type LocalSession t
     accessSession :: AccessSessionLens t base (LocalSession t)
@@ -83,7 +128,6 @@
 
 
 -- | Tells the session state manager to load the session.
--- Users should not have to call this function
 loadSession :: forall s v. HasManager s => Handler s v ()
 loadSession = withTop' (toManager :: SnapletLens (Snaplet s) (TheManager s)) managerLoad
 
@@ -98,7 +142,7 @@
 getSession :: forall s t. (HasManager s, AccessSession (Manages (TheManager s)) t) => Handler s t (LocalSession t)
 getSession = do
     fs <- getFullSession
-    return $ fs^.accessSession (error "Do not evaluate!" :: t)
+    return $ fs^.getASLens accessSession (error "Do not evaluate!" :: t)
 
 
 modifyFullSession :: forall s v. HasManager s => (Manages (TheManager s) -> Manages (TheManager s)) -> Handler s v (Manages (TheManager s))
@@ -107,7 +151,7 @@
 
 -- | Set the LocalSession part of the session state to a new value
 setSession :: forall s t. (HasManager s, AccessSession (Manages (TheManager s)) t) => LocalSession t -> Handler s t ()
-setSession inner = void $ modifyFullSession (accessSession (error "Do not evaluate!" :: t) .~ inner)
+setSession inner = void $ modifyFullSession (getASLens accessSession (error "Do not evaluate!" :: t) .~ inner)
 
 
 -- | Modify the LocalSession session state with a function, returns the altered LocalSession state
@@ -117,4 +161,4 @@
 --      getSession = modifySession id
 -- @
 modifySession :: forall s t. (HasManager s, AccessSession (Manages (TheManager s)) t) => (LocalSession t -> LocalSession t) -> Handler s t (Manages (TheManager s))
-modifySession f = modifyFullSession (accessSession (error "Do not evaluate!" :: t) %~ f)
+modifySession f = modifyFullSession (getASLens accessSession (error "Do not evaluate!" :: t) %~ f)
diff --git a/src/Snap/Snaplet/Session/Scoped/InMemory.hs b/src/Snap/Snaplet/Session/Scoped/InMemory.hs
--- a/src/Snap/Snaplet/Session/Scoped/InMemory.hs
+++ b/src/Snap/Snaplet/Session/Scoped/InMemory.hs
@@ -1,3 +1,12 @@
+{-|
+Module      : $Header$
+Description : Concrete in-memory session state manager
+Copyright   : (c) Justus Adam, 2016
+License     : BSD3
+Maintainer  : dev@justus.science
+Stability   : experimental
+Portability : POSIX
+-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE TemplateHaskell  #-}
 {-# LANGUAGE TypeFamilies     #-}
