diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,8 @@
+0.4.1
+
+* Add `System.Directory`
+* Other minor improvements
+
 0.4.0
 
 * Rewrite of filepather
diff --git a/filepather.cabal b/filepather.cabal
--- a/filepather.cabal
+++ b/filepather.cabal
@@ -1,5 +1,5 @@
 name:                 filepather
-version:              0.4.0
+version:              0.4.1
 synopsis:             Functions on System.FilePath
 description:
   Functions over @System.FilePath@ including a find function for recursing down directories.
@@ -23,6 +23,8 @@
 library
   exposed-modules:
                       System.FilePath.FilePather
+                      System.FilePath.FilePather.Compose
+                      System.FilePath.FilePather.Directory
                       System.FilePath.FilePather.Find
                       System.FilePath.FilePather.ReadFilePath
                       System.FilePath.FilePather.ToFilePath
@@ -38,6 +40,7 @@
                       , mtl >= 2.2 && < 2.3
                       , semigroups >= 0.9 && < 1
                       , semigroupoids >= 5.2 && < 6
+                      , time >= 1.2 && < 2
                       , transformers >= 0.5 && < 0.7
 
   hs-source-dirs:     src
diff --git a/src/System/FilePath/FilePather.hs b/src/System/FilePath/FilePather.hs
--- a/src/System/FilePath/FilePather.hs
+++ b/src/System/FilePath/FilePather.hs
@@ -2,6 +2,8 @@
   module P
 ) where
 
+import System.FilePath.FilePather.Compose as P
+import System.FilePath.FilePather.Directory as P
 import System.FilePath.FilePather.Find as P
 import System.FilePath.FilePather.Posix as P
 import System.FilePath.FilePather.ReadFilePath as P
diff --git a/src/System/FilePath/FilePather/Compose.hs b/src/System/FilePath/FilePather/Compose.hs
new file mode 100644
--- /dev/null
+++ b/src/System/FilePath/FilePather/Compose.hs
@@ -0,0 +1,55 @@
+{-# OPTIONS_GHC -Wall #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module System.FilePath.FilePather.Compose(
+  composeToRead
+, (->>-)
+, composeReadTo
+, (-<<-)
+) where
+
+import Control.Lens ( view, Wrapped(_Wrapped') )
+import Data.Functor.Bind ( (-<-), (->-), Bind )
+import System.FilePath.FilePather.ReadFilePath
+    ( ReadFilePathT(..) )
+import System.FilePath.FilePather.ToFilePath ( ToFilePathT(..) )
+
+composeToRead ::
+  Bind f =>
+  ToFilePathT f a
+  -> ReadFilePathT f b
+  -> a
+  -> f b
+composeToRead f g =
+  view _Wrapped' f ->- view _Wrapped' g
+
+(->>-) ::
+  Bind f =>
+  ToFilePathT f a
+  -> ReadFilePathT f b
+  -> a
+  -> f b
+(->>-) =
+  composeToRead
+
+infixr 1 ->>-
+
+composeReadTo ::
+  Bind f =>
+  ReadFilePathT f b
+  -> ToFilePathT f a
+  -> a
+  -> f b
+composeReadTo f g =
+  view _Wrapped' f -<- view _Wrapped' g
+
+(-<<-) ::
+  Bind f =>
+  ReadFilePathT f b
+  -> ToFilePathT f a
+  -> a
+  -> f b
+(-<<-) =
+  composeReadTo
+
+infixr 1 -<<-
diff --git a/src/System/FilePath/FilePather/Directory.hs b/src/System/FilePath/FilePather/Directory.hs
new file mode 100644
--- /dev/null
+++ b/src/System/FilePath/FilePather/Directory.hs
@@ -0,0 +1,292 @@
+{-# OPTIONS_GHC -Wall #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module System.FilePath.FilePather.Directory(
+  createDirectory
+, createDirectoryIfMissing
+, removeDirectory
+, removeDirectoryRecursive
+, removePathForcibly
+, renameDirectory
+, listDirectory
+, getDirectoryContents
+, withCurrentDirectory
+, getXdgDirectory
+, getAppUserDataDirectory
+, removeFile
+, renameFile
+, renamePath
+, copyFile
+, copyFileWithMetadata
+, getFileSize
+, canonicalizePath
+, makeAbsolute
+, makeRelativeToCurrentDirectory
+, doesPathExist
+, doesFileExist
+, doesDirectoryExist
+, findExecutable
+, findExecutables
+, findExecutablesInDirectories
+, findFile
+, findFiles
+, findFileWith
+, findFilesWith
+, createFileLink
+, createDirectoryLink
+, removeDirectoryLink
+, pathIsSymbolicLink
+, getSymbolicLinkTarget
+, getPermissions
+, setPermissions
+, copyPermissions
+, getAccessTime
+, getModificationTime
+, setAccessTime
+, setModificationTime
+, module SD
+) where
+
+import Control.Category ( Category((.)) )
+import Control.Lens ( over, _Wrapped )
+import Data.Maybe ( Maybe )
+import Data.Bool ( Bool )
+import Data.Time ( UTCTime )
+import GHC.Num( Integer )
+import qualified System.Directory as D
+import System.Directory as SD(getCurrentDirectory, getHomeDirectory, XdgDirectory(..), XdgDirectoryList(..), getXdgDirectoryList, getUserDocumentsDirectory, getTemporaryDirectory, exeExtension, Permissions(..), emptyPermissions, readable, writable, executable, searchable, setOwnerReadable, setOwnerWritable, setOwnerExecutable, setOwnerSearchable)
+import System.FilePath.FilePather.ReadFilePath
+    ( ReadFilePathT(..) )
+import System.FilePath ( FilePath )
+import System.IO ( IO )
+
+createDirectory ::
+  ReadFilePathT IO ()
+createDirectory =
+  ReadFilePathT D.createDirectory
+
+createDirectoryIfMissing ::
+  Bool
+  -> ReadFilePathT IO ()
+createDirectoryIfMissing =
+  ReadFilePathT . D.createDirectoryIfMissing
+
+removeDirectory ::
+  ReadFilePathT IO ()
+removeDirectory =
+  ReadFilePathT D.removeDirectory
+
+removeDirectoryRecursive ::
+  ReadFilePathT IO ()
+removeDirectoryRecursive =
+  ReadFilePathT D.removeDirectoryRecursive
+
+removePathForcibly ::
+  ReadFilePathT IO ()
+removePathForcibly =
+  ReadFilePathT D.removePathForcibly
+
+renameDirectory ::
+  FilePath
+  -> ReadFilePathT IO ()
+renameDirectory =
+  ReadFilePathT . D.renameDirectory
+
+listDirectory ::
+  ReadFilePathT IO [FilePath]
+listDirectory =
+  ReadFilePathT D.listDirectory
+
+getDirectoryContents ::
+  ReadFilePathT IO [FilePath]
+getDirectoryContents =
+  ReadFilePathT D.listDirectory
+
+withCurrentDirectory ::
+  IO a
+  -> ReadFilePathT IO a
+withCurrentDirectory io =
+  ReadFilePathT (`D.withCurrentDirectory` io)
+
+getXdgDirectory ::
+  XdgDirectory
+  -> ReadFilePathT IO FilePath
+getXdgDirectory xdg =
+  ReadFilePathT (D.getXdgDirectory xdg)
+
+getAppUserDataDirectory ::
+  ReadFilePathT IO FilePath
+getAppUserDataDirectory =
+  ReadFilePathT D.getAppUserDataDirectory
+
+removeFile ::
+  ReadFilePathT IO ()
+removeFile =
+  ReadFilePathT D.removeFile
+
+renameFile ::
+  FilePath
+  -> ReadFilePathT IO ()
+renameFile =
+  ReadFilePathT . D.renameFile
+
+renamePath ::
+  FilePath
+  -> ReadFilePathT IO ()
+renamePath =
+  ReadFilePathT . D.renamePath
+
+copyFile ::
+  FilePath
+  -> ReadFilePathT IO ()
+copyFile =
+  ReadFilePathT . D.copyFile
+
+copyFileWithMetadata ::
+  FilePath
+  -> ReadFilePathT IO ()
+copyFileWithMetadata =
+  ReadFilePathT . D.copyFileWithMetadata
+
+getFileSize ::
+  ReadFilePathT IO Integer
+getFileSize =
+  ReadFilePathT D.getFileSize
+
+canonicalizePath ::
+  ReadFilePathT IO FilePath
+canonicalizePath =
+  ReadFilePathT D.canonicalizePath
+
+makeAbsolute ::
+  ReadFilePathT IO FilePath
+makeAbsolute =
+  ReadFilePathT D.makeAbsolute
+
+makeRelativeToCurrentDirectory ::
+  ReadFilePathT IO FilePath
+makeRelativeToCurrentDirectory =
+  ReadFilePathT D.makeRelativeToCurrentDirectory
+
+doesPathExist ::
+  ReadFilePathT IO Bool
+doesPathExist =
+  ReadFilePathT D.doesPathExist
+
+doesFileExist ::
+  ReadFilePathT IO Bool
+doesFileExist =
+  ReadFilePathT D.doesFileExist
+
+doesDirectoryExist ::
+  ReadFilePathT IO Bool
+doesDirectoryExist =
+  ReadFilePathT D.doesDirectoryExist
+
+findExecutable ::
+  ReadFilePathT IO (Maybe FilePath)
+findExecutable =
+  ReadFilePathT D.findExecutable
+
+findExecutables ::
+  ReadFilePathT IO [FilePath]
+findExecutables =
+  ReadFilePathT D.findExecutables
+
+findExecutablesInDirectories ::
+  [FilePath]
+  -> ReadFilePathT IO [FilePath]
+findExecutablesInDirectories =
+  ReadFilePathT . D.findExecutablesInDirectories
+
+findFile ::
+  [FilePath]
+  -> ReadFilePathT IO (Maybe FilePath)
+findFile =
+  ReadFilePathT . D.findFile
+
+findFiles ::
+  [FilePath]
+  -> ReadFilePathT IO [FilePath]
+findFiles =
+  ReadFilePathT . D.findFiles
+
+findFileWith ::
+  ReadFilePathT IO Bool
+  -> [FilePath]
+  -> ReadFilePathT IO (Maybe FilePath)
+findFileWith x ps =
+  over _Wrapped (`D.findFileWith` ps) x
+
+findFilesWith ::
+  ReadFilePathT IO Bool
+  -> [FilePath]
+  -> ReadFilePathT IO [FilePath]
+findFilesWith x ps =
+  over _Wrapped (`D.findFilesWith` ps) x
+
+createFileLink ::
+  FilePath
+  -> ReadFilePathT IO ()
+createFileLink =
+  ReadFilePathT . D.createFileLink
+
+createDirectoryLink ::
+  FilePath
+  -> ReadFilePathT IO ()
+createDirectoryLink =
+  ReadFilePathT . D.createDirectoryLink
+
+removeDirectoryLink ::
+  ReadFilePathT IO ()
+removeDirectoryLink =
+  ReadFilePathT D.removeDirectoryLink
+
+pathIsSymbolicLink ::
+  ReadFilePathT IO Bool
+pathIsSymbolicLink =
+  ReadFilePathT D.pathIsSymbolicLink
+
+getSymbolicLinkTarget ::
+  ReadFilePathT IO FilePath
+getSymbolicLinkTarget =
+  ReadFilePathT D.getSymbolicLinkTarget
+
+getPermissions ::
+  ReadFilePathT IO Permissions
+getPermissions =
+  ReadFilePathT D.getPermissions
+
+setPermissions ::
+  Permissions
+  -> ReadFilePathT IO ()
+setPermissions p =
+  ReadFilePathT (`D.setPermissions` p)
+
+copyPermissions ::
+  FilePath
+  -> ReadFilePathT IO ()
+copyPermissions =
+  ReadFilePathT . D.copyPermissions
+
+getAccessTime ::
+  ReadFilePathT IO UTCTime
+getAccessTime =
+  ReadFilePathT D.getAccessTime
+
+getModificationTime ::
+  ReadFilePathT IO UTCTime
+getModificationTime =
+  ReadFilePathT D.getModificationTime
+
+setAccessTime ::
+  UTCTime
+  -> ReadFilePathT IO ()
+setAccessTime u =
+  ReadFilePathT (`D.setAccessTime` u)
+
+setModificationTime ::
+  UTCTime
+  -> ReadFilePathT IO ()
+setModificationTime u =
+  ReadFilePathT (`D.setModificationTime` u)
diff --git a/src/System/FilePath/FilePather/Find.hs b/src/System/FilePath/FilePather/Find.hs
--- a/src/System/FilePath/FilePather/Find.hs
+++ b/src/System/FilePath/FilePather/Find.hs
@@ -2,15 +2,18 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 
 module System.FilePath.FilePather.Find(
-  findFiles
+  findAllFiles
 , always
 , findFilesAlways
+, findFilesBase
+, findFilesBaseAlways
 ) where
 
 import Control.Applicative ( Applicative(liftA2, pure) )
 import Control.Category ( Category(id) )
 import Control.Lens ( view )
 import Control.Monad ( join, Monad((>>=)) )
+import Control.Monad.Reader.Class ( MonadReader(ask) )
 import System.FilePath.FilePather.Posix
     ( (</>), FilePath, dropTrailingPathSeparator )
 import System.IO ( IO )
@@ -23,10 +26,10 @@
 import System.FilePath.FilePather.ReadFilePath
     ( ReadFilePathT(..), readFilePath )
 
-findFiles ::
+findAllFiles ::
   ReadFilePathT IO Bool
   -> ReadFilePathT IO [FilePath]
-findFiles (ReadFilePathT test) =
+findAllFiles (ReadFilePathT test) =
   let bool' ::
         Monad f =>
         f a
@@ -70,9 +73,22 @@
   Applicative f =>
   ReadFilePathT f Bool
 always =
-  ReadFilePathT (pure (pure True))
+  pure True
 
 findFilesAlways ::
   ReadFilePathT IO [FilePath]
 findFilesAlways =
-  findFiles always
+  findAllFiles always
+
+findFilesBase ::
+  ReadFilePathT IO Bool
+  -> ReadFilePathT IO [FilePath]
+findFilesBase r =
+  do  p <- ask
+      z <- findAllFiles r
+      pure (fmap (p </>) z)
+
+findFilesBaseAlways ::
+  ReadFilePathT IO [FilePath]
+findFilesBaseAlways =
+  findFilesBase always
diff --git a/src/System/FilePath/FilePather/Posix.hs b/src/System/FilePath/FilePather/Posix.hs
--- a/src/System/FilePath/FilePather/Posix.hs
+++ b/src/System/FilePath/FilePather/Posix.hs
@@ -51,8 +51,8 @@
 import Data.String( String )
 import Data.Bool( Bool )
 import Data.Maybe ( Maybe )
-import qualified System.FilePath as FP
-import System.FilePath as SFP(FilePath, pathSeparator, pathSeparators, isPathSeparator, extSeparator, isExtSeparator, splitSearchPath, (-<.>), (</>))
+import qualified System.FilePath.Posix as FP
+import System.FilePath.Posix as SFP(FilePath, pathSeparator, pathSeparators, isPathSeparator, extSeparator, isExtSeparator, splitSearchPath, (-<.>), (</>))
 import System.FilePath.FilePather.ToFilePath
     ( ToFilePath, toFilePath )
 import System.FilePath.FilePather.ReadFilePath
diff --git a/src/System/FilePath/FilePather/ToFilePath.hs b/src/System/FilePath/FilePather/ToFilePath.hs
--- a/src/System/FilePath/FilePather/ToFilePath.hs
+++ b/src/System/FilePath/FilePather/ToFilePath.hs
@@ -9,19 +9,18 @@
 , toRead
 ) where
 
+import Control.Applicative ( Applicative(pure, liftA2) )
 import Control.Category ( Category((.)) )
-import Control.Lens
-    ( view,
-      from,
-      iso,
-      Iso,
-      Iso',
-      Wrapped(..) )
+import Control.Lens ( iso, Iso, Wrapped(..) )
 import Data.Functor.Contravariant ( Contravariant(contramap) )
+import Data.Either ( either )
+import Data.Functor.Contravariant.Divisible
+    ( Decidable(..), Divisible(..) )
 import Data.Functor.Identity ( Identity(..) )
-import System.FilePath ( FilePath )
+import Data.Void ( absurd )
+import System.FilePath ( (</>), FilePath )
 import System.FilePath.FilePather.ReadFilePath
-    ( ReadFilePath, readFilePath )
+    ( ReadFilePathT(..) )
 
 newtype ToFilePathT f a =
   ToFilePathT (a -> f FilePath)
@@ -41,6 +40,18 @@
   contramap f (ToFilePathT g) =
     ToFilePathT (g . f)
 
+instance Applicative f => Divisible (ToFilePathT f) where
+  divide f (ToFilePathT g) (ToFilePathT h) =
+    ToFilePathT (\x -> let (b, c) = f x in liftA2 (</>) (g b) (h c))
+  conquer =
+    ToFilePathT (pure (pure ""))
+
+instance Applicative f => Decidable (ToFilePathT f) where
+  choose f (ToFilePathT g) (ToFilePathT h) =
+    ToFilePathT (either g h . f)
+  lose f =
+    ToFilePathT (absurd . f)
+
 toFilePath ::
   Iso
     (ToFilePath a)
@@ -54,10 +65,13 @@
 {-# INLINE toFilePath #-}
 
 toRead ::
-  Iso'
-    (ToFilePath FilePath)
-    (ReadFilePath FilePath)
+  Iso
+    (ToFilePathT f FilePath)
+    (ToFilePathT f' FilePath)
+    (ReadFilePathT f FilePath)
+    (ReadFilePathT f' FilePath)
 toRead =
   iso
-    (view (toFilePath . from readFilePath))
-    (view (readFilePath . from toFilePath))
+    (\(ToFilePathT x) -> ReadFilePathT x)
+    (\(ReadFilePathT x) -> ToFilePathT x)
+{-# INLINE toRead #-}
