diff --git a/src/Web/Rep/Examples.hs b/src/Web/Rep/Examples.hs
--- a/src/Web/Rep/Examples.hs
+++ b/src/Web/Rep/Examples.hs
@@ -27,13 +27,13 @@
 where
 
 import qualified Clay
-import Control.Lens hiding ((.=))
 import Data.Attoparsec.Text
 import Data.Biapplicative
 import Data.Bool
 import Data.Text (Text, pack)
 import GHC.Generics
 import Lucid
+import Optics.Core
 import Text.InterpolatedString.Perl6
 import Web.Rep
 
diff --git a/src/Web/Rep/Html.hs b/src/Web/Rep/Html.hs
--- a/src/Web/Rep/Html.hs
+++ b/src/Web/Rep/Html.hs
@@ -38,7 +38,7 @@
 -- | Convert a link to a css library from text to html.
 --
 -- >>> libCss "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
--- <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
+-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
 libCss :: Text -> Html ()
 libCss url =
   link_
diff --git a/src/Web/Rep/Page.hs b/src/Web/Rep/Page.hs
--- a/src/Web/Rep/Page.hs
+++ b/src/Web/Rep/Page.hs
@@ -37,8 +37,6 @@
 
 import Clay (Css)
 import qualified Clay
-import Control.Lens
-import Data.Generics.Labels ()
 import Data.Text (Text, unpack)
 import Data.Text.Lazy (toStrict)
 import GHC.Generics
@@ -46,6 +44,7 @@
 import Language.JavaScript.Parser.AST
 import Language.JavaScript.Process.Minify
 import Lucid
+import Optics.Core
 import Text.InterpolatedString.Perl6
 
 -- | Components of a web page.
diff --git a/src/Web/Rep/Render.hs b/src/Web/Rep/Render.hs
--- a/src/Web/Rep/Render.hs
+++ b/src/Web/Rep/Render.hs
@@ -13,11 +13,11 @@
 where
 
 import Control.Applicative
-import Control.Lens
 import Control.Monad
 import Data.Foldable
 import Data.Text (Text, pack, unpack)
 import Lucid
+import Optics.Core
 import Web.Rep.Html
 import Web.Rep.Page
 
@@ -108,13 +108,13 @@
         Inline -> p ^. #libsCss
         Separated ->
           p ^. #libsCss
-            <> [libCss (pack $ pc ^. #filenames . #cssConcern)]
+            <> [libCss (pack $ pc ^. #filenames % #cssConcern)]
     libsJs' =
       case pc ^. #concerns of
         Inline -> p ^. #libsJs
         Separated ->
           p ^. #libsJs
-            <> [libJs (pack $ pc ^. #filenames . #jsConcern)]
+            <> [libJs (pack $ pc ^. #filenames % #jsConcern)]
 
 -- | Render Page concerns to files.
 renderPageToFile :: FilePath -> PageConfig -> Page -> IO ()
diff --git a/src/Web/Rep/Server.hs b/src/Web/Rep/Server.hs
--- a/src/Web/Rep/Server.hs
+++ b/src/Web/Rep/Server.hs
@@ -8,12 +8,12 @@
   )
 where
 
-import Control.Lens hiding (only)
 import Control.Monad
 import Control.Monad.Trans.Class
 import Data.Text (unpack)
 import Lucid
 import Network.Wai.Middleware.Static (addBase, noDots, only, staticPolicy)
+import Optics.Core hiding (only)
 import Web.Rep.Page
 import Web.Rep.Render
 import Web.Scotty
@@ -37,7 +37,7 @@
                     lift $ writeFile' jsfp (unpack js)
                     html $ renderText h
                 )
-    cssfp = pc ^. #filenames . #cssConcern
-    jsfp = pc ^. #filenames . #jsConcern
+    cssfp = pc ^. #filenames % #cssConcern
+    jsfp = pc ^. #filenames % #jsConcern
     writeFile' fp s = unless (s == mempty) (writeFile fp s)
     servedir = (\x -> middleware $ staticPolicy (noDots <> addBase x)) <$> pc ^. #localdirs
diff --git a/src/Web/Rep/Shared.hs b/src/Web/Rep/Shared.hs
--- a/src/Web/Rep/Shared.hs
+++ b/src/Web/Rep/Shared.hs
@@ -22,15 +22,15 @@
 where
 
 import Control.Applicative
-import Control.Lens
 import Control.Monad.IO.Class
 import Control.Monad.State.Lazy
 import Data.Biapplicative
-import Data.Generics.Labels ()
 import Data.HashMap.Strict (HashMap)
 import qualified Data.HashMap.Strict as HashMap
 import Data.Text (Text, pack)
 import Lucid
+import Optics.Core
+import Optics.Zoom
 
 -- |
 -- Information contained in a web page can usually be considered to be isomorphic to a map of named values - a 'HashMap'. This is especially true when considering a differential of information contained in a web page. Looking at a page from the outside, it often looks like a streaming differential of a hashmap.
diff --git a/src/Web/Rep/SharedReps.hs b/src/Web/Rep/SharedReps.hs
--- a/src/Web/Rep/SharedReps.hs
+++ b/src/Web/Rep/SharedReps.hs
@@ -39,8 +39,7 @@
   )
 where
 
-import Box.Cont ()
-import Control.Lens
+import Box.Codensity ()
 import Control.Monad
 import Control.Monad.State.Lazy
 import Data.Attoparsec.Text hiding (take)
@@ -51,6 +50,8 @@
 import qualified Data.List as List
 import Data.Text (Text, intercalate, pack, unpack)
 import Lucid
+import Optics.Core
+import Optics.Zoom
 import Text.InterpolatedString.Perl6
 import Web.Rep.Bootstrap
 import Web.Rep.Html
diff --git a/src/Web/Rep/Socket.hs b/src/Web/Rep/Socket.hs
--- a/src/Web/Rep/Socket.hs
+++ b/src/Web/Rep/Socket.hs
@@ -25,12 +25,12 @@
 
 import Box
 import Box.Socket
-import Control.Lens
 import Control.Monad
 import Control.Monad.Conc.Class as C
 import Control.Monad.State.Lazy
 import qualified Data.Attoparsec.Text as A
 import Data.Bifunctor
+import Data.Functor.Contravariant
 import Data.HashMap.Strict as HashMap
 import Data.Text (Text, pack)
 import qualified Data.Text as Text
@@ -38,6 +38,7 @@
 import Lucid as L
 import Network.Wai.Handler.WebSockets
 import qualified Network.WebSockets as WS
+import Optics.Core
 import Text.InterpolatedString.Perl6
 import Web.Rep.Bootstrap
 import Web.Rep.Html
@@ -65,7 +66,7 @@
 sharedServer :: SharedRep IO a -> SocketConfig -> Page -> (Html () -> [Code]) -> (Either Text a -> IO [Code]) -> IO ()
 sharedServer srep cfg p i o =
   serveSocketBox cfg p
-    <$.> fromAction (backendLoop srep i o . wrangle)
+    <$|> fromAction (backendLoop srep i o . wrangle)
 
 defaultSharedServer :: (Show a) => SharedRep IO a -> IO ()
 defaultSharedServer srep =
@@ -135,7 +136,11 @@
 wrangle (Box c e) = Box c' e'
   where
     c' = listC $ contramap code c
-    e' = mapE (pure . either (const Nothing) Just) (parseE parserJ e)
+    e' = witherE (pure . either (const Nothing) Just) (parseE parserJ e)
+
+-- | attoparsec parse emitter which returns the original text on failure
+parseE :: (Functor m) => A.Parser a -> Emitter m Text -> Emitter m (Either Text a)
+parseE parser e = (\t -> either (const $ Left t) Right (A.parseOnly parser t)) <$> e
 
 -- | {"event":{"element":"textid","value":"abcdees"}}
 parserJ :: A.Parser (Text, Text)
diff --git a/web-rep.cabal b/web-rep.cabal
--- a/web-rep.cabal
+++ b/web-rep.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               web-rep
-version:            0.8.0
+version:            0.9.0
 synopsis:           representations of a web page
 category:           web
 description:
@@ -12,7 +12,7 @@
 license-file:       LICENSE.md
 build-type:         Simple
 extra-source-files: ChangeLog.md
-tested-with:        GHC ==8.8.4 || ==8.10.4 || ==9.0.1 || ==9.2.0.20210821
+tested-with:        GHC ==8.8.4 || ==8.10.7 || ==9.2.1
 
 source-repository head
   type:     git
@@ -37,16 +37,16 @@
     , attoparsec                ^>=0.14
     , base                      >=4.12    && <5
     , bifunctors                ^>=5.5.11
-    , box                       ^>=0.7
-    , box-socket                ^>=0.2
+    , box                       ^>=0.8
+    , box-socket                ^>=0.3
     , clay                      ^>=0.13
     , concurrency               ^>=1.11
-    , generic-lens              ^>=2.2
     , interpolatedstring-perl6  ^>=1.0
     , language-javascript       >=0.6.0   && <0.8
-    , lens                      ^>=5.0
     , lucid                     ^>=2.9
     , mtl                       ^>=2.2.2
+    , optics-core               ^>=0.4
+    , optics-extra              ^>=0.4
     , scotty                    >=0.11.5  && <0.13
     , text                      ^>=1.2.3
     , transformers              ^>=0.5.6
