diff --git a/LICENCE b/LICENCE
new file mode 100644
--- /dev/null
+++ b/LICENCE
@@ -0,0 +1,27 @@
+Copyright 2024 Tony Morris
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+import Distribution.Simple
+main = defaultMain
+
diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,3 @@
+0.0.1
+
+* This change log starts
diff --git a/src/Data/Stringz.hs b/src/Data/Stringz.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Stringz.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall #-}
+
+module Data.Stringz(
+  module S
+) where
+
+import Data.Stringz.ByteString as S
+import Data.Stringz.String as S
+import Data.Stringz.Text as S
diff --git a/src/Data/Stringz/ByteString.hs b/src/Data/Stringz/ByteString.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Stringz/ByteString.hs
@@ -0,0 +1,146 @@
+{-# OPTIONS_GHC -Wall #-}
+{-# LANGUAGE FlexibleInstances #-}
+
+module Data.Stringz.ByteString where
+
+import Control.Lens
+import qualified Data.ByteString.Char8 as ByteStringChar8
+import qualified Data.ByteString.Lazy.Char8 as ByteStringLazyChar8
+import qualified Data.Text as Text
+import qualified Data.Text.Lazy as LazyText
+
+class HasByteString a where
+  byteString ::
+    Lens' a ByteStringChar8.ByteString
+
+instance HasByteString [Char] where
+  byteString =
+    iso
+      ByteStringChar8.pack
+      ByteStringChar8.unpack
+
+instance HasByteString Text.Text where
+  byteString =
+    iso Text.unpack Text.pack . iso ByteStringChar8.pack ByteStringChar8.unpack
+
+instance HasByteString LazyText.Text where
+  byteString =
+    iso LazyText.unpack LazyText.pack . iso ByteStringChar8.pack ByteStringChar8.unpack
+
+instance HasByteString ByteStringChar8.ByteString where
+  byteString =
+    id
+
+instance HasByteString ByteStringLazyChar8.ByteString where
+  byteString =
+    iso ByteStringLazyChar8.toStrict ByteStringLazyChar8.fromStrict
+
+instance HasByteString a => HasByteString (Identity a) where
+  byteString =
+    iso runIdentity Identity . byteString
+
+instance HasByteString a => HasByteString (Const a b) where
+  byteString =
+    iso getConst Const . byteString
+
+class HasLazyByteString a where
+  lazyByteString ::
+    Lens' a ByteStringLazyChar8.ByteString
+
+instance HasLazyByteString [Char] where
+  lazyByteString =
+    iso
+      ByteStringLazyChar8.pack
+      ByteStringLazyChar8.unpack
+
+instance HasLazyByteString Text.Text where
+  lazyByteString =
+    iso Text.unpack Text.pack . iso ByteStringLazyChar8.pack ByteStringLazyChar8.unpack
+
+instance HasLazyByteString LazyText.Text where
+  lazyByteString =
+    iso LazyText.unpack LazyText.pack . iso ByteStringLazyChar8.pack ByteStringLazyChar8.unpack
+
+instance HasLazyByteString ByteStringChar8.ByteString where
+  lazyByteString =
+    iso ByteStringChar8.fromStrict ByteStringChar8.toStrict
+
+instance HasLazyByteString ByteStringLazyChar8.ByteString where
+  lazyByteString =
+    id
+
+instance HasLazyByteString a => HasLazyByteString (Identity a) where
+  lazyByteString =
+    iso runIdentity Identity . lazyByteString
+
+instance HasLazyByteString a => HasLazyByteString (Const a b) where
+  lazyByteString =
+    iso getConst Const . lazyByteString
+
+class AsByteString a where
+  _ByteString ::
+    Prism' a ByteStringChar8.ByteString
+
+instance AsByteString [Char] where
+  _ByteString =
+    iso
+      ByteStringChar8.pack
+      ByteStringChar8.unpack
+
+instance AsByteString Text.Text where
+  _ByteString =
+    iso Text.unpack Text.pack . _ByteString
+
+instance AsByteString LazyText.Text where
+  _ByteString =
+    iso LazyText.unpack LazyText.pack . _ByteString
+
+instance AsByteString ByteStringChar8.ByteString where
+  _ByteString =
+    id
+
+instance AsByteString ByteStringLazyChar8.ByteString where
+  _ByteString =
+    iso ByteStringLazyChar8.toStrict ByteStringLazyChar8.fromStrict
+
+instance AsByteString a => AsByteString (Identity a) where
+  _ByteString =
+    iso runIdentity Identity . _ByteString
+
+instance AsByteString a => AsByteString (Const a b) where
+  _ByteString =
+    iso getConst Const . _ByteString
+
+class AsLazyByteString a where
+  _LazyByteString ::
+    Prism' a ByteStringLazyChar8.ByteString
+
+instance AsLazyByteString [Char] where
+  _LazyByteString =
+    iso
+      ByteStringLazyChar8.pack
+      ByteStringLazyChar8.unpack
+
+instance AsLazyByteString Text.Text where
+  _LazyByteString =
+    iso Text.unpack Text.pack . _LazyByteString
+
+instance AsLazyByteString LazyText.Text where
+  _LazyByteString =
+    iso LazyText.unpack LazyText.pack . _LazyByteString
+
+instance AsLazyByteString ByteStringChar8.ByteString where
+  _LazyByteString =
+    iso ByteStringLazyChar8.fromStrict ByteStringLazyChar8.toStrict
+
+instance AsLazyByteString ByteStringLazyChar8.ByteString where
+  _LazyByteString =
+    id
+
+instance AsLazyByteString a => AsLazyByteString (Identity a) where
+  _LazyByteString =
+    iso runIdentity Identity . _LazyByteString
+
+instance AsLazyByteString a => AsLazyByteString (Const a b) where
+  _LazyByteString =
+    iso getConst Const . _LazyByteString
diff --git a/src/Data/Stringz/String.hs b/src/Data/Stringz/String.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Stringz/String.hs
@@ -0,0 +1,81 @@
+{-# OPTIONS_GHC -Wall #-}
+{-# LANGUAGE FlexibleInstances #-}
+
+module Data.Stringz.String where
+
+import Control.Lens
+import qualified Data.ByteString.Char8 as ByteStringChar8
+import qualified Data.ByteString.Lazy.Char8 as ByteStringLazyChar8
+import qualified Data.Text as Text
+import qualified Data.Text.Lazy as LazyText
+
+class HasString a where
+  string ::
+    Lens' a String
+
+instance HasString [Char] where
+  string =
+    id
+instance HasString Text.Text where
+  string =
+    iso
+      Text.unpack
+      Text.pack
+
+instance HasString LazyText.Text where
+  string =
+    iso
+      LazyText.unpack
+      LazyText.pack
+
+instance HasString ByteStringChar8.ByteString where
+  string =
+    iso ByteStringChar8.unpack ByteStringChar8.pack . string
+
+instance HasString ByteStringLazyChar8.ByteString where
+  string =
+    iso ByteStringLazyChar8.unpack ByteStringLazyChar8.pack . string
+
+instance HasString a => HasString (Identity a) where
+  string =
+    iso runIdentity Identity . string
+
+instance HasString a => HasString (Const a b) where
+  string =
+    iso getConst Const . string
+
+class AsString a where
+  _String ::
+    Prism' a String
+
+instance AsString [Char] where
+  _String =
+    id
+
+instance AsString Text.Text where
+  _String =
+    iso
+      Text.unpack
+      Text.pack
+
+instance AsString LazyText.Text where
+  _String =
+    iso
+      LazyText.unpack
+      LazyText.pack
+
+instance AsString ByteStringChar8.ByteString where
+  _String =
+    iso ByteStringChar8.unpack ByteStringChar8.pack . _String
+
+instance AsString ByteStringLazyChar8.ByteString where
+  _String =
+    iso ByteStringLazyChar8.unpack ByteStringLazyChar8.pack . _String
+
+instance AsString a => AsString (Identity a) where
+  _String =
+    iso runIdentity Identity . _String
+
+instance AsString a => AsString (Const a b) where
+  _String =
+    iso getConst Const . _String
diff --git a/src/Data/Stringz/Text.hs b/src/Data/Stringz/Text.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Stringz/Text.hs
@@ -0,0 +1,154 @@
+{-# OPTIONS_GHC -Wall #-}
+{-# LANGUAGE FlexibleInstances #-}
+
+module Data.Stringz.Text where
+
+import Control.Lens
+import qualified Data.ByteString.Char8 as ByteStringChar8
+import qualified Data.ByteString.Lazy.Char8 as ByteStringLazyChar8
+import qualified Data.Text as Text
+import qualified Data.Text.Lazy as LazyText
+
+class HasText a where
+  text ::
+    Lens' a Text.Text
+
+instance HasText [Char] where
+  text =
+    iso
+      Text.pack
+      Text.unpack
+
+instance HasText Text.Text where
+  text =
+    id
+
+instance HasText LazyText.Text where
+  text =
+    iso
+      LazyText.toStrict
+      LazyText.fromStrict
+
+instance HasText ByteStringChar8.ByteString where
+  text =
+    iso ByteStringChar8.unpack ByteStringChar8.pack . text
+
+instance HasText ByteStringLazyChar8.ByteString where
+  text =
+    iso ByteStringLazyChar8.unpack ByteStringLazyChar8.pack . text
+
+instance HasText a => HasText (Identity a) where
+  text =
+    iso runIdentity Identity . text
+
+instance HasText a => HasText (Const a b) where
+  text =
+    iso getConst Const . text
+
+class HasLazyText a where
+  lazyText ::
+    Lens' a LazyText.Text
+
+instance HasLazyText [Char] where
+  lazyText =
+    iso
+      LazyText.pack
+      LazyText.unpack
+
+instance HasLazyText Text.Text where
+  lazyText =
+    iso
+      LazyText.fromStrict
+      LazyText.toStrict
+
+instance HasLazyText LazyText.Text where
+  lazyText =
+    id
+
+instance HasLazyText ByteStringChar8.ByteString where
+  lazyText =
+    iso ByteStringChar8.unpack ByteStringChar8.pack . lazyText
+
+instance HasLazyText ByteStringLazyChar8.ByteString where
+  lazyText =
+    iso ByteStringLazyChar8.unpack ByteStringLazyChar8.pack . lazyText
+
+instance HasLazyText a => HasLazyText (Identity a) where
+  lazyText =
+    iso runIdentity Identity . lazyText
+
+instance HasLazyText a => HasLazyText (Const a b) where
+  lazyText =
+    iso getConst Const . lazyText
+
+class AsText a where
+  _Text ::
+    Prism' a Text.Text
+
+instance AsText [Char] where
+  _Text =
+    iso
+      Text.pack
+      Text.unpack
+
+instance AsText Text.Text where
+  _Text =
+    id
+
+instance AsText LazyText.Text where
+  _Text =
+    iso
+      LazyText.toStrict
+      LazyText.fromStrict
+
+instance AsText ByteStringChar8.ByteString where
+  _Text =
+    iso ByteStringChar8.unpack ByteStringChar8.pack . _Text
+
+instance AsText ByteStringLazyChar8.ByteString where
+  _Text =
+    iso ByteStringLazyChar8.unpack ByteStringLazyChar8.pack . _Text
+
+instance AsText a => AsText (Identity a) where
+  _Text =
+    iso runIdentity Identity . _Text
+
+instance AsText a => AsText (Const a b) where
+  _Text =
+    iso getConst Const . _Text
+
+class AsLazyText a where
+  _LazyText ::
+    Prism' a LazyText.Text
+
+instance AsLazyText [Char] where
+  _LazyText =
+    iso
+      LazyText.pack
+      LazyText.unpack
+
+instance AsLazyText Text.Text where
+  _LazyText =
+    iso
+      LazyText.fromStrict
+      LazyText.toStrict
+
+instance AsLazyText LazyText.Text where
+  _LazyText =
+    id
+
+instance AsLazyText ByteStringChar8.ByteString where
+  _LazyText =
+    iso ByteStringChar8.unpack ByteStringChar8.pack . _LazyText
+
+instance AsLazyText ByteStringLazyChar8.ByteString where
+  _LazyText =
+    iso ByteStringLazyChar8.unpack ByteStringLazyChar8.pack . _LazyText
+
+instance AsLazyText a => AsLazyText (Identity a) where
+  _LazyText =
+    iso runIdentity Identity . _LazyText
+
+instance AsLazyText a => AsLazyText (Const a b) where
+  _LazyText =
+    iso getConst Const . _LazyText
diff --git a/stringz.cabal b/stringz.cabal
new file mode 100644
--- /dev/null
+++ b/stringz.cabal
@@ -0,0 +1,36 @@
+name:                 stringz
+version:              0.0.1
+synopsis:             Optics for string-like data types
+description:          Optics for string-like data types e.g. [Char], Text, ByteString
+license:              BSD3
+license-file:         LICENCE
+author:               Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>
+maintainer:           Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>
+copyright:            Copyright (C) 2024 Tony Morris
+category:             Data
+build-type:           Simple
+extra-source-files:   changelog.md
+cabal-version:        >=1.10
+homepage:             https://gitlab.com/tonymorris/stringz
+bug-reports:          https://gitlab.com/tonymorris/stringz/issues
+tested-with:          GHC == 9.6.5
+
+source-repository     head
+  type:               git
+  location:           git@gitlab.com:tonymorris/stringz.git
+
+library
+  exposed-modules:
+                      Data.Stringz
+                      Data.Stringz.ByteString
+                      Data.Stringz.String
+                      Data.Stringz.Text
+
+  build-depends:        base                 >= 4.9    && < 6
+                      , lens                 >= 5      && < 6
+                      , text                 >= 2      && < 3
+                      , bytestring           >= 0.9    && < 1
+
+  hs-source-dirs:     src
+  default-language:   Haskell2010
+  ghc-options:        -Wall
