diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,11 +1,15 @@
 # Revision history for reflex-process
 
+## 0.3.1.0
+
+* Support reflex 0.8
+* Fix a handle leak (#23) and a thread leak (#24)
+
 ## 0.3.0.0
 
 * ([#15](https://github.com/reflex-frp/reflex-process/pull/15), [#13](https://github.com/reflex-frp/reflex-process/pull/13)) **(Breaking change)** Introduce `SendPipe` type for encoding when an input stream should send EOF. Change `createProcess` to take a `ProcessConfig t (SendPipe ByteString)` so that sending EOF is possible.
   * **IMPORTANT**: For `createProcess` messages to `stdin` must now be wrapped in `SendPipe_Message` *and* have a `"\n"` manually appended to regain the old behavior. Previously `createProcess` implicitly added a `"\n"` to all messages sent to the process. This has been removed and *you must now manually add any necessary new lines to your messages.* This change allows `createProcess` to work with processes in a encoding-agnostic way on `stdin`.
 * ([#17](https://github.com/reflex-frp/reflex-process/pull/17)) Deprecate `createRedirectedProcess` in favor of a new, scarier name: `unsafeCreateProcessWithHandles`. This was done to communicate that it does not enforce necessary guarantees for the process to be handled correctly.
-* ([#15](https://github.com/reflex-frp/reflex-process/pull/15), [#13](https://github.com/reflex-frp/reflex-process/pull/13)) **(Breaking change)** Sending a message with `SendPipe_Message` `createProcess`
 * ([#11](https://github.com/reflex-frp/reflex-process/pull/11)) Add `createProcessBufferingInput` for buffering input to processes and change `createProcess` to use an unbounded buffer instead of blocking the FRP network when the process blocks on its input handle.
 * ([#11](https://github.com/reflex-frp/reflex-process/pull/11), [#14](https://github.com/reflex-frp/reflex-process/pull/14)) `ProcessConfig` now includes a `_processConfig_createProcess` field for customizing how the process is created.
 * ([#13](https://github.com/reflex-frp/reflex-process/pull/13)) Fix race condition between process completion `Event`s and process `stdout`/`stderr` `Event`s. Process completion is now always the very last `Event` to fire for a given `Process`.
diff --git a/README.lhs b/README.lhs
--- a/README.lhs
+++ b/README.lhs
@@ -1,12 +1,12 @@
 reflex-process
 ==============
 
-[![hackage](https://img.shields.io/hackage/v/reflex-process.svg)](https://hackage.haskell.org/package/reflex-process) [![hackage-ci](https://matrix.hackage.haskell.org/api/v2/packages/reflex-process/badge)](https://matrix.hackage.haskell.org/#/package/reflex-process) [![travis-ci](https://api.travis-ci.org/reflex-frp/reflex-process.svg?branch=develop)](https://travis-ci.org/reflex-frp/reflex-process)
+[![Haskell](https://img.shields.io/badge/language-Haskell-orange.svg)](https://haskell.org) [![Hackage](https://img.shields.io/hackage/v/reflex-process.svg)](https://hackage.haskell.org/package/reflex-process) [![Hackage CI](https://matrix.hackage.haskell.org/api/v2/packages/reflex-process/badge)](https://matrix.hackage.haskell.org/#/package/reflex-process) [![Travis CI](https://api.travis-ci.org/reflex-frp/reflex-process.svg?branch=develop)](https://travis-ci.org/reflex-frp/reflex-process) [![BSD3 License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://github.com/reflex-frp/reflex-process/blob/master/LICENSE)
 
-Functional-reactive shell commands
-----------------------------------
+Functional-reactive system processes
+------------------------------------
 
-This library provides a functional-reactive interface for running shell commands from [reflex](https://github.com/reflex-frp/reflex).
+Run and interact with system processes from within a [Reflex FRP](https://reflex-frp.org/) application.
 
 Example
 -------
@@ -46,7 +46,8 @@
 ---------------------
 
 You can get `ghcid` running for working on the code with the command:
-```
+
+```bash
 nix-shell -E '((import ./reflex-platform {}).ghc.callCabal2nix "reflex-process" ./. {}).env' --run ghcid
 ```
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
 reflex-process
 ==============
 
-[![hackage](https://img.shields.io/hackage/v/reflex-process.svg)](https://hackage.haskell.org/package/reflex-process) [![hackage-ci](https://matrix.hackage.haskell.org/api/v2/packages/reflex-process/badge)](https://matrix.hackage.haskell.org/#/package/reflex-process) [![travis-ci](https://api.travis-ci.org/reflex-frp/reflex-process.svg?branch=develop)](https://travis-ci.org/reflex-frp/reflex-process)
+[![Haskell](https://img.shields.io/badge/language-Haskell-orange.svg)](https://haskell.org) [![Hackage](https://img.shields.io/hackage/v/reflex-process.svg)](https://hackage.haskell.org/package/reflex-process) [![Hackage CI](https://matrix.hackage.haskell.org/api/v2/packages/reflex-process/badge)](https://matrix.hackage.haskell.org/#/package/reflex-process) [![Travis CI](https://api.travis-ci.org/reflex-frp/reflex-process.svg?branch=develop)](https://travis-ci.org/reflex-frp/reflex-process) [![BSD3 License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://github.com/reflex-frp/reflex-process/blob/master/LICENSE)
 
-Functional-reactive shell commands
-----------------------------------
+Functional-reactive system processes
+------------------------------------
 
-This library provides a functional-reactive interface for running shell commands from [reflex](https://github.com/reflex-frp/reflex).
+Run and interact with system processes from within a [Reflex FRP](https://reflex-frp.org/) application.
 
 Example
 -------
@@ -46,7 +46,8 @@
 ---------------------
 
 You can get `ghcid` running for working on the code with the command:
-```
+
+```bash
 nix-shell -E '((import ./reflex-platform {}).ghc.callCabal2nix "reflex-process" ./. {}).env' --run ghcid
 ```
 
diff --git a/reflex-process.cabal b/reflex-process.cabal
--- a/reflex-process.cabal
+++ b/reflex-process.cabal
@@ -1,8 +1,11 @@
 cabal-version: >=1.10
 name: reflex-process
-version: 0.3.0.0
-synopsis: reflex-frp interface for running shell commands
-description: Run shell commands from within reflex applications and interact with them over a functional-reactive interface
+version: 0.3.1.0
+synopsis: Reflex FRP interface for running system processes
+description:
+  Run and interact with system processes from within a Reflex FRP application.
+  .
+  <https://reflex-frp.org>
 bug-reports: https://github.com/reflex-frp/reflex-process/issues
 license: BSD3
 license-file: LICENSE
@@ -22,7 +25,7 @@
                , bytestring >=0.10 && < 0.11
                , data-default >= 0.2 && < 0.8
                , process >= 1.6.4 && < 1.7
-               , reflex >= 0.7.1 && < 0.8
+               , reflex >= 0.7.1 && < 0.9
                , unix >= 2.7 && < 2.8
   hs-source-dirs: src
   default-language: Haskell2010
diff --git a/src/Reflex/Process.hs b/src/Reflex/Process.hs
--- a/src/Reflex/Process.hs
+++ b/src/Reflex/Process.hs
@@ -4,6 +4,7 @@
 -}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE GADTs #-}
+{-# LANGUAGE RecursiveDo #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 module Reflex.Process
@@ -19,11 +20,12 @@
   , createRedirectedProcess
   ) where
 
-import Control.Concurrent.Async (Async, async, waitBoth)
+import Control.Concurrent.Async (Async, async, race_, waitBoth)
 import Control.Concurrent.Chan (newChan, readChan, writeChan)
 import Control.Exception (finally)
 import Control.Monad (void, when)
 import Control.Monad.IO.Class (MonadIO, liftIO)
+import Control.Monad.Fix (MonadFix)
 import Data.ByteString (ByteString)
 import qualified Data.ByteString as BS
 import Data.Default (Default, def)
@@ -40,13 +42,11 @@
 
 data SendPipe i
   = SendPipe_Message i
-  -- ^ A message that's sent to the underlying process
+  -- ^ A message that's sent to the underlying process. This does NOT include a trailing newline when sending your message.
   | SendPipe_EOF
-  -- ^ Send an EOF to the underlying process
+  -- ^ Send an EOF to the underlying process. Once this is sent no further messages will be processed.
   | SendPipe_LastMessage i
-  -- ^ Send the last message (an EOF will be added). This option is offered for
-  -- convenience, because it has the same effect of sending a Message and then
-  -- the EOF signal
+  -- ^ Send the last message along with an EOF. Once this is sent no further messages will be processed.
 
 -- | The inputs to a process
 data ProcessConfig t i = ProcessConfig
@@ -81,7 +81,7 @@
   }
 
 -- | Create a process feeding it input using an 'Event' and exposing its output
--- 'Event's representing the process exit code, stdout, and stderr.
+-- 'Event's representing the process exit code, @stdout@, and @stderr@.
 --
 -- The @stdout@ and @stderr@ 'Handle's are line-buffered.
 --
@@ -92,7 +92,7 @@
 -- provided 'CreateProcess' are replaced with new pipes and all output is redirected
 -- to those pipes.
 createProcess
-  :: (MonadIO m, TriggerEvent t m, PerformEvent t m, MonadIO (Performable m))
+  :: (MonadIO m, TriggerEvent t m, PerformEvent t m, MonadIO (Performable m), MonadFix m)
   => P.CreateProcess -- ^ Specification of process to create
   -> ProcessConfig t (SendPipe ByteString) -- ^ Reflex-level configuration for the process
   -> m (Process t ByteString ByteString)
@@ -106,11 +106,12 @@
 --
 -- The @stdout@ and @stderr@ 'Handle's are line-buffered.
 --
--- For example, you may use 'Chan' for an unbounded buffer (like 'createProcess' does) like this:
+-- For example, you may use @Chan@ for an unbounded buffer (like 'createProcess' does) like this:
+--
 -- >  channel <- liftIO newChan
 -- >  createProcessBufferingInput (readChan channel) (writeChan channel) myConfig
 --
--- Similarly you could use 'TChan'.
+-- Similarly you could use @TChan@.
 --
 -- Bounded buffers may cause the Reflex network to block when you trigger an 'Event' that would
 -- cause more data to be sent to a process whose @stdin@ is blocked.
@@ -124,31 +125,32 @@
 -- provided 'CreateProcess' are replaced with new pipes and all output is redirected
 -- to those pipes.
 createProcessBufferingInput
-  :: (MonadIO m, TriggerEvent t m, PerformEvent t m, MonadIO (Performable m))
+  :: (MonadIO m, TriggerEvent t m, PerformEvent t m, MonadIO (Performable m), MonadFix m)
   => IO (SendPipe ByteString)
   -- ^ An action that reads a value from the input stream buffer.
-  -- This must block when the buffer is empty or not ready.
+  -- This will run in a separate thread and must block when the buffer is empty or not ready.
   -> (SendPipe ByteString -> IO ())
   -- ^ An action that writes a value to the input stream buffer.
   -> P.CreateProcess -- ^ Specification of process to create
   -> ProcessConfig t (SendPipe ByteString) -- ^ Reflex-level configuration for the process
   -> m (Process t ByteString ByteString)
-createProcessBufferingInput readBuffer writeBuffer = unsafeCreateProcessWithHandles input output output
+createProcessBufferingInput readBuffer writeBuffer spec config = do
+  rec p <- unsafeCreateProcessWithHandles (input $ _process_handle p) output output spec config
+  pure p
   where
-    input :: Handle -> IO (SendPipe ByteString -> IO ())
-    input h = do
+    input :: ProcessHandle -> Handle -> IO (SendPipe ByteString -> IO ())
+    input ph h = do
       H.hSetBuffering h H.NoBuffering
-      void $ liftIO $ async $ fix $ \loop -> do
+      void $ liftIO $ async $ race_ (waitForProcess ph) $ fix $ \loop -> do
         newMessage <- readBuffer
         open <- H.hIsOpen h
         when open $ do
           writable <- H.hIsWritable h
           when writable $ do
             case newMessage of
-              SendPipe_Message m -> BS.hPutStr h m
-              SendPipe_LastMessage m -> BS.hPutStr h m >> H.hClose h
+              SendPipe_Message m -> BS.hPutStr h m *> loop
+              SendPipe_LastMessage m -> BS.hPutStr h m *> H.hClose h
               SendPipe_EOF -> H.hClose h
-            loop
       return writeBuffer
     output h trigger = do
       H.hSetBuffering h H.LineBuffering
@@ -172,9 +174,11 @@
 unsafeCreateProcessWithHandles
   :: forall t m i o e. (MonadIO m, TriggerEvent t m, PerformEvent t m, MonadIO (Performable m))
   => (Handle -> IO (i -> IO ()))
-  -- ^ Builder for the standard input handler. The 'Handle' is the write end of the process' @stdin@ and
+  -- ^ Builder for the standard input handler.
+  -- This is provided so you can link any new threads to this one to avoid leaking threads.
+  -- The 'Handle' is the write end of the process' @stdin@ and
   -- the resulting @i -> IO ()@ is a function that writes each input 'Event t i' to into 'Handle'.
-  -- This functios must not block or the entire Reflex network will block.
+  -- This function must not block or the entire Reflex network will block.
   -> (Handle -> (o -> IO ()) -> IO (IO ()))
   -- ^ Builder for the standard output handler. The 'Handle' is the read end of the process' @stdout@ and
   -- the @o -> IO ()@ is a function that will trigger the output @Event t o@ when called. The resulting
@@ -193,8 +197,6 @@
   (hIn, hOut, hErr, ph) <- case po of
     (Just hIn, Just hOut, Just hErr, ph) -> pure (hIn, hOut, hErr, ph)
     _ -> error "Reflex.Process.unsafeCreateProcessWithHandles: Created pipes were not returned by System.Process.createProcess."
-  writeInput :: i -> IO () <- liftIO $ mkWriteStdInput hIn
-  performEvent_ $ liftIO . writeInput <$> input
   sigOut :: Event t (Maybe P.Signal) <- performEvent $ ffor signal $ \sig -> liftIO $ do
     mpid <- P.getPid ph
     for mpid $ \pid -> sig <$ P.signalProcess sig pid
@@ -220,6 +222,10 @@
     waited <- waitForProcess ph
     _ <- waitBoth outThread errThread
     ecTrigger waited -- Output events should never fire after process completion
+
+  writeInput :: i -> IO () <- liftIO $ mkWriteStdInput hIn
+  performEvent_ $ liftIO . writeInput <$> input
+
   return $ Process
     { _process_exit = ecOut
     , _process_stdout = out
