diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # dir-traverse
 
+## 0.2.2.0
+
+  * Add `getDirFiltered`
+
 ## 0.2.1.0
 
   * Add `getSubdirsRecursive`
diff --git a/dir-traverse.cabal b/dir-traverse.cabal
--- a/dir-traverse.cabal
+++ b/dir-traverse.cabal
@@ -1,46 +1,47 @@
-cabal-version: 1.18
-name: dir-traverse
-version: 0.2.1.0
-license: BSD3
-license-file: LICENSE
-copyright: Copyright: (c) 2019 Vanessa McHale
-maintainer: vamchale@gmail.com
-author: Vanessa McHale
-synopsis: Simple directory traversal library
-description:
-    Simple cross-platform directory traversals in Haskell
-category: System, Directory
-build-type: Simple
-extra-doc-files: README.md
-                 CHANGELOG.md
+cabal-version:   1.18
+name:            dir-traverse
+version:         0.2.2.0
+license:         BSD3
+license-file:    LICENSE
+copyright:       Copyright: (c) 2019 Vanessa McHale
+maintainer:      vamchale@gmail.com
+author:          Vanessa McHale
+synopsis:        Simple directory traversal library
+description:     Simple cross-platform directory traversals in Haskell
+category:        System, Directory
+build-type:      Simple
+extra-doc-files:
+    README.md
+    CHANGELOG.md
 
 source-repository head
-    type: git
+    type:     git
     location: https://github.com/vmchale/dir-traverse
 
 library
-    exposed-modules:
-        System.Directory.Recursive
-    hs-source-dirs: src
+    exposed-modules:  System.Directory.Recursive
+    hs-source-dirs:   src
     default-language: Haskell2010
-    ghc-options: -Wall -O2
+    ghc-options:      -Wall
     build-depends:
         base >=4.3 && <5,
-        directory -any
+        directory >=1.2.5.0,
+        filepath -any
 
     if impl(ghc >=8.0)
-        ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates
-                     -Wredundant-constraints -Widentities
+        ghc-options:
+            -Wincomplete-uni-patterns -Wincomplete-record-updates
+            -Wredundant-constraints -Widentities
 
     if impl(ghc >=8.4)
         ghc-options: -Wmissing-export-lists
 
 benchmark dir-traverse-bench
-    type: exitcode-stdio-1.0
-    main-is: Bench.hs
-    hs-source-dirs: bench
+    type:             exitcode-stdio-1.0
+    main-is:          Bench.hs
+    hs-source-dirs:   bench
     default-language: Haskell2010
-    ghc-options: -Wall
+    ghc-options:      -Wall
     build-depends:
         base >=4.9,
         dir-traverse -any,
@@ -52,8 +53,9 @@
         directory -any
 
     if impl(ghc >=8.0)
-        ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates
-                     -Wredundant-constraints -Widentities
+        ghc-options:
+            -Wincomplete-uni-patterns -Wincomplete-record-updates
+            -Wredundant-constraints -Widentities
 
     if impl(ghc >=8.4)
         ghc-options: -Wmissing-export-lists
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,36 +1,29 @@
 module System.Directory.Recursive ( getDirRecursive
                                   , getSubdirsRecursive
+                                  , getDirFiltered
                                   ) where
 
 import           Control.Applicative (pure, (<$>))
 import           Control.Monad       (filterM)
 import           Data.Foldable       (fold)
 import           Data.Traversable    (traverse)
-import           System.Directory    (doesDirectoryExist, getDirectoryContents)
-import           System.Info         (os)
+import           System.Directory    (doesDirectoryExist, listDirectory)
+import           System.FilePath     ((</>))
 
 
-{-# INLINE getSubdirsRecursive #-}
 -- | @since 0.2.1.0
 getSubdirsRecursive :: FilePath -> IO [FilePath]
-getSubdirsRecursive fp = do
-    all' <- listDirectory fp
-    let all'' = mkRel <$> all'
-    dirs <- filterM doesDirectoryExist all''
-    case dirs of
-        [] -> pure dirs
-        ds -> do
-            next <- foldMapA getSubdirsRecursive ds
-            pure $ dirs ++ next
-
-    where mkRel = (fp </>)
-          foldMapA = (fmap fold .) . traverse
+getSubdirsRecursive = getDirFiltered (const (pure True))
 
-{-# INLINE getDirRecursive #-}
 getDirRecursive :: FilePath -> IO [FilePath]
-getDirRecursive fp = do
+getDirRecursive = getDirFiltered doesDirectoryExist
+
+{-# INLINE getDirFiltered #-}
+-- | @since 0.2.2.0
+getDirFiltered :: (FilePath -> IO Bool) -> FilePath -> IO [FilePath]
+getDirFiltered p fp = do
     all' <- listDirectory fp
-    let all'' = mkRel <$> all'
+    all'' <- filterM p (mkRel <$> all')
     dirs <- filterM doesDirectoryExist all''
     case dirs of
         [] -> pure all''
@@ -40,12 +33,3 @@
 
     where mkRel = (fp </>)
           foldMapA = (fmap fold .) . traverse
-
-(</>) :: FilePath -> FilePath -> FilePath
-(</>) x y =
-    case os of
-        "mingw32" -> x ++ "\\" ++ y
-        _         -> x ++ "/" ++ y
-
-listDirectory :: FilePath -> IO [FilePath]
-listDirectory = fmap (filter (\p -> p /= "." && p /= "..")) . getDirectoryContents
