diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+## 1.3.1
+
+* Added `bundleVia`, deprecating `bundleRecord` and `bundleVariant`
+
 ## 1.3
 
 * Fixed an incorrect behaviour of `extractConstructor`
diff --git a/benchmarks/bench.hs b/benchmarks/bench.hs
--- a/benchmarks/bench.hs
+++ b/benchmarks/bench.hs
@@ -27,7 +27,7 @@
 data Gender = Male | Female deriving (Show, Generic)
 
 instance Serialise Gender where
-  bundleSerialise = bundleVariant id
+  bundleSerialise = bundleVia WineryVariant
 
 instance CBOR.Serialise Gender
 instance B.Binary Gender
@@ -48,7 +48,7 @@
   } deriving (Show, Generic)
 
 instance Serialise TestRec where
-  bundleSerialise = bundleRecord id
+  bundleSerialise = bundleVia WineryRecord
 
 instance NFData TestRec where
   rnf TestRec{} = ()
diff --git a/src/Codec/Winery.hs b/src/Codec/Winery.hs
--- a/src/Codec/Winery.hs
+++ b/src/Codec/Winery.hs
@@ -102,6 +102,7 @@
   , bundleRecord
   , bundleRecordDefault
   , bundleVariant
+  , bundleVia
   -- * Preset schema
   , bootstrapSchema
   ) where
@@ -113,6 +114,7 @@
 import Control.Exception (throw, throwIO)
 import qualified Data.ByteString as B
 import qualified Data.ByteString.FastBuilder as BB
+import Data.Coerce
 import Data.Function (fix)
 import qualified Data.Text as T
 import Data.Typeable
@@ -421,3 +423,12 @@
   toBuilder = gtoBuilderProduct
   extractor = gextractorProduct
   decodeCurrent = gdecodeCurrentProduct
+
+bundleVia :: forall a t. (Coercible a t, Serialise t) => (a -> t) -> BundleSerialise a
+bundleVia _ = BundleSerialise
+  { bundleSchemaGen = coerce (schemaGen @t)
+  , bundleToBuilder = coerce (toBuilder @t)
+  , bundleExtractor = coerce (extractor @t)
+  , bundleDecodeCurrent = coerce (decodeCurrent @t)
+  }
+{-# INLINE bundleVia #-}
diff --git a/src/Codec/Winery/Class.hs b/src/Codec/Winery/Class.hs
--- a/src/Codec/Winery/Class.hs
+++ b/src/Codec/Winery/Class.hs
@@ -168,6 +168,7 @@
   , bundleDecodeCurrent = gdecodeCurrentRecord
   }
 {-# INLINE bundleRecord #-}
+{-# DEPRECATED bundleRecord "Use bundleVia instead" #-}
 
 -- | A bundle of generic implementations for records, with a default value
 bundleRecordDefault :: (GEncodeProduct (Rep a), GSerialiseRecord (Rep a), GDecodeProduct (Rep a), Generic a, Typeable a)
@@ -181,6 +182,7 @@
   , bundleDecodeCurrent = gdecodeCurrentRecord
   }
 {-# INLINE bundleRecordDefault #-}
+{-# DEPRECATED bundleRecordDefault "Use bundleVia instead" #-}
 
 -- | A bundle of generic implementations for variants
 bundleVariant :: (GSerialiseVariant (Rep a), GConstructorCount (Rep a), GEncodeVariant (Rep a), GDecodeVariant (Rep a), Generic a, Typeable a)
@@ -193,6 +195,7 @@
   , bundleDecodeCurrent = gdecodeCurrentVariant
   }
 {-# INLINE bundleVariant #-}
+{-# DEPRECATED bundleVariant "Use bundleVia instead" #-}
 
 -- | Obtain a schema on 'SchemaGen', binding a fixpoint when necessary.
 -- If you are hand-rolling a definition of 'schemaGen', you should call this
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -81,14 +81,14 @@
   arbitrary = TRec <$> arbitrary <*> arbitrary
 
 instance Serialise TRec where
-  bundleSerialise = bundleRecord id
+  bundleSerialise = bundleVia WineryRecord
 
 prop_TRec = testSerialise @ TRec
 
 data TList a = TCons a (TList a) | TNil deriving (Show, Eq, Generic)
 
 instance Serialise a => Serialise (TList a) where
-  bundleSerialise = bundleVariant id
+  bundleSerialise = bundleVia WineryVariant
 
 instance Arbitrary a => Arbitrary (TList a) where
   arbitrary = sized $ \n -> if n <= 0
@@ -117,13 +117,15 @@
     Node <$> resize leftSize arbitrary <*> arbitrary <*> resize rightSize arbitrary
 
 instance Serialise Tree where
-  bundleSerialise = bundleVariant id
+  bundleSerialise = bundleVia WineryVariant
 
 instance Serialise Node where
-  bundleSerialise = bundleRecord $ const $ buildExtractor $ Node
-    <$> (extractField "left" <|> extractField "leftChild")
-    <*> extractField "value"
-    <*> (extractField "right" <|> extractField "rightChild")
+  bundleSerialise = (bundleVia WineryRecord)
+    { bundleExtractor = buildExtractor $ Node
+      <$> (extractField "left" <|> extractField "leftChild")
+      <*> extractField "value"
+      <*> (extractField "right" <|> extractField "rightChild")
+    }
 
 prop_tree = testSerialise @ Tree
 prop_node = testSerialise @ Node
@@ -134,7 +136,7 @@
   arbitrary = toEnum <$> Gen.choose (0, 6)
 
 instance Serialise Foo where
-  bundleSerialise = bundleVariant id
+  bundleSerialise = bundleVia WineryVariant
 
 prop_Foo = testSerialise @ Foo
 
@@ -144,7 +146,7 @@
   arbitrary = toEnum <$> Gen.choose (0, 2)
 
 instance Serialise Soup where
-  bundleSerialise = bundleVariant id
+  bundleSerialise = bundleVia WineryVariant
 
 data Food = Rice | Ramen Soup | Pasta Text Text deriving (Generic, Eq, Show)
 
@@ -158,7 +160,8 @@
     ]
 
 instance Serialise Food where
-  bundleSerialise = bundleVariant $ const $ buildExtractor
+  bundleSerialise = bundleVia WineryVariant
+  extractor = buildExtractor
     $ ("Rice", \() -> Rice)
     `extractConstructor` ("Ramen", Ramen)
     `extractConstructor` ("Pasta", uncurry Pasta)
diff --git a/winery.cabal b/winery.cabal
--- a/winery.cabal
+++ b/winery.cabal
@@ -1,6 +1,6 @@
 cabal-version:  2.0
 name:           winery
-version:        1.3
+version:        1.3.1
 synopsis:       A compact, well-typed seralisation format for Haskell values
 description:
   <<https://i.imgur.com/lTosHnE.png>>
