diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
 # Change Log
 
+## [v1.3.1]() (2015-04-30)
+
+**API Changes**
+
+  - Type of `SVGOptions` changed. `_svgDefinitions :: Maybe SvgM`
+
+**Internal Changes**
+
+  - Use `ReaderT` for styles
+
 ## [v1.3](https://github.com/diagrams/diagrams-svg/tree/v1.3) (2015-04-19)
 
 [Full Changelog](https://github.com/diagrams/diagrams-svg/compare/v1.1.0.4...v1.1.0.5)
diff --git a/diagrams-svg.cabal b/diagrams-svg.cabal
--- a/diagrams-svg.cabal
+++ b/diagrams-svg.cabal
@@ -1,5 +1,5 @@
 Name:                diagrams-svg
-Version:             1.3
+Version:             1.3.1
 Synopsis:            SVG backend for diagrams drawing EDSL.
 Homepage:            http://projects.haskell.org/diagrams/
 License:             BSD3
diff --git a/src/Diagrams/Backend/SVG.hs b/src/Diagrams/Backend/SVG.hs
--- a/src/Diagrams/Backend/SVG.hs
+++ b/src/Diagrams/Backend/SVG.hs
@@ -58,7 +58,7 @@
 --
 -- > data Options SVG V2 n = SVGOptions
 -- >     { _size           :: SizeSpec V2 n   -- ^ The requested size.
--- >     , _svgDefinitions :: [Attribute]
+-- >     , _svgDefinitions :: Maybe SvgM
 -- >                           -- ^ Custom definitions that will be added to the @defs@
 -- >                           --   section of the output.
 -- >     , _idPrefix       :: T.Text
@@ -79,7 +79,7 @@
 -- @
 --
 -- which you could call like @renderDia SVG (SVGOptions (mkWidth 250)
--- [] "") myDiagram@ (if you have the 'OverloadedStrings' extension
+-- Nothing "") myDiagram@ (if you have the 'OverloadedStrings' extension
 -- enabled; otherwise you can use 'Text.pack ""').  (In some
 -- situations GHC may not be able to infer the type @m@, in which case
 -- you can use a type annotation to specify it; it may be useful to
@@ -116,12 +116,13 @@
 import           System.FilePath
 
 -- from base
+import           Control.Monad.Reader
 import           Control.Monad.State
 import           Data.Char
 import           Data.Typeable
 
 -- from hashable
-import           Data.Hashable            (Hashable (..))
+import           Data.Hashable            (Hashable (), hashWithSalt)
 
 -- from bytestring
 import qualified Data.ByteString          as SBS
@@ -135,7 +136,7 @@
 import           Diagrams.Core.Types      (Annotation (..))
 
 -- from diagrams-lib
-import           Diagrams.Prelude         hiding (Attribute, size, view)
+import           Diagrams.Prelude         hiding (Attribute, size, view, local)
 import           Diagrams.TwoD.Adjust     (adjustDia2D)
 import           Diagrams.TwoD.Attributes (splitTextureFills)
 import           Diagrams.TwoD.Path       (Clip (Clip))
@@ -158,25 +159,35 @@
 type instance V SVG = V2
 type instance N SVG = Double
 
-data SvgRenderState n = SvgRenderState
+data Environment n = Environment
+  { _style :: Style V2 n
+  , __pre :: T.Text
+  }
+
+makeLenses ''Environment
+
+data SvgRenderState = SvgRenderState
   { _clipPathId :: Int
   , _fillGradId :: Int
   , _lineGradId :: Int
-  , _style      :: Style V2 n
-  , __pre       :: T.Text
   }
 
 makeLenses ''SvgRenderState
 
+initialEnvironment :: SVGFloat n => T.Text -> Environment n
+initialEnvironment = Environment (mempty # recommendFillColor transparent)
+
 -- Fill gradients ids are even, line gradient ids are odd.
-initialSvgRenderState :: SVGFloat n => T.Text -> SvgRenderState n
-initialSvgRenderState = SvgRenderState 0 0 1 (mempty # recommendFillColor transparent)
+initialSvgRenderState :: SvgRenderState
+initialSvgRenderState = SvgRenderState 0 0 1
 
--- | Monad to keep track of state when rendering an SVG.
---   Currently just keeps a monotonically increasing counter
---   for assiging a unique clip path ID.
-type SvgRenderM n = State (SvgRenderState n) SvgM
+-- | Monad to keep track of environment and state when rendering an SVG.
+type SvgRenderM n = ReaderT (Environment n) (State SvgRenderState) SvgM
 
+runRenderM :: SVGFloat n => T.Text -> SvgRenderM n -> SvgM
+runRenderM o s = flip evalState initialSvgRenderState
+               $ runReaderT  s (initialEnvironment o)
+
 instance SVGFloat n => Monoid (Render SVG V2 n) where
   mempty = R $ return mempty
   R r1 `mappend` R r2_ = R $ do
@@ -190,7 +201,7 @@
                       => T.Text
                       -> SvgM          -- ^ Input SVG
                       -> Style V2 n    -- ^ Styles
-                      -> SvgRenderM n    -- ^ Resulting svg
+                      -> SvgRenderM n  -- ^ Resulting svg
 
 renderSvgWithClipping prefix svg s =
   case op Clip <$> getAttr s of
@@ -219,17 +230,17 @@
   return $ R.renderLineTextureDefs ident s
 
 instance SVGFloat n => Backend SVG V2 n where
-  data Render  SVG V2 n = R (SvgRenderM n)
-  type Result  SVG V2 n = SvgM
-  data Options SVG V2 n = SVGOptions
+  newtype Render  SVG V2 n = R (SvgRenderM n)
+  type    Result  SVG V2 n = SvgM
+  data    Options SVG V2 n = SVGOptions
     { _size           :: SizeSpec V2 n   -- ^ The requested size.
-    , _svgDefinitions :: [Attribute]
+    , _svgDefinitions :: Maybe SvgM
                           -- ^ Custom definitions that will be added to the @defs@
                           --   section of the output.
     , _idPrefix       :: T.Text
     }
 
-  renderRTree _ opts rt = evalState svgOutput (initialSvgRenderState $ opts ^.idPrefix)
+  renderRTree _ opts rt = runRenderM (opts ^.idPrefix) svgOutput
     where
       svgOutput = do
         let R r    = rtree (splitTextureFills rt)
@@ -242,11 +253,7 @@
 rtree :: SVGFloat n => RTree SVG V2 n Annotation -> Render SVG V2 n
 rtree (Node n rs) = case n of
   RPrim p                 -> render SVG p
-  RStyle sty'             -> R $ do
-    -- mappend new state and retrieve old state
-    sty <- style <<<>= sty'
-    -- render contents and return state to old state
-    r <* (style .= sty)
+  RStyle sty              -> R $ local (over style (<> sty)) r
   RAnnot (OpacityGroup o) -> R $ g_ [opacity_ $ toText o] <$> r
   RAnnot (Href uri)       -> R $ a_ [xlinkHref_ $ toText uri] <$> r
   _                       -> R r
@@ -258,7 +265,7 @@
 sizeSpec f opts = f (_size opts) <&> \s -> opts { _size = s }
 
 -- | Lens onto the svg definitions of the svg options.
-svgDefinitions :: SVGFloat n => Lens' (Options SVG V2 n) [Attribute]
+svgDefinitions :: SVGFloat n => Lens' (Options SVG V2 n) (Maybe SvgM)
 svgDefinitions f opts =
   f (_svgDefinitions opts) <&> \ds -> opts { _svgDefinitions = ds }
 
@@ -272,7 +279,8 @@
 
 attributedRender :: SVGFloat n => SvgM -> SvgRenderM n
 attributedRender svg = do
-  SvgRenderState _idClip idFill idLine sty preT <- get
+  SvgRenderState _idClip idFill idLine <- get
+  Environment sty preT <- ask
   clippedSvg   <- renderSvgWithClipping preT svg sty
   lineGradDefs <- lineTextureDefs sty
   fillGradDefs <- fillTextureDefs sty
@@ -289,16 +297,14 @@
 instance SVGFloat n => Renderable (DImage n Embedded) SVG where
   render _ = R . return . R.renderDImageEmb
 
--- TODO: instance Renderable Image SVG where
-
 -- | Render a diagram as an SVG, writing to the specified output file
 --   and using the requested size.
 renderSVG :: SVGFloat n => FilePath -> SizeSpec V2 n -> QDiagram SVG V2 n Any -> IO ()
-renderSVG outFile spec = renderSVG' outFile (SVGOptions spec [] (mkPrefix outFile))
+renderSVG outFile spec = renderSVG' outFile (SVGOptions spec Nothing (mkPrefix outFile))
 
 -- | Render a diagram as a pretty printed SVG.
 renderPretty :: SVGFloat n => FilePath -> SizeSpec V2 n -> QDiagram SVG V2 n Any -> IO ()
-renderPretty outFile spec = renderPretty' outFile (SVGOptions spec [] (mkPrefix outFile))
+renderPretty outFile spec = renderPretty' outFile (SVGOptions spec Nothing (mkPrefix outFile))
 
 -- Create a prefile using the basename of the output file. Only standard
 -- letters are considered.
@@ -349,4 +355,5 @@
     return $ R.renderDImage di $ R.dataUri mime d
 
 instance (Hashable n, SVGFloat n) => Hashable (Options SVG V2 n) where
-  hashWithSalt s  (SVGOptions sz defs _) = s `hashWithSalt` sz `hashWithSalt` defs
+  hashWithSalt s  (SVGOptions sz defs _) = s `hashWithSalt` sz `hashWithSalt` ds
+    where ds = fmap renderBS defs
diff --git a/src/Graphics/Rendering/SVG.hs b/src/Graphics/Rendering/SVG.hs
--- a/src/Graphics/Rendering/SVG.hs
+++ b/src/Graphics/Rendering/SVG.hs
@@ -42,6 +42,8 @@
 #if __GLASGOW_HASKELL__ < 710
 import           Data.Foldable               (foldMap)
 #endif
+
+import           Data.Maybe                  (fromMaybe)
 import           Data.Monoid
 
 -- from diagrams-core
@@ -84,14 +86,16 @@
 
 -- | @svgHeader w h defs s@: @w@ width, @h@ height,
 --   @defs@ global definitions for defs sections, @s@ actual SVG content.
-svgHeader :: SVGFloat n => n -> n -> [Attribute] -> SvgM -> SvgM
-svgHeader w h defines s =  doctype_ <> with (svg11_ (g_  defines s))
+svgHeader :: SVGFloat n => n -> n -> Maybe SvgM -> SvgM -> SvgM
+svgHeader w h defines s =  doctype_ <> with (svg11_ (defs_  ds <> s))
   [ width_  (toText w)
   , height_ (toText h)
   , font_size_ "1"
   , viewBox_ (pack . unwords $ map show ([0, 0, round w, round h] :: [Int]))
   , stroke_ "rgb(0,0,0)"
   , stroke_opacity_ "1" ]
+  where
+    ds = fromMaybe mempty defines
 
 renderPath :: SVGFloat n => Path V2 n -> SvgM
 renderPath trs = if makePath == T.empty then mempty else path_ [d_ makePath]
