diff --git a/Data/Conduit/Extra.hs b/Data/Conduit/Extra.hs
--- a/Data/Conduit/Extra.hs
+++ b/Data/Conduit/Extra.hs
@@ -1,11 +1,13 @@
 module Data.Conduit.Extra
     ( module Data.Conduit.Extra.ZipSink
+    , module Data.Conduit.Extra.ZipConduit
     , module Data.Conduit.Extra.Resumable
     , fuseLeftovers
     , fuseReturnLeftovers
     ) where
 
 import Data.Conduit.Extra.ZipSink
+import Data.Conduit.Extra.ZipConduit
 import Data.Conduit.Extra.Resumable
 import Data.Conduit
 import Data.Conduit.Internal (Pipe (..), ConduitM (..))
diff --git a/Data/Conduit/Extra/ZipConduit.hs b/Data/Conduit/Extra/ZipConduit.hs
new file mode 100644
--- /dev/null
+++ b/Data/Conduit/Extra/ZipConduit.hs
@@ -0,0 +1,78 @@
+{-# LANGUAGE DeriveFunctor #-}
+module Data.Conduit.Extra.ZipConduit
+    ( ZipConduit (..)
+    , sequenceConduits
+    ) where
+
+import Data.Conduit
+import Data.Conduit.Internal (Pipe (..), ConduitM (..), injectLeftovers)
+import Data.Void (absurd)
+import Control.Monad (liftM)
+import Control.Applicative (Applicative (..))
+import Data.Traversable (Traversable, sequenceA)
+
+zipConduit :: Monad m
+           => ConduitM i o m (x -> y)
+           -> ConduitM i o m x
+           -> ConduitM i o m y
+zipConduit (ConduitM left0) (ConduitM right0) =
+    ConduitM $ go (return ()) (return ()) (injectLeftovers left0) (injectLeftovers right0)
+  where
+    go _ _ (Done f) (Done x) = Done (f x)
+    go _ finalY (HaveOutput x finalX o) y = HaveOutput
+        (go finalX finalY x y)
+        (finalX >> finalY)
+        o
+    go finalX _ x (HaveOutput y finalY o) = HaveOutput
+        (go finalX finalY x y)
+        (finalX >> finalY)
+        o
+    go _ _ (Leftover _ i) _ = absurd i
+    go _ _ _ (Leftover _ i) = absurd i
+    go finalX finalY (PipeM mx) y = PipeM (flip (go finalX finalY) y `liftM` mx)
+    go finalX finalY x (PipeM my) = PipeM (go finalX finalY x `liftM` my)
+    go finalX finalY (NeedInput px cx) (NeedInput py cy) = NeedInput
+        (\i -> go finalX finalY (px i) (py i))
+        (\u -> go finalX finalY (cx u) (cy u))
+    go finalX finalY (NeedInput px cx) (Done y) = NeedInput
+        (\i -> go finalX finalY (px i) (Done y))
+        (\u -> go finalX finalY (cx u) (Done y))
+    go finalX finalY (Done x) (NeedInput py cy) = NeedInput
+        (\i -> go finalX finalY (Done x) (py i))
+        (\u -> go finalX finalY (Done x) (cy u))
+
+-- | Provides an alternative @Applicative@ instance for @ConduitM@. In this instance,
+-- every incoming value is provided to all @ConduitM@s, and output is coalesced together.
+-- Leftovers from individual @ConduitM@s will be used within that component, and then discarded
+-- at the end of their computation. Output and finalizers will both be handled in a left-biased manner.
+--
+-- As an example, take the following program:
+--
+-- @
+-- main :: IO ()
+-- main = do
+--     let src = mapM_ yield [1..3 :: Int]
+--         conduit1 = CL.map (+1)
+--         conduit2 = CL.concatMap (replicate 2)
+--         conduit = getZipConduit $ ZipConduit conduit1 <* ZipConduit conduit2
+--         sink = CL.mapM_ print
+--     src $$ conduit =$ sink
+-- @
+--
+-- It will produce the output: 2, 1, 1, 3, 2, 2, 4, 3, 3
+--
+-- Since 0.1.5
+newtype ZipConduit i o m r = ZipConduit { getZipConduit :: ConduitM i o m r }
+    deriving Functor
+instance Monad m => Applicative (ZipConduit i o m) where
+    pure = ZipConduit . pure
+    ZipConduit left <*> ZipConduit right = ZipConduit (zipConduit left right)
+
+-- | Provide identical input to all of the @Conduit@s and combine their outputs
+-- into a single stream.
+--
+-- Implemented on top of @ZipConduit@, see that data type for more details.
+--
+-- Since 0.1.5
+sequenceConduits :: (Traversable f, Monad m) => f (ConduitM i o m r) -> ConduitM i o m (f r)
+sequenceConduits = getZipConduit . sequenceA . fmap ZipConduit
diff --git a/conduit-extra.cabal b/conduit-extra.cabal
--- a/conduit-extra.cabal
+++ b/conduit-extra.cabal
@@ -1,5 +1,5 @@
 Name:                conduit-extra
-Version:             0.1.4
+Version:             0.1.5
 Synopsis:            Experimental helper functions for conduit.
 Description:
     This package is meant as a testing ground for new concepts in conduit. The idea is to have a much lower barrier to entry for this library relative to conduit itself. This way, conduit itself will continue to have a best-practices, minimal, stable API, while people are free to try crazy new features.
@@ -17,6 +17,7 @@
                      , Data.Conduit.Extra.Pipes
                      , Data.Conduit.Extra.Resumable
                      , Data.Conduit.Extra.ZipSink
+                     , Data.Conduit.Extra.ZipConduit
                      , Data.Conduit.Extra.Utils
   Build-depends:       base                     >= 4            && < 5
                      , conduit                  >= 1.0
diff --git a/test/main.hs b/test/main.hs
--- a/test/main.hs
+++ b/test/main.hs
@@ -13,6 +13,7 @@
 import qualified Data.Conduit.Extra as CE
 import Data.Conduit (runResourceT)
 import qualified Data.Conduit.ExtraSpec as ES
+import qualified Data.Conduit.Extra.ZipConduitSpec as ZipConduit
 
 
 main :: IO ()
@@ -33,3 +34,4 @@
             x `shouldBe` (505000 :: Integer)
 
     ES.spec
+    ZipConduit.spec
