diff --git a/quasar.cabal b/quasar.cabal
index 8e62dac7fbafdb385a4183d403bd958ca10b4155..3ecf818d26541c5e7693385a93562ba635e2bf40 100644
--- a/quasar.cabal
+++ b/quasar.cabal
@@ -85,6 +85,7 @@ library
     unordered-containers,
   exposed-modules:
     Quasar
+    Quasar.Async.Fork
     Quasar.Async.STMHelper
     Quasar.Async.V2
     Quasar.Awaitable
diff --git a/src/Quasar/Async/Fork.hs b/src/Quasar/Async/Fork.hs
new file mode 100644
index 0000000000000000000000000000000000000000..311f1cc9ed12afdc1218811cec74f0f597c76561
--- /dev/null
+++ b/src/Quasar/Async/Fork.hs
@@ -0,0 +1,51 @@
+module Quasar.Async.Fork (
+  -- * Forking with an asynchronous exception channel
+  -- ** STM
+  fork,
+  fork_,
+  forkWithUnmask,
+  forkWithUnmask_,
+
+  -- ** ShortIO
+  forkWithUnmaskShortIO,
+  forkWithUnmaskShortIO_,
+) where
+
+import Control.Concurrent (ThreadId)
+import Control.Concurrent.STM
+import Control.Monad.Catch
+import Quasar.Async.STMHelper
+import Quasar.Awaitable
+import Quasar.Exceptions
+import Quasar.Prelude
+import Quasar.Utils.ShortIO
+
+
+-- * Fork in STM (with ExceptionChannel)
+
+fork :: IO () -> TIOWorker -> ExceptionChannel -> STM (Awaitable ThreadId)
+fork fn = forkWithUnmask (\unmask -> unmask fn)
+
+fork_ :: IO () -> TIOWorker -> ExceptionChannel -> STM ()
+fork_ fn worker exChan = void $ fork fn worker exChan
+
+
+forkWithUnmask :: ((forall a. IO a -> IO a) -> IO ()) -> TIOWorker -> ExceptionChannel -> STM (Awaitable ThreadId)
+forkWithUnmask fn worker exChan = startShortIO (forkWithUnmaskShortIO fn exChan) worker exChan
+
+forkWithUnmask_ :: ((forall a. IO a -> IO a) -> IO ()) -> TIOWorker -> ExceptionChannel -> STM ()
+forkWithUnmask_ fn worker exChan = void $ forkWithUnmask fn worker exChan
+
+
+-- * Fork in ShortIO (with ExceptionChannel)
+
+forkWithUnmaskShortIO :: ((forall a. IO a -> IO a) -> IO ()) -> ExceptionChannel -> ShortIO ThreadId
+forkWithUnmaskShortIO fn exChan = forkFn
+  where
+    forkFn :: ShortIO ThreadId
+    forkFn = mask_ $ forkIOWithUnmaskShortIO wrappedFn
+    wrappedFn :: (forall a. IO a -> IO a) -> IO ()
+    wrappedFn unmask = fn unmask `catchAll` \ex -> atomically (throwToExceptionChannel exChan ex)
+
+forkWithUnmaskShortIO_ :: ((forall a. IO a -> IO a) -> IO ()) -> ExceptionChannel -> ShortIO ()
+forkWithUnmaskShortIO_ fn exChan = void $ forkWithUnmaskShortIO fn exChan
diff --git a/src/Quasar/Async/STMHelper.hs b/src/Quasar/Async/STMHelper.hs
index 6e38644998e4e952771685aa116ef437a923a521..3b92b1994f02a320f34f47819aa3d3176a38994e 100644
--- a/src/Quasar/Async/STMHelper.hs
+++ b/src/Quasar/Async/STMHelper.hs
@@ -1,15 +1,12 @@
 module Quasar.Async.STMHelper (
+  -- * Helper to fork from STM
   TIOWorker,
   newTIOWorker,
   startShortIO,
   startShortIO_,
-  fork,
-  fork_,
-  forkWithUnmask,
-  forkWithUnmask_,
 ) where
 
-import Control.Concurrent (ThreadId, forkIO)
+import Control.Concurrent (forkIO)
 import Control.Concurrent.STM
 import Control.Exception (BlockedIndefinitelyOnSTM)
 import Control.Monad.Catch
@@ -50,22 +47,3 @@ newTIOWorker = do
       (\(_ :: BlockedIndefinitelyOnSTM) -> pure ())
 
   pure $ TIOWorker jobQueue
-
-
-fork :: IO () -> TIOWorker -> ExceptionChannel -> STM (Awaitable ThreadId)
-fork fn = forkWithUnmask (\unmask -> unmask fn)
-
-fork_ :: IO () -> TIOWorker -> ExceptionChannel -> STM ()
-fork_ fn worker exChan = void $ fork fn worker exChan
-
-
-forkWithUnmask :: ((forall a. IO a -> IO a) -> IO ()) -> TIOWorker -> ExceptionChannel -> STM (Awaitable ThreadId)
-forkWithUnmask fn worker exChan = startShortIO forkFn worker exChan
-  where
-    forkFn :: ShortIO ThreadId
-    forkFn = mask_ $ forkIOWithUnmaskShortIO wrappedFn
-    wrappedFn :: (forall a. IO a -> IO a) -> IO ()
-    wrappedFn unmask = fn unmask `catchAll` \ex -> atomically (throwToExceptionChannel exChan ex)
-
-forkWithUnmask_ :: ((forall a. IO a -> IO a) -> IO ()) -> TIOWorker -> ExceptionChannel -> STM ()
-forkWithUnmask_ fn worker exChan = void $ forkWithUnmask fn worker exChan
diff --git a/src/Quasar/Async/V2.hs b/src/Quasar/Async/V2.hs
index f1ba3d86f2cd0cc1fc7d600d364d34d83fb7704d..8b66c934eb8722537f8e2890c26252357cc7e270 100644
--- a/src/Quasar/Async/V2.hs
+++ b/src/Quasar/Async/V2.hs
@@ -18,6 +18,7 @@ module Quasar.Async.V2 (
 import Control.Concurrent (ThreadId)
 import Control.Concurrent.STM
 import Control.Monad.Catch
+import Quasar.Async.Fork
 import Quasar.Async.STMHelper
 import Quasar.Awaitable
 import Quasar.Exceptions