diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -157,10 +157,10 @@
 
 Here's the result:
 
-|           | encode 1 | encode 1000 | decode  |
-|-----------|----------|-------------|---------|
-| winery    | __0.28 μs__  | __0.26 ms__ | __0.81 ms__ |
-| cereal    | 0.82 μs  | 0.78 ms     | 0.90 ms |
-| binary    | 1.7 μs   | 1.7 ms      | 2.0 ms  |
-| serialise | 0.61 μs  | 0.50 ms     | 1.4 ms  |
-| aeson     | 9.9 μs   | 9.7 ms      | 17 ms   |
+|           | encode 1 | encode 1000 | decode  | length  |
+|-----------|----------|-------------|---------| ------- |
+| winery    | __0.28 μs__  | __0.26 ms__ | __0.81 ms__ | __58662__ |
+| cereal    | 0.82 μs  | 0.78 ms     | 0.90 ms | 91709  |
+| binary    | 1.7 μs   | 1.7 ms      | 2.0 ms  | 125709 |
+| serialise | 0.61 μs  | 0.50 ms     | 1.4 ms  | 65437  |
+| aeson     | 9.9 μs   | 9.7 ms      | 17 ms   | 160558 |
diff --git a/benchmarks/bench.hs b/benchmarks/bench.hs
--- a/benchmarks/bench.hs
+++ b/benchmarks/bench.hs
@@ -17,10 +17,8 @@
 data Gender = Male | Female deriving (Show, Generic)
 
 instance Serialise Gender where
-  schemaGen = gschemaGenVariant
-  toBuilder = gtoBuilderVariant
-  extractor = gextractorVariant
-  decodeCurrent = gdecodeCurrentVariant
+  bundleSerialise = bundleVariant id
+
 instance CBOR.Serialise Gender
 instance B.Binary Gender
 instance C.Serialize Gender
@@ -39,10 +37,7 @@
   } deriving (Show, Generic)
 
 instance Serialise TestRec where
-  schemaGen = gschemaGenRecord
-  toBuilder = gtoBuilderRecord
-  extractor = gextractorRecord Nothing
-  decodeCurrent = gdecodeCurrentRecord
+  bundleSerialise = bundleRecord id
 
 instance NFData TestRec where
   rnf TestRec{} = ()
diff --git a/src/Data/Winery.hs b/src/Data/Winery.hs
--- a/src/Data/Winery.hs
+++ b/src/Data/Winery.hs
@@ -98,6 +98,11 @@
   , gdecodeCurrentVariant
   , gextractorProduct
   , gdecodeCurrentProduct
+  -- * Bundles
+  , BundleSerialise(..)
+  , bundleRecord
+  , bundleRecordDefault
+  , bundleVariant
   -- * Preset schema
   , bootstrapSchema
   )where
@@ -204,9 +209,13 @@
 class Typeable a => Serialise a where
   -- | Obtain the schema of the datatype.
   schemaGen :: Proxy a -> SchemaGen Schema
+  schemaGen = bundleSchemaGen bundleSerialise
+  {-# INLINE schemaGen #-}
 
   -- | Serialise a value.
   toBuilder :: a -> BB.Builder
+  toBuilder = bundleToBuilder bundleSerialise
+  {-# INLINE toBuilder #-}
 
   -- | A value of 'Extractor a' interprets a schema and builds a function from
   -- 'Term' to @a@. This must be equivalent to 'decodeCurrent' when the schema
@@ -221,11 +230,68 @@
   -- where @d@ is equivalent to 'decodeCurrent'.
   --
   extractor :: Extractor a
+  extractor = bundleExtractor bundleSerialise
+  {-# INLINE extractor #-}
 
   -- | Decode a value with the current schema.
   --
   -- @'decodeCurrent' `evalDecoder` 'toBuilder' x@ ≡ x
   decodeCurrent :: Decoder a
+  decodeCurrent = bundleDecodeCurrent bundleSerialise
+  {-# INLINE decodeCurrent #-}
+
+  -- | Instead of the four methods above, you can supply a bundle.
+  bundleSerialise :: BundleSerialise a
+  bundleSerialise = BundleSerialise
+    { bundleSchemaGen = schemaGen
+    , bundleToBuilder = toBuilder
+    , bundleExtractor = extractor
+    , bundleDecodeCurrent = decodeCurrent
+    }
+
+  {-# MINIMAL schemaGen, toBuilder, extractor, decodeCurrent | bundleSerialise #-}
+
+-- | A bundle of 'Serialise' methods
+data BundleSerialise a = BundleSerialise
+  { bundleSchemaGen :: Proxy a -> SchemaGen Schema
+  , bundleToBuilder :: a -> BB.Builder
+  , bundleExtractor :: Extractor a
+  , bundleDecodeCurrent :: Decoder a
+  }
+
+bundleRecord :: (GEncodeProduct (Rep a), GSerialiseRecord (Rep a), Generic a, Typeable a)
+  => (Extractor a -> Extractor a) -- extractor modifier
+  -> BundleSerialise a
+bundleRecord f = BundleSerialise
+  { bundleSchemaGen = gschemaGenRecord
+  , bundleToBuilder = gtoBuilderRecord
+  , bundleExtractor = f $ gextractorRecord Nothing
+  , bundleDecodeCurrent = gdecodeCurrentRecord
+  }
+{-# INLINE bundleRecord #-}
+
+bundleRecordDefault :: (GEncodeProduct (Rep a), GSerialiseRecord (Rep a), Generic a, Typeable a)
+  => a -- default value
+  -> (Extractor a -> Extractor a) -- extractor modifier
+  -> BundleSerialise a
+bundleRecordDefault def f = BundleSerialise
+  { bundleSchemaGen = gschemaGenRecord
+  , bundleToBuilder = gtoBuilderRecord
+  , bundleExtractor = f $ gextractorRecord $ Just def
+  , bundleDecodeCurrent = gdecodeCurrentRecord
+  }
+{-# INLINE bundleRecordDefault #-}
+
+bundleVariant :: (GSerialiseVariant (Rep a), Generic a, Typeable a)
+  => (Extractor a -> Extractor a) -- extractor modifier
+  -> BundleSerialise a
+bundleVariant f = BundleSerialise
+  { bundleSchemaGen = gschemaGenVariant
+  , bundleToBuilder = gtoBuilderVariant
+  , bundleExtractor = f $ gextractorVariant
+  , bundleDecodeCurrent = gdecodeCurrentVariant
+  }
+{-# INLINE bundleVariant #-}
 
 -- | Check the integrity of a Serialise instance.
 --
diff --git a/winery.cabal b/winery.cabal
--- a/winery.cabal
+++ b/winery.cabal
@@ -1,7 +1,7 @@
 cabal-version: 1.12
 
 name:           winery
-version:        1
+version:        1.0.1
 synopsis:       Sustainable serialisation library
 description:    Please see the README on GitHub at <https://github.com/fumieval/winery#readme>
 category:       Data, Codec, Parsing, Serialization
