diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Revision history for streamly-posix
+
+## 0.1.0.0 -- 2020-02-16
+
+* First version. Released on an unsuspecting world.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2020, Julian Ospald
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Julian Ospald nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/src/Streamly/External/Posix/DirStream.hs b/src/Streamly/External/Posix/DirStream.hs
new file mode 100644
--- /dev/null
+++ b/src/Streamly/External/Posix/DirStream.hs
@@ -0,0 +1,85 @@
+{-# LANGUAGE CPP              #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiWayIf       #-}
+
+-- |
+-- Module      :  Streamly.External.Posix.DirStream
+-- Copyright   :  © 2020 Julian Ospald
+-- License     :  BSD3
+--
+-- Maintainer  :  Julian Ospald <hasufell@posteo.de>
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- This module provides high-level file streaming API,
+-- working with directory streams (POSIX).
+module Streamly.External.Posix.DirStream
+  (
+  -- * Directory listing
+    unfoldDirContents
+  , dirContentsStream
+  , dirContents
+  )
+where
+
+import           Control.Exception.Safe
+import           Control.Monad.IO.Class         ( liftIO
+                                                , MonadIO
+                                                )
+import           Data.Word8
+import           Prelude                 hiding ( readFile )
+import           Streamly
+import           Streamly.Internal.Data.Unfold.Types
+import           System.Posix.ByteString
+import           System.Posix.Directory.ByteString
+                                               as PosixBS
+import           System.Posix.Foreign           ( DirType )
+import           System.Posix.RawFilePath.Directory.Traversals
+                                         hiding ( getDirectoryContents )
+import qualified Data.ByteString               as BS
+import qualified Streamly.Internal.Data.Stream.StreamD.Type
+                                               as D
+#if MIN_VERSION_streamly(0,7,1)
+import qualified Streamly.Internal.Data.Unfold as SIU
+#endif
+import qualified Streamly.Internal.Prelude     as S
+
+
+-- | Create an 'Unfold' of directory contents.
+unfoldDirContents :: MonadIO m => Unfold m DirStream (DirType, RawFilePath)
+unfoldDirContents = Unfold step return
+ where
+  {-# INLINE [0] step #-}
+  step dirstream = do
+    (typ, e) <- liftIO $ readDirEnt dirstream
+    return if
+      | BS.null e                       -> D.Stop
+      | BS.pack [_period] == e          -> D.Skip dirstream
+      | BS.pack [_period, _period] == e -> D.Skip dirstream
+      | otherwise                       -> D.Yield (typ, e) dirstream
+
+
+-- | Read the directory contents as a stream.
+--
+-- The DirStream is closed automatically, when the streamly stream exits
+-- normally, aborts or gets garbage collected.
+-- The stream must not be used after the dirstream is closed.
+dirContentsStream :: (MonadCatch m, MonadAsync m, MonadMask m)
+                  => DirStream
+                  -> SerialT m (DirType, RawFilePath)
+dirContentsStream ds =
+#if MIN_VERSION_streamly(0,7,1)
+  S.unfold (SIU.finallyIO (liftIO . PosixBS.closeDirStream) unfoldDirContents) $ ds
+#else
+  S.finally (liftIO . PosixBS.closeDirStream $ ds) . S.unfold unfoldDirContents $ ds
+#endif
+
+
+-- | Read the directory contents strictly as a list.
+--
+-- The DirStream is closed automatically.
+dirContents :: (MonadCatch m, MonadAsync m, MonadMask m)
+            => DirStream
+            -> m [(DirType, RawFilePath)]
+dirContents = S.toList . dirContentsStream
+
diff --git a/streamly-posix.cabal b/streamly-posix.cabal
new file mode 100644
--- /dev/null
+++ b/streamly-posix.cabal
@@ -0,0 +1,56 @@
+cabal-version:       >=1.10
+
+name:                streamly-posix
+version:             0.1.0.0
+synopsis:            Posix related streaming APIs
+description:         Posix related streaming APIs (such as file reading/writing)
+bug-reports:         https://github.com/hasufell/streamly-posix/issues
+license:             BSD3
+license-file:        LICENSE
+author:              Julian Ospald <hasufell@posteo.de>
+maintainer:          Julian Ospald <hasufell@posteo.de>
+copyright:           Julian Ospald <hasufell@posteo.de> 2020
+category:            Streaming
+build-type:          Simple
+extra-source-files:  CHANGELOG.md
+
+library
+  if os(windows)
+    build-depends: unbuildable<0
+    buildable: False
+  exposed-modules:   Streamly.External.Posix.DirStream
+  -- other-modules:
+  -- other-extensions:
+  build-depends:         base                >= 4.12 && < 5
+                       , bytestring          >= 0.10
+                       , hpath-posix         >= 0.13
+                       , safe-exceptions     >= 0.1
+                       , streamly            >= 0.7
+                       , streamly-bytestring >= 0.1.0.1
+                       , unix                >= 2.7
+                       , word8               >= 0.1.3
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+  GHC-Options:         -Wall -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
+
+test-suite sf-test
+  if os(windows)
+    build-depends: unbuildable<0
+    buildable: False
+  type:                exitcode-stdio-1.0
+  main-is:             Main.hs
+  hs-source-dirs:      test
+  build-depends:         base                >= 4.12 && < 5
+                       , filepath
+                       , hpath-posix         >= 0.13
+                       , hspec
+                       , hspec-discover
+                       , streamly-posix
+                       , temporary
+                       , unix                >= 2.7
+  default-language:    Haskell2010
+  GHC-Options:         -Wall -threaded -rtsopts -with-rtsopts=-N
+
+source-repository head
+  type:     git
+  location: https://github.com/hasufell/streamly-posix
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,41 @@
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main where
+
+import           Data.Foldable
+import           Data.List                      ( sortBy )
+import           Streamly.External.Posix.DirStream
+import           System.FilePath
+import           System.IO
+import           System.IO.Temp
+import           System.Posix.Directory as Posix
+import           System.Posix.Foreign
+import           Test.Hspec
+
+
+
+checkDirContents :: FilePath -> IO ()
+checkDirContents fp = do
+  let f1 = fp </> "f1"
+  let f2 = fp </> "f2"
+  let f3 = fp </> "f3"
+  let f4 = fp </> "f4"
+  for_ [f1, f2, f3, f4] $ \f -> openFile f ReadWriteMode
+  ds       <- Posix.openDirStream fp
+  contents <- fmap (sortBy (\(_, y) (_, z) -> compare y z)) $ dirContents ds
+  contents
+    `shouldBe` [ (DirType 8, "f1")
+               , (DirType 8, "f2")
+               , (DirType 8, "f3")
+               , (DirType 8, "f4")
+               ]
+
+
+
+
+main :: IO ()
+main = hspec $ do
+  describe "Streamly.External.FileSystem.DirStream.Posix" $ do
+    it "dirContents" $ withSystemTempDirectory "y" checkDirContents
