diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,6 @@
+Changelog
+=========
+
+1.1.0
+-----
+- Added Lenses and Traversals (no `lens` dependency)
diff --git a/Data/Versions.hs b/Data/Versions.hs
--- a/Data/Versions.hs
+++ b/Data/Versions.hs
@@ -2,7 +2,7 @@
 
 -- |
 -- Module    : Data.Versions
--- Copyright : (c) Colin Woodbury, 2015
+-- Copyright : (c) Colin Woodbury, 2015, 2016
 -- License   : BSD3
 -- Maintainer: Colin Woodbury <colingw@gmail.com>
 --
@@ -59,7 +59,25 @@
     , prettyV
     , prettySemVer
     , prettyVer
-    , prettyMess ) where
+    , prettyMess
+      -- * Lenses
+      -- ** Top-level Traversals
+    , _Versioning
+    , _Ideal
+    , _General
+    , _Complex
+      -- ** (Ideal) SemVer Lenses
+    , svMajor
+    , svMinor
+    , svPatch
+    , svPreRel
+    , svMeta
+      -- ** (General) Version Lenses
+    , vChunks
+    , vRel
+      -- ** Misc. Lenses / Traversals
+    , _Digits
+    , _Str ) where
 
 import Data.List (intersperse)
 import Data.Semigroup
@@ -75,6 +93,29 @@
 data Versioning = Ideal SemVer | General Version | Complex Mess
                 deriving (Eq,Show)
 
+-- | Traverse some Text for its inner versioning.
+--
+-- > _Versioning :: Traversal' Text Versioning
+--
+-- > ("1.2.3" & _Versioning . _Ideal . svPatch %~ (+ 1)) == "1.2.4"
+_Versioning :: Applicative f => (Versioning -> f Versioning) -> Text -> f Text
+_Versioning f t = either (const (pure t)) (fmap prettyV . f) $ parseV t
+
+-- | > _Ideal :: Traversal' Versioning SemVer
+_Ideal :: Applicative f => (SemVer -> f SemVer) -> Versioning -> f Versioning
+_Ideal f (Ideal s) = Ideal <$> f s
+_Ideal _ v = pure v
+
+-- | > _General :: Traversal' Versioning Version
+_General :: Applicative f => (Version -> f Version) -> Versioning -> f Versioning
+_General f (General v) = General <$> f v
+_General _ v = pure v
+
+-- | > _Complex :: Traversal' Versioning Mess
+_Complex :: Applicative f => (Mess -> f Mess) -> Versioning -> f Versioning
+_Complex f (Complex m) = Complex <$> f m
+_Complex _ v = pure v
+
 -- | Comparison of @Ideal@s is always well defined.
 --
 -- If comparison of @General@s is well-defined, then comparison
@@ -117,12 +158,32 @@
 -- 2. Build metadata does not affect version precedence.
 --
 -- For more information, see http://semver.org
-data SemVer = SemVer { svMajor  :: Int
-                     , svMinor  :: Int
-                     , svPatch  :: Int
-                     , svPreRel :: [VChunk]
-                     , svMeta   :: [VChunk] } deriving (Show)
+data SemVer = SemVer { _svMajor  :: Int
+                     , _svMinor  :: Int
+                     , _svPatch  :: Int
+                     , _svPreRel :: [VChunk]
+                     , _svMeta   :: [VChunk] } deriving (Show)
 
+-- | > svMajor :: Lens' SemVer Int
+svMajor :: Functor f => (Int -> f Int) -> SemVer -> f SemVer
+svMajor f sv = fmap (\ma -> sv { _svMajor = ma }) (f $ _svMajor sv)
+
+-- | > svMinor :: Lens' SemVer Int
+svMinor :: Functor f => (Int -> f Int) -> SemVer -> f SemVer
+svMinor f sv = fmap (\mi -> sv { _svMinor = mi }) (f $ _svMinor sv)
+
+-- | > svPatch :: Lens' SemVer Int
+svPatch :: Functor f => (Int -> f Int) -> SemVer -> f SemVer
+svPatch f sv = fmap (\pa -> sv { _svPatch = pa }) (f $ _svPatch sv)
+
+-- | > svPreRel :: Lens' SemVer Int
+svPreRel :: Functor f => ([VChunk] -> f [VChunk]) -> SemVer -> f SemVer
+svPreRel f sv = fmap (\pa -> sv { _svPreRel = pa }) (f $ _svPreRel sv)
+
+-- | > svMeta :: Lens' SemVer Int
+svMeta :: Functor f => ([VChunk] -> f [VChunk]) -> SemVer -> f SemVer
+svMeta f sv = fmap (\pa -> sv { _svMeta = pa }) (f $ _svMeta sv)
+
 -- | Two SemVers are equal if all fields except metadata are equal.
 instance Eq SemVer where
   (SemVer ma mi pa pr _) == (SemVer ma' mi' pa' pr' _) =
@@ -145,6 +206,16 @@
 -- by periods in the source.
 data VUnit = Digits Int | Str Text deriving (Eq,Show,Read,Ord)
 
+-- | > _Digits :: Traversal' VUnit Int
+_Digits :: Applicative f => (Int -> f Int) -> VUnit -> f VUnit
+_Digits f (Digits i) = Digits <$> f i
+_Digits _ v = pure v
+
+-- | > _Str :: Traversal' VUnit Text
+_Str :: Applicative f => (Text -> f Text) -> VUnit -> f VUnit
+_Str f (Str t) = Str <$> f t
+_Str _ v = pure v
+
 -- | A logical unit of a version number. Can consist of multiple letters
 -- and numbers.
 type VChunk = [VUnit]
@@ -155,8 +226,16 @@
 -- Generally conforms to the @x.x.x-x@ pattern.
 --
 -- Examples of @Version@ that are not @SemVer@: 0.25-2, 8.u51-1, 20150826-1
-data Version = Version { vChunks :: [VChunk]
-                       , vRel    :: [VChunk] } deriving (Eq,Ord,Show)
+data Version = Version { _vChunks :: [VChunk]
+                       , _vRel    :: [VChunk] } deriving (Eq,Ord,Show)
+
+-- | > vChunks :: Lens' Version [VChunk]
+vChunks :: Functor f => ([VChunk] -> f [VChunk]) -> Version -> f Version
+vChunks f v = fmap (\vc -> v { _vChunks = vc }) (f $ _vChunks v)
+
+-- | > vRel :: Lens' Version [VChunk]
+vRel :: Functor f => ([VChunk] -> f [VChunk]) -> Version -> f Version
+vRel f v = fmap (\vc -> v { _vRel = vc }) (f $ _vRel v)
 
 -- | A (Complex) Mess.
 -- This is a /descriptive/ parser, based on examples of stupidly
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -1,11 +1,12 @@
 {-# LANGUAGE OverloadedStrings #-}
 
-module Test where
+module Main where
 
 import Data.Either
 import Data.Monoid ((<>))
 import Data.Text (Text,unpack)
 import Data.Versions
+import Lens.Micro
 import Test.Tasty
 import Test.Tasty.HUnit
 
@@ -105,6 +106,11 @@
       , testCase "1.2-5 < 1.2.3-1"       $ comp parseV "1.2-5" "1.2.3-1"
       ]
     ]
+    , testGroup "Lenses and Traversals"
+      [ testCase "SemVer - Increment Patch" incPatch
+      , testCase "SemVer - Increment Patch from Text" incFromT
+      , testCase "Traverse `General` as `Ideal`" noInc
+      ]
   ]
 
 -- | Does pretty-printing return a Versioning to its original form?
@@ -140,6 +146,18 @@
 isMess (Complex _) = True
 isMess _ = False
 
+incPatch :: Assertion
+incPatch = (v1 & _Ideal . svPatch %~ (+ 1)) @?= v2
+  where v1 = Ideal $ SemVer 1 2 3 [] []
+        v2 = Ideal $ SemVer 1 2 4 [] []
+
+-- | Nothing should happen.
+noInc :: Assertion
+noInc = (v & _Ideal . svPatch %~ (+ 1)) @?= v
+  where v = General $ Version [] []
+
+incFromT :: Assertion
+incFromT = ("1.2.3" & _Versioning . _Ideal . svPatch %~ (+ 1)) @?= "1.2.4"
 
 {-}
 -- Need to submit patch for these, as well as Maybe instance.
diff --git a/versions.cabal b/versions.cabal
--- a/versions.cabal
+++ b/versions.cabal
@@ -1,5 +1,5 @@
 name:                versions
-version:             1.0.2
+version:             1.1.0
 synopsis:            Types and parsers for software version numbers.
 description:         A library for parsing and comparing software version numbers.
                      .
@@ -28,6 +28,8 @@
 build-type:          Simple
 cabal-version:       >=1.10
 
+extra-source-files:    CHANGELOG.md
+
 source-repository head
   type:     git
   location: git://github.com/fosskers/haskell-versions.git
@@ -36,6 +38,7 @@
   exposed-modules:     Data.Versions
 
   other-extensions:    OverloadedStrings
+
   build-depends:       base >=4.8 && <4.9
                      , parsec >=3.1 && <3.2
                      , semigroups >= 0.16.2.2
@@ -49,12 +52,10 @@
 
   build-depends:       base >=4.8 && <4.9
                      , either >= 4.4.1
-                     , extra >= 1.4.1
-                     , semigroups >= 0.16.2.2
+                     , microlens >= 0.4 && < 0.5
                      , tasty >= 0.10.1.2
                      , tasty-hunit >= 0.9.2
                      , text >=1.2 && <1.3
-                     , text-show >= 2
                      , versions
 
   hs-source-dirs:      test
