diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Changelog for unliftio-path
+
+# v0.0.1.0
+
+* Mirror of most UnliftIO.Directory functions using `Path` instead of `FilePath`.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020 Daniel Firth
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# unliftio-path
+
+This is [unliftio](https://hackage.haskell.org/package/unliftio) but using the
+[path](https://hackage.haskell.org/package/path) library instead of
+`FilePath`s. Early release, contains most directory operations.
diff --git a/src/UnliftIO/Path/Directory.hs b/src/UnliftIO/Path/Directory.hs
new file mode 100644
--- /dev/null
+++ b/src/UnliftIO/Path/Directory.hs
@@ -0,0 +1,227 @@
+{- |
+   Module     : UnliftIO.Path.Directory
+   License    : MIT
+   Stability  : experimental
+
+`UnliftIO.Directory lifted to `Path`.
+-}
+module UnliftIO.Path.Directory (
+  createDirectory
+, createDirectoryIfMissing
+, removeDirectory
+, removeDirectoryRecursive
+, removePathForcibly
+, renameDirectory
+, listDirectory
+, getDirectoryContents
+, getCurrentDirectory
+, setCurrentDirectory
+, withCurrentDirectory
+, getHomeDirectory
+, getXdgDirectory
+, UnliftIO.Directory.XdgDirectory(..)
+, getAppUserDataDirectory
+, getUserDocumentsDirectory
+, getTemporaryDirectory
+, removeFile
+, renameFile
+, copyFile
+, copyFileWithMetadata
+, findExecutable
+, findExecutables
+, UnliftIO.Directory.exeExtension
+, getFileSize
+, doesPathExist
+, doesFileExist
+, doesDirectoryExist
+, pathIsSymbolicLink
+, UnliftIO.Directory.Permissions
+, UnliftIO.Directory.emptyPermissions
+, UnliftIO.Directory.readable
+, UnliftIO.Directory.writable
+, UnliftIO.Directory.executable
+, UnliftIO.Directory.searchable
+, UnliftIO.Directory.setOwnerReadable
+, UnliftIO.Directory.setOwnerWritable
+, UnliftIO.Directory.setOwnerExecutable
+, UnliftIO.Directory.setOwnerSearchable
+, getPermissions
+, setPermissions
+, copyPermissions
+, getAccessTime
+, getModificationTime
+, setAccessTime
+, setModificationTime
+) where
+
+import Control.Monad
+import Control.Monad.Catch
+import Control.Monad.IO.Class
+import Data.Time
+import Path
+import UnliftIO
+import qualified UnliftIO.Directory
+
+-- Lifted `UnliftIO.Directory.createDirectory`.
+createDirectory :: MonadIO m => Path b Dir -> m ()
+createDirectory = UnliftIO.Directory.createDirectory . toFilePath
+
+-- Lifted `UnliftIO.Directory.createDirectoryIfMissing`.
+createDirectoryIfMissing :: MonadIO m => Bool -> Path b Dir -> m ()
+createDirectoryIfMissing b = UnliftIO.Directory.createDirectoryIfMissing b . toFilePath
+
+-- Lifted `UnliftIO.Directory.removeDirectory`.
+removeDirectory :: MonadIO m => Path b Dir -> m ()
+removeDirectory = UnliftIO.Directory.removeDirectory . toFilePath
+
+-- Lifted `UnliftIO.Directory.removeDirectoryRecursive`.
+removeDirectoryRecursive :: MonadIO m => Path b Dir -> m ()
+removeDirectoryRecursive = UnliftIO.Directory.removeDirectoryRecursive . toFilePath
+
+-- Lifted `UnliftIO.Directory.removePathForcibly`.
+removePathForcibly :: MonadIO m => Path b t -> m ()
+removePathForcibly = UnliftIO.Directory.removePathForcibly . toFilePath
+
+-- Lifed `UnliftIO.Directory.renameDirectory`.
+renameDirectory :: MonadIO m => Path b Dir -> Path b' Dir -> m ()
+renameDirectory x y = UnliftIO.Directory.renameDirectory (toFilePath x) (toFilePath y)
+
+getDirectoryContents_ :: (MonadThrow m, MonadIO m) => Path b Dir -> m ([Path Rel Dir], [Path Rel File])
+getDirectoryContents_ d = do
+  xs   <- UnliftIO.Directory.listDirectory . toFilePath $ d
+  dirs <- mapM parseRelDir =<< filterM UnliftIO.Directory.doesDirectoryExist xs
+  fils <- mapM parseRelFile =<< filterM UnliftIO.Directory.doesFileExist xs
+  return (dirs, fils)
+
+-- Lifted `UnliftIO.Directory.listDirectory`.
+listDirectory :: (MonadThrow m, MonadIO m) => Path b Dir -> m ([Path Rel Dir], [Path Rel File])
+listDirectory = getDirectoryContents_
+
+-- Lifted `UnliftIO.Directory.getDirectoryContents`.
+getDirectoryContents :: (MonadThrow m, MonadIO m) => Path b Dir -> m ([Path Rel Dir], [Path Rel File])
+getDirectoryContents = getDirectoryContents_
+
+-- Lifted `UnliftIO.Directory.getCurrentDirectory`.
+getCurrentDirectory :: (MonadThrow m, MonadIO m) => m (Path Abs Dir)
+getCurrentDirectory = UnliftIO.Directory.getCurrentDirectory >>= parseAbsDir
+
+-- Lifted `UnliftIO.Directory.setCurrentDirectory`.
+setCurrentDirectory :: MonadIO m => Path Abs Dir -> m ()
+setCurrentDirectory = UnliftIO.Directory.setCurrentDirectory . toFilePath
+
+-- Lifted `UnliftIO.Directory.withCurrentDirectory`.
+withCurrentDirectory :: (MonadThrow m, MonadUnliftIO m) => Path Abs Dir -> m a -> m a
+withCurrentDirectory = UnliftIO.Directory.withCurrentDirectory . toFilePath
+
+-- Lifted `UnliftIO.Directory.getHomeDirectory`.
+getHomeDirectory :: (MonadThrow m, MonadIO m) => m (Path Abs Dir)
+getHomeDirectory = UnliftIO.Directory.getHomeDirectory >>= parseAbsDir
+
+-- Lifted `UnliftIO.Directory.getXdgDirectory`.
+getXdgDirectory :: (MonadThrow m, MonadIO m) => UnliftIO.Directory.XdgDirectory -> Path Rel Dir -> m (Path Abs Dir)
+getXdgDirectory x = UnliftIO.Directory.getXdgDirectory x . toFilePath >=> parseAbsDir
+
+-- Lifted `UnliftIO.Directory.getAppUserDataDirectory`.
+getAppUserDataDirectory :: (MonadThrow m, MonadIO m) => Path Rel Dir -> m (Path Abs Dir)
+getAppUserDataDirectory = UnliftIO.Directory.getAppUserDataDirectory . toFilePath >=> parseAbsDir
+
+-- Lifted `UnliftIO.Directory.getUserDocumentsDirectory`.
+getUserDocumentsDirectory :: (MonadThrow m, MonadIO m) => m (Path Abs Dir)
+getUserDocumentsDirectory = UnliftIO.Directory.getUserDocumentsDirectory >>= parseAbsDir
+
+-- Lifted `UnliftIO.Directory.getTemporaryDirectory`.
+getTemporaryDirectory :: (MonadThrow m, MonadIO m) => m (Path Abs Dir)
+getTemporaryDirectory = UnliftIO.Directory.getTemporaryDirectory >>= parseAbsDir
+
+-- Lifted `UnliftIO.Directory.removeFile`.
+removeFile :: MonadIO m => Path b File -> m ()
+removeFile = UnliftIO.Directory.removeFile . toFilePath
+
+-- Lifted `UnliftIO.Directory.renameFile`.
+renameFile :: MonadIO m => Path b File -> Path b' File -> m ()
+renameFile x y = UnliftIO.Directory.renameFile (toFilePath x) (toFilePath y)
+
+-- Lifted `UnliftIO.Directory.renamePath`.
+renamePath :: MonadIO m => Path b t -> Path b' t -> m ()
+renamePath x y = UnliftIO.Directory.renamePath (toFilePath x) (toFilePath y)
+
+-- Lifted 'UnliftIO.Directory.copyFile'.
+copyFile :: MonadIO m => Path b File -> Path b' File -> m ()
+copyFile x y = UnliftIO.Directory.copyFile (toFilePath x) (toFilePath y)
+
+-- Lifted 'UnliftIO.Directory.copyFileWithMetadata`.
+copyFileWithMetadata :: MonadIO m => Path b File -> Path b' File -> m ()
+copyFileWithMetadata x y = UnliftIO.Directory.copyFile (toFilePath x) (toFilePath y)
+
+-- Lifted `UnliftIO.Directory.makeAbsolute`, `Dir` specific. Takes only `Path Rel Dirs`s.
+makeAbsoluteDir :: (MonadThrow m, MonadIO m) => Path Rel Dir -> m (Path Abs Dir)
+makeAbsoluteDir = UnliftIO.Directory.makeAbsolute . toFilePath >=> parseAbsDir
+
+-- Lifted `UnliftIO.Directory.makeAbsolute`, `File` specific. Takes only `Path Rel File`s.
+makeAbsoluteFile :: (MonadThrow m, MonadIO m) => Path Rel File -> m (Path Abs File)
+makeAbsoluteFile = UnliftIO.Directory.makeAbsolute . toFilePath >=> parseAbsFile
+
+-- Lifted `UnliftIO.Directory.makeRelativeToCurrentDirectory`, `Dir` specific. Takes only `Path Abs Dir`s.
+makeRelativeToCurrentDirectoryDir :: (MonadThrow m, MonadIO m) => Path Abs Dir -> m (Path Rel Dir)
+makeRelativeToCurrentDirectoryDir = UnliftIO.Directory.makeRelativeToCurrentDirectory . toFilePath >=> parseRelDir
+
+-- Lifted `UnliftIO.Directory.makeRelativeToCurrentDirectory`, `File` specific. Takes only `Path Abs File`s.
+makeRelativeToCurrentDirectoryFile :: (MonadThrow m, MonadIO m) => Path Abs File -> m (Path Rel File)
+makeRelativeToCurrentDirectoryFile = UnliftIO.Directory.makeRelativeToCurrentDirectory . toFilePath >=> parseRelFile
+
+-- Lifted `UnliftIO.Directory.findExecutable`.
+findExecutable :: (MonadThrow m, MonadIO m) => String -> m (Maybe (Path Abs File))
+findExecutable = UnliftIO.Directory.findExecutable >=> mapM parseAbsFile
+
+-- Lifted `UnliftIO.Directory.findExecutables`.
+findExecutables :: (MonadThrow m, MonadIO m) => String -> m [Path Abs File]
+findExecutables = UnliftIO.Directory.findExecutables >=> mapM parseAbsFile
+
+-- Lifted `UnliftIO.Directory.getFileSize`.
+getFileSize :: MonadIO m => Path b File -> m Integer
+getFileSize = UnliftIO.Directory.getFileSize . toFilePath
+
+-- Lifted `UnliftIO.Directory.doesPathExist`.
+doesPathExist :: MonadIO m => Path b t -> m Bool
+doesPathExist = UnliftIO.Directory.doesPathExist . toFilePath
+
+-- Lifted `UnliftIO.Directory.doesFileExist`.
+doesFileExist :: MonadIO m => Path b File -> m Bool
+doesFileExist = UnliftIO.Directory.doesFileExist . toFilePath
+
+-- Lifted `UnliftIO.Directory.doesDirectoryExist`.
+doesDirectoryExist :: MonadIO m => Path b Dir -> m Bool
+doesDirectoryExist = UnliftIO.Directory.doesDirectoryExist . toFilePath
+
+-- Lifted `UnliftIO.Directory.pathIsSymbolicLink`.
+pathIsSymbolicLink :: MonadIO m => Path b t -> m Bool
+pathIsSymbolicLink = UnliftIO.Directory.pathIsSymbolicLink . toFilePath
+
+-- Lifted `UnliftiO.Directory.getPermissions`.
+getPermissions :: MonadIO m => Path b t -> m UnliftIO.Directory.Permissions
+getPermissions = UnliftIO.Directory.getPermissions . toFilePath
+
+-- Lifted `UnliftiO.Directory.getPermissions`.
+setPermissions :: MonadIO m => Path b t -> UnliftIO.Directory.Permissions -> m ()
+setPermissions = UnliftIO.Directory.setPermissions . toFilePath
+
+-- Lifted `UnliftiO.Directory.copyPermissions`.
+copyPermissions :: MonadIO m => Path b t -> Path b' t' -> m ()
+copyPermissions x y = UnliftIO.Directory.copyPermissions (toFilePath x) (toFilePath y)
+
+-- Lifted `UnliftIO.Directory.getAccessTime`.
+getAccessTime :: MonadIO m => Path b t -> m UTCTime
+getAccessTime = UnliftIO.Directory.getAccessTime . toFilePath
+
+-- Lifted `UnliftIO.Directory.getModificationTime`.
+getModificationTime :: MonadIO m => Path b t -> m UTCTime
+getModificationTime = UnliftIO.Directory.getModificationTime . toFilePath
+
+-- Lifted `UnliftIO.Directory.setAccessTime`.
+setAccessTime :: MonadIO m => Path b t -> UTCTime -> m ()
+setAccessTime x = UnliftIO.Directory.setAccessTime (toFilePath x)
+
+-- Lifted `UnliftIO.Directory.setModificationTime`.
+setModificationTime :: MonadIO m => Path b t -> UTCTime -> m ()
+setModificationTime x = UnliftIO.Directory.setModificationTime (toFilePath x)
+
diff --git a/unliftio-path.cabal b/unliftio-path.cabal
new file mode 100644
--- /dev/null
+++ b/unliftio-path.cabal
@@ -0,0 +1,35 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.34.2.
+--
+-- see: https://github.com/sol/hpack
+
+name:           unliftio-path
+version:        0.0.1.0
+synopsis:       UnliftIO using well-typed Paths.
+description:    UnliftIO using well-typed Paths.
+category:       Text
+author:         Daniel Firth
+maintainer:     dan.firth@homotopic.tech
+copyright:      2020 Daniel Firth
+license:        MIT
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    README.md
+    ChangeLog.md
+
+library
+  exposed-modules:
+      UnliftIO.Path.Directory
+  other-modules:
+      Paths_unliftio_path
+  hs-source-dirs:
+      src
+  build-depends:
+      base >=4.7 && <5
+    , exceptions
+    , path
+    , time
+    , unliftio
+  default-language: Haskell2010
