diff --git a/process-extras.cabal b/process-extras.cabal
--- a/process-extras.cabal
+++ b/process-extras.cabal
@@ -1,5 +1,5 @@
 Name:               process-extras
-Version:            0.3.1
+Version:            0.3.3.1
 Synopsis:           Process extras
 Description:        Extra functionality for the Process library
                     <http://hackage.haskell.org/package/process>.
@@ -40,4 +40,5 @@
     process,
     bytestring,
     text,
-    deepseq
+    deepseq,
+    template-haskell
diff --git a/src/System/Process/ByteString.hs b/src/System/Process/ByteString.hs
--- a/src/System/Process/ByteString.hs
+++ b/src/System/Process/ByteString.hs
@@ -1,8 +1,9 @@
-{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE CPP, MultiParamTypeClasses, TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module System.Process.ByteString where
 
 import Control.Applicative ((<$>))
+import Control.DeepSeq (NFData)
 import Control.Monad
 import Data.ByteString (ByteString)
 import Data.ListLike.IO (hGetContents)
@@ -11,6 +12,10 @@
 import System.Process
 import System.Process.Common
 import System.Exit (ExitCode)
+
+#if !MIN_VERSION_bytestring(0,10,0)
+instance NFData ByteString
+#endif
 
 -- | Like 'System.Process.readProcessWithExitCode', but using 'ByteString'
 instance ListLikeProcessIO ByteString Word8 where
diff --git a/src/System/Process/ByteString/Lazy.hs b/src/System/Process/ByteString/Lazy.hs
--- a/src/System/Process/ByteString/Lazy.hs
+++ b/src/System/Process/ByteString/Lazy.hs
@@ -1,9 +1,9 @@
-{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE CPP, MultiParamTypeClasses, TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module System.Process.ByteString.Lazy where
 
 import Control.Applicative ((<$>))
-import Control.DeepSeq (force)
+import Control.DeepSeq (NFData, force)
 import qualified Control.Exception as C (evaluate)
 import Data.ByteString.Lazy (ByteString, toChunks, fromChunks)
 import Data.ListLike.IO (hGetContents)
@@ -12,6 +12,10 @@
 import System.Process
 import System.Process.Common
 import System.Exit (ExitCode)
+
+#if !MIN_VERSION_bytestring(0,10,0)
+instance NFData ByteString
+#endif
 
 -- | Like 'System.Process.readProcessWithExitCode', but using 'ByteString'
 instance ListLikeProcessIO ByteString Word8 where
diff --git a/src/System/Process/Common.hs b/src/System/Process/Common.hs
--- a/src/System/Process/Common.hs
+++ b/src/System/Process/Common.hs
@@ -1,9 +1,18 @@
-{-# LANGUAGE FlexibleInstances, FunctionalDependencies, MultiParamTypeClasses, RankNTypes, ScopedTypeVariables, UndecidableInstances #-}
+{-# LANGUAGE FlexibleInstances, FunctionalDependencies, MultiParamTypeClasses, RankNTypes, ScopedTypeVariables, TemplateHaskell, UndecidableInstances #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
-module System.Process.Common where
+module System.Process.Common
+    ( ProcessMaker(process)
+    , ListLikeProcessIO(forceOutput, readChunks)
+    , ProcessOutput(pidf, outf, errf, intf, codef)
+    , readProcessWithExitCode
+    , readCreateProcessWithExitCode
+    , readCreateProcess
+    , readCreateProcessLazy
+    ) where
 
 import Control.Applicative (pure, (<$>), (<*>))
 import Control.Concurrent
+import Control.DeepSeq (NFData)
 import Control.Exception as E (SomeException, onException, catch, mask, throw, try)
 import Control.Monad
 import Data.ListLike (null)
@@ -12,11 +21,35 @@
 import GHC.IO.Exception (IOErrorType(ResourceVanished), IOException(ioe_type))
 import Prelude hiding (null)
 import System.Exit (ExitCode(ExitFailure))
-import System.IO (Handle, hClose, hFlush)
+import System.IO (Handle, hClose, hFlush, BufferMode, hSetBuffering)
 import System.IO.Unsafe (unsafeInterleaveIO)
-import System.Process
+import System.Process hiding (readProcessWithExitCode)
 import Utils (forkWait)
 
+-- | This instance lets us use DeepSeq's force function on a stream of Chunks.
+instance NFData ExitCode
+
+class ProcessMaker a where
+    process :: a -> IO (Handle, Handle, Handle, ProcessHandle)
+
+-- | This is the usual maker argument to 'readCreateProcess'.
+instance ProcessMaker CreateProcess where
+    process p = do
+      (Just inh, Just outh, Just errh, pid) <- createProcess p { std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe }
+      return (inh, outh, errh, pid)
+
+-- | Passing this to 'readCreateProcess' as the maker argument allows
+-- you to set the buffer mode of the process stdout and stderr handles
+-- just after the handles are created.  These are set to
+-- BlockBuffering by default, but for running console commands
+-- LineBuffering is probably what you want.
+instance ProcessMaker (CreateProcess, BufferMode, BufferMode) where
+    process (p, outmode, errmode) = do
+      (Just inh, Just outh, Just errh, pid) <- createProcess p { std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe }
+      hSetBuffering outh outmode
+      hSetBuffering errh errmode
+      return (inh, outh, errh, pid)
+
 class Monoid b => ProcessOutput a b | b -> a where
     pidf :: ProcessHandle -> b
     outf :: a -> b
@@ -53,18 +86,15 @@
 readProcessWithExitCode cmd args input = readCreateProcessWithExitCode (proc cmd args) input
 
 readCreateProcessWithExitCode
-    :: ListLikeProcessIO a c =>
-       CreateProcess            -- ^ command and arguments to run
-    -> a               -- ^ standard input
+    :: (ProcessMaker maker, ListLikeProcessIO a c) =>
+       maker               -- ^ command and arguments to run
+    -> a                   -- ^ standard input
     -> IO (ExitCode, a, a) -- ^ exitcode, stdout, stderr
 readCreateProcessWithExitCode = readCreateProcess
 
-readCreateProcess :: (ProcessOutput a b, ListLikeProcessIO a c) => CreateProcess -> a -> IO b
-readCreateProcess p input = mask $ \restore -> do
-    (Just inh, Just outh, Just errh, pid) <-
-        createProcess p{ std_in  = CreatePipe,
-                                       std_out = CreatePipe,
-                                       std_err = CreatePipe }
+readCreateProcess :: (ProcessMaker maker, ProcessOutput a b, ListLikeProcessIO a c) => maker -> a -> IO b
+readCreateProcess maker input = mask $ \restore -> do
+    (inh, outh, errh, pid) <- process maker
     flip onException
       (do terminateProcess pid; hClose inh; hClose outh; hClose errh;
           waitForProcess pid) $ restore $ do
@@ -99,12 +129,9 @@
       ignoreResourceVanished' e = throw e
 
 -- | Like readCreateProcess, but the output is read lazily.
-readCreateProcessLazy :: (ProcessOutput a b, ListLikeProcessIO a c) => CreateProcess -> a -> IO b
-readCreateProcessLazy p input = mask $ \restore -> do
-    (Just inh, Just outh, Just errh, pid) <-
-        createProcess p{ std_in  = CreatePipe,
-                                       std_out = CreatePipe,
-                                       std_err = CreatePipe }
+readCreateProcessLazy :: (ProcessMaker maker, ProcessOutput a b, ListLikeProcessIO a c) => maker -> a -> IO b
+readCreateProcessLazy maker input = mask $ \restore -> do
+    (inh, outh, errh, pid) <- process maker
     onException
       (restore $
        do -- fork off a thread to start consuming stdout
diff --git a/src/System/Process/ListLike.hs b/src/System/Process/ListLike.hs
--- a/src/System/Process/ListLike.hs
+++ b/src/System/Process/ListLike.hs
@@ -1,8 +1,15 @@
--- | Re-export all symbols and instances of the process-extras package.
+-- | Re-export all symbols and instances of the process-extras
+-- package.  Adds the Chunk type with a ProcessOutput instance, and a
+-- collectOutput function to turn a list of chunks into any instance
+-- of ProcessOutput, such as (ExitCode, String, String).  This means
+-- you can have readCreateProcess output a list of Chunk, operate on
+-- it to do progress reporting, and finally convert it to the type
+-- that readProcessWithExitCode woud have returned.
 {-# LANGUAGE FlexibleInstances, FunctionalDependencies, MultiParamTypeClasses, UndecidableInstances #-}
 {-# OPTIONS_GHC -Wall -fno-warn-orphans #-}
 module System.Process.ListLike
-    ( ListLikeProcessIO(forceOutput)
+    ( ProcessMaker(process)
+    , ListLikeProcessIO(forceOutput)
     , ProcessOutput(pidf, outf, errf, codef, intf)
     , readCreateProcess
     , readCreateProcessLazy
@@ -24,8 +31,8 @@
 import System.Process (CmdSpec(..), CreateProcess(..), ProcessHandle, showCommandForUser)
 import System.Process.ByteString ()
 import System.Process.ByteString.Lazy ()
-import System.Process.Common (ListLikeProcessIO(forceOutput, readChunks), ProcessOutput(pidf, outf, errf, codef, intf),
-                                readCreateProcess, readCreateProcessLazy, readCreateProcessWithExitCode, readProcessWithExitCode)
+import System.Process.Common (ProcessMaker(process), ListLikeProcessIO(forceOutput, readChunks), ProcessOutput(pidf, outf, errf, codef, intf),
+                              readCreateProcess, readCreateProcessLazy, readCreateProcessWithExitCode, readProcessWithExitCode)
 import System.Process.Text ()
 import System.Process.Text.Lazy ()
 
diff --git a/src/Utils.hs b/src/Utils.hs
--- a/src/Utils.hs
+++ b/src/Utils.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE TemplateHaskell #-}
 module Utils where
 
 import Control.Concurrent
