diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # dir-traverse
 
+## 0.2.3.0
+
+  * Add `getFilesRecursive`
+
 ## 0.2.2.3
 
   * Performance improvements with `unsafeInterleaveIO`
diff --git a/dir-traverse.cabal b/dir-traverse.cabal
--- a/dir-traverse.cabal
+++ b/dir-traverse.cabal
@@ -1,6 +1,6 @@
 cabal-version:   1.18
 name:            dir-traverse
-version:         0.2.2.3
+version:         0.2.3.0
 license:         BSD3
 license-file:    LICENSE
 copyright:       Copyright: (c) 2019 Vanessa McHale
diff --git a/src/System/Directory/Recursive.hs b/src/System/Directory/Recursive.hs
--- a/src/System/Directory/Recursive.hs
+++ b/src/System/Directory/Recursive.hs
@@ -1,5 +1,6 @@
 module System.Directory.Recursive ( getDirRecursive
                                   , getSubdirsRecursive
+                                  , getFilesRecursive
                                   , getDirFiltered
                                   ) where
 
@@ -7,20 +8,35 @@
 import           Control.Monad       (filterM)
 import           Data.Foldable       (fold)
 import           Data.Traversable    (traverse)
-import           System.Directory    (doesDirectoryExist, listDirectory)
+import           System.Directory    (doesDirectoryExist, doesFileExist,
+                                      listDirectory)
 import           System.FilePath     ((</>))
 import           System.IO.Unsafe    (unsafeInterleaveIO)
 
 
--- | @since 0.2.1.0
+-- | Recursively get all subdirectories in the given directory.
+--
+-- @since 0.2.1.0
 getSubdirsRecursive :: FilePath -> IO [FilePath]
 getSubdirsRecursive = getDirFiltered doesDirectoryExist
 
+-- | Recursively get all files and subdirectories in the given directory.
 getDirRecursive :: FilePath -> IO [FilePath]
-getDirRecursive = getDirFiltered (const (pure True))
+getDirRecursive = getDirFiltered (const $ pure True)
 
+-- | Recursively get all files in the given directory.
+--
+-- @since 0.2.3.0
+getFilesRecursive :: FilePath -> IO [FilePath]
+getFilesRecursive fp = getDirRecursive fp >>= filterM doesFileExist
+
 {-# INLINE getDirFiltered #-}
--- | @since 0.2.2.0
+-- | Recursively get all files and subdirectories in the given directory that
+-- satisfy the given predicate. Note that the content of subdirectories not
+-- matching the filter is ignored. In particular, that means something like
+-- @getDirFiltered doesFileExist@ will /not/ recursively return all files.
+--
+-- @since 0.2.2.0
 getDirFiltered :: (FilePath -> IO Bool) -- ^ Filepath filter
                -> FilePath
                -> IO [FilePath]
