diff --git a/CONTRIBUTORS b/CONTRIBUTORS
new file mode 100644
--- /dev/null
+++ b/CONTRIBUTORS
@@ -0,0 +1,1 @@
+Robin Banks <anarchomorphism@seomraspraoi.org>
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,2 @@
+may the last IP lawyer be hung
+with the guts of the last cop
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/monad-fork.cabal b/monad-fork.cabal
new file mode 100644
--- /dev/null
+++ b/monad-fork.cabal
@@ -0,0 +1,29 @@
+name:           monad-fork
+version:        0.1
+synopsis:       Type class for monads which support a fork operation.
+license:        PublicDomain
+license-file:   LICENSE
+author:         Robin Banks
+maintainer:     anarchomorphism@seomraspraoi.org
+stability:      Experimental
+category:       Control
+cabal-version:  >= 1.6
+build-type:     Simple
+
+extra-source-files:
+  CONTRIBUTORS
+
+Library
+  hs-source-dirs:
+    src
+
+  exposed-modules:
+    Control.Monad.Fork.Class
+
+  build-depends:
+    base > 4 && < 5,
+    monad-control > 0.3 && < 0.4
+
+source-repository head
+  type:     git
+  location: git://git.seomraspraoi.org/monad-fork.git
diff --git a/src/Control/Monad/Fork/Class.hs b/src/Control/Monad/Fork/Class.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Fork/Class.hs
@@ -0,0 +1,49 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverlappingInstances #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module Control.Monad.Fork.Class
+    ( MonadFork (..)
+    )
+where
+
+import           Control.Concurrent (ThreadId, forkIO)
+import           Control.Monad (liftM)
+import           Control.Monad.Trans.Control
+                     ( MonadBaseControl
+                     , MonadTransControl
+                     , liftBaseDiscard
+                     , liftWith
+                     )
+
+------------------------------------------------------------------------------
+-- | The 'MonadFork' type class, for monads which support a fork operation.
+--
+-- The instance for 'IO' is simply 'forkIO', while several very overlapping
+-- instances are provided for composite monads, using the monad-control
+-- package.
+--
+-- An example of a monad which has a 'MonadFork' instance that is not simply
+-- a lifted form of 'forkIO' is the @ResourceT@ monad from the conduit
+-- package, which defines the operation @resourceForkIO@. The instances
+-- defined here, using the OverlappingInstances extension, will correctly
+-- handle the case of monads transformed on top of @ResourceT@ (assuming a
+-- definition exists for @ResourceT@).
+class MonadFork m where
+    fork :: m () -> m ThreadId
+
+
+------------------------------------------------------------------------------
+instance MonadFork IO where
+    fork = forkIO
+
+
+------------------------------------------------------------------------------
+instance (MonadFork b, MonadBaseControl b m) => MonadFork m where
+    fork = liftBaseDiscard fork
+
+
+------------------------------------------------------------------------------
+instance (MonadTransControl t, MonadFork m, Monad m) => MonadFork (t m) where
+    fork m = liftWith $ \run -> fork $ liftM (const ()) $ run m
