diff --git a/Biobase/Types/Energy.hs b/Biobase/Types/Energy.hs
--- a/Biobase/Types/Energy.hs
+++ b/Biobase/Types/Energy.hs
@@ -7,8 +7,10 @@
 module Biobase.Types.Energy where
 
 import Control.DeepSeq
+import Control.Lens
 import Data.Aeson (FromJSON, ToJSON)
 import Data.Binary (Binary)
+import Data.Data
 import Data.Default
 import Data.Hashable
 import Data.Serialize (Serialize)
@@ -28,31 +30,30 @@
 --
 -- TODO shall we phantom-type the actual units?
 
-newtype DeltaGibbs = DG { getDG :: Double }
-  deriving (Eq,Ord,Num,Fractional,Read,Show,Generic)
-
-
+newtype DG = DG { dG :: Double }
+  deriving (Eq,Ord,Num,Fractional,Read,Show,Generic,Data,Typeable)
+makeLenses ''DG
 
-derivingUnbox "DeltaGibbs"
-  [t| DeltaGibbs -> Double |]  [| getDG |]  [| DG |]
+derivingUnbox "DG"
+  [t| DG -> Double |]  [| dG |]  [| DG |]
 
-instance Hashable  DeltaGibbs
-instance Binary    DeltaGibbs
-instance Serialize DeltaGibbs
-instance FromJSON  DeltaGibbs
-instance ToJSON    DeltaGibbs
-instance NFData    DeltaGibbs
+instance Hashable  DG
+instance Binary    DG
+instance Serialize DG
+instance FromJSON  DG
+instance ToJSON    DG
+instance NFData    DG
 
-deriving instance NumericalExtremes DeltaGibbs
-deriving instance NumericalEpsilon  DeltaGibbs
+deriving instance NumericalExtremes DG
+deriving instance NumericalEpsilon  DG
 
-instance Default DeltaGibbs where
+instance Default DG where
   def = maxLarge
   {-# Inline def #-}
 
 
 
--- | @round $ DeltaGibbs / 100@.
+-- | @round $ DG / 100@.
 
 newtype DeltaDekaGibbs = DekaG { getDekaG :: Int }
   deriving (Eq,Ord,Num,Read,Show,Generic)
diff --git a/Biobase/Types/Sequence.hs b/Biobase/Types/Sequence.hs
new file mode 100644
--- /dev/null
+++ b/Biobase/Types/Sequence.hs
@@ -0,0 +1,199 @@
+
+-- | Wrappers around biosequences.
+
+module Biobase.Types.Sequence where
+
+import           Control.Lens
+import           Control.DeepSeq
+import           Data.ByteString (ByteString)
+import           Data.Char (ord,chr,toUpper)
+import           Data.Data (Data)
+import           Data.Typeable (Typeable)
+import           GHC.Generics (Generic)
+import qualified Data.ByteString.Char8 as BS
+import qualified Data.ByteString.UTF8 as BSU
+import           GHC.Exts (IsString(..))
+
+
+
+-- | A sequence identifier. Just a newtype wrapped text field. Because we can
+-- never know what people are up to, this is utf8-encoded.
+--
+-- TODO Provide @Iso'@ for @Text@, too?
+
+newtype SequenceID = SequenceID { _sequenceID ∷ ByteString }
+  deriving (Data, Typeable, Generic, Eq, Ord, Read, Show, IsString)
+makeLenses ''SequenceID
+
+instance NFData SequenceID
+
+-- | Convert to a string in a unicode-aware manner.
+
+sequenceIDstring ∷ Iso' SequenceID String
+sequenceIDstring = sequenceID . iso BSU.toString BSU.fromString
+{-# Inline sequenceIDstring #-}
+
+
+
+-- | A short RNA sequence.
+--
+-- It is an instance of 'Ixed' to allow @RNAseq (BS.pack "cag") ^? ix 2 == Just 'g'@.
+
+newtype RNAseq = RNAseq { _rnaseq ∷ ByteString }
+  deriving (Data, Typeable, Generic, Eq, Ord, Read, Show)
+makeLenses ''RNAseq
+
+instance NFData RNAseq
+
+type instance Index RNAseq = Int
+
+type instance IxValue RNAseq = Char
+
+instance Ixed RNAseq where
+  ix k = rnaseq . ix k . iso (chr . fromIntegral) (fromIntegral . ord)
+  {-# Inline ix #-}
+
+deriving instance Reversing RNAseq
+
+mkRNAseq ∷ ByteString → RNAseq
+mkRNAseq = RNAseq . BS.map go . BS.map toUpper
+  where go x | x `elem` acgu = x
+             | otherwise     = 'N'
+        acgu ∷ String
+        acgu = "ACGU"
+
+instance IsString RNAseq where
+  fromString = mkRNAseq . BS.pack
+
+
+
+-- | A short DNA sequence.
+--
+-- Note everything really long should be handled by specialized libraries with
+-- streaming capabilities.
+
+newtype DNAseq = DNAseq { _dnaseq ∷ ByteString }
+  deriving (Data, Typeable, Generic, Eq, Ord, Read, Show)
+makeLenses ''DNAseq
+
+instance NFData DNAseq
+
+type instance Index DNAseq = Int
+
+type instance IxValue DNAseq = Char
+
+instance Ixed DNAseq where
+  ix k = dnaseq . ix k . iso (chr . fromIntegral) (fromIntegral . ord)
+  {-# Inline ix #-}
+
+mkDNAseq ∷ ByteString → DNAseq
+mkDNAseq = DNAseq . BS.map go . BS.map toUpper
+  where go x | x `elem` acgt = x
+             | otherwise     = 'N'
+        acgt ∷ String
+        acgt = "ACGT"
+
+instance IsString DNAseq where
+  fromString = mkDNAseq . BS.pack
+
+deriving instance Reversing DNAseq
+
+-- | Simple case translation from @U@ to @T@. with upper and lower-case
+-- awareness.
+
+rna2dna ∷ Char → Char
+rna2dna = \case
+  'U' → 'T'
+  'u' → 't'
+  x   → x
+{-# Inline rna2dna #-}
+
+-- | Single character RNA complement.
+
+rnaComplement ∷ Char → Char
+rnaComplement = \case
+  'A' → 'U'
+  'a' → 'u'
+  'C' → 'G'
+  'c' → 'g'
+  'G' → 'C'
+  'g' → 'c'
+  'U' → 'A'
+  'u' → 'a'
+  x   → x
+{-# Inline rnaComplement #-}
+
+-- | Simple case translation from @T@ to @U@ with upper- and lower-case
+-- awareness.
+
+dna2rna ∷ Char → Char
+dna2rna = \case
+  'T' → 'U'
+  't' → 'u'
+  x   → x
+{-# Inline dna2rna #-}
+
+-- | Single character DNA complement.
+
+dnaComplement ∷ Char → Char
+dnaComplement = \case
+  'A' → 'T'
+  'a' → 't'
+  'C' → 'G'
+  'c' → 'g'
+  'G' → 'C'
+  'g' → 'c'
+  'T' → 'A'
+  't' → 'a'
+  x   → x
+{-# Inline dnaComplement #-}
+
+
+
+-- | Transcribes a DNA sequence into an RNA sequence. Note that 'transcribe' is
+-- actually very generic. We just define its semantics to be that of
+-- biomolecular transcription.
+--
+-- 'transcribe' makes the assumption that, given @DNA -> RNA@, we transcribe
+-- the coding strand.
+-- <http://hyperphysics.phy-astr.gsu.edu/hbase/Organic/transcription.html>
+--
+-- @@ DNAseq "ACGT" ^. transcribe == RNAseq "ACGU" RNAseq "ACGU" ^. transcribe
+-- == DNAseq "ACGT" RNAseq "ACGU" ^. from transcribe :: DNAseq == DNAseq "ACGT"
+-- @@
+
+class Transcribe f where
+  type TranscribeTo f ∷ *
+  transcribe ∷ Iso' f (TranscribeTo f)
+
+-- | Transcribe a DNA sequence into an RNA sequence. This does not @reverse@
+-- the sequence!
+
+instance Transcribe DNAseq where
+  type TranscribeTo DNAseq = RNAseq
+  transcribe = iso (RNAseq . BS.map dna2rna . _dnaseq) (DNAseq . BS.map rna2dna . _rnaseq)
+  {-# Inline transcribe #-}
+
+-- | Transcribe a RNA sequence into an DNA sequence. This does not @reverse@
+-- the sequence!
+
+instance Transcribe RNAseq where
+  type TranscribeTo RNAseq = DNAseq
+  transcribe = from transcribe
+  {-# Inline transcribe #-}
+
+
+
+-- | The complement of a biosequence.
+
+class Complement f where
+  complement ∷ Iso' f f
+
+instance Complement DNAseq where
+  complement = iso (DNAseq . BS.map dnaComplement . _dnaseq) (DNAseq . BS.map dnaComplement . _dnaseq)
+  {-# Inline complement #-}
+
+instance Complement RNAseq where
+  complement = iso (RNAseq . BS.map rnaComplement . _rnaseq) (RNAseq . BS.map rnaComplement . _rnaseq)
+  {-# Inline complement #-}
+
diff --git a/Biobase/Types/Structure.hs b/Biobase/Types/Structure.hs
new file mode 100644
--- /dev/null
+++ b/Biobase/Types/Structure.hs
@@ -0,0 +1,138 @@
+
+-- | Wrappers for structural data. Encoded as bytestrings. This differs from
+-- @BiobaseXNA@, where specialized encodings are used. These structures are
+-- supposedly "short", they need to fit into a strict bytestring.
+--
+-- TODO Consider where to move each type. There are merge possibilities between
+-- BiobaseXNA and BiobaseTypes.
+
+module Biobase.Types.Structure where
+
+import           Control.DeepSeq
+import           Control.Lens
+import           Control.Monad.Error.Class
+import           Control.Monad (foldM,unless)
+import           Data.ByteString (ByteString)
+import           Data.Data
+import           Data.Set (Set)
+import           GHC.Generics (Generic)
+import qualified Data.ByteString.Char8 as BS8
+import qualified Data.List as L
+import qualified Data.Set as Set
+
+
+
+-- | Secondary structure using @()@ for paired elements, and @.@ for unpaired
+-- ones. It is assumed that the @()@ match up. These structures from a Monoid.
+
+newtype RNAss = RNAss { _rnass ∷ ByteString }
+  deriving (Eq,Ord,Show,Read,Data,Typeable,Generic,Monoid)
+makeLenses ''RNAss
+
+instance NFData RNAss
+
+-- | Ensemble structure encoding. *Very* different type ctor name chosen! The
+-- structure of this string makes verification much more complicated.
+--
+-- TODO describe encoding used by RNAfold for the ensemble string.
+
+newtype RNAensembleStructure = RNAes { _rnaes ∷ ByteString }
+  deriving (Eq,Ord,Show,Read,Data,Typeable,Generic)
+makeLenses ''RNAensembleStructure
+
+instance NFData RNAensembleStructure
+
+-- | Cofolded structure.
+
+data RNAds = RNAds
+  { _rnadsL ∷ !ByteString
+  , _rnadsR ∷ !ByteString
+  }
+  deriving (Eq,Ord,Show,Read,Data,Typeable,Generic)
+makeLenses ''RNAds
+
+instance NFData RNAds
+
+-- | A Prism that turns ByteStrings with a single @&@ into @RNAds@.
+
+rnads ∷ Prism' ByteString RNAds
+rnads = prism (\(RNAds l r) → BS8.concat [l, "&", r])
+              (\s → case BS8.split '&' s of [l,r] → Right (RNAds l r) ; _ → Left s)
+{-# Inline rnads #-}
+
+-- | Isomorphism from @RNAds@ to @(RNAss,RNAss)@. The @RNAss@ are only
+-- legal if taken both: @rnassFromDimer . both@.
+
+rnads2rnassPair ∷ Iso' RNAds (RNAss, RNAss)
+rnads2rnassPair = iso (\(RNAds l r) → (RNAss l, RNAss r)) (\(RNAss l, RNAss r) → RNAds l r)
+{-# Inline rnads2rnassPair #-}
+
+-- | Try to create a dimeric structure.
+
+mkRNAds ∷ (Monad m, MonadError RNAStructureError m) ⇒ ByteString → m RNAds
+mkRNAds q = BS8.split '&' q & \case
+    [l,r] → do
+      -- TODO can still fail with unmatched brackets.
+      return $ RNAds
+        { _rnadsL = l
+        , _rnadsR = r
+        }
+    _     → throwError $ RNAStructureError "mkRNAds: not a dimer" q
+{-# Inline mkRNAds #-}
+
+-- | Capture what might be wrong with the RNAss.
+
+data RNAStructureError = RNAStructureError
+  { _rnaStructureError  ∷ String
+  , _rnaOffender        ∷ ByteString
+  }
+  deriving (Show,Generic)
+
+instance NFData RNAStructureError
+
+-- | Verifies that the given RNAss is properly formatted. Otherwise, error out.
+--
+-- TODO Implement! Check with BiobaseXNA and the stack effort in there. This
+-- might influence if the verification goes into BiobaseXNA and happens via an
+-- @Iso'@.
+
+verifyRNAss ∷ (Monad m, MonadError RNAStructureError m) ⇒ RNAss → m RNAss
+verifyRNAss ss = do
+  return ss
+
+newtype RNApset = RNApset { _rnapset ∷ Set (Int,Int) }
+  deriving (Read,Show,Eq,Ord,Generic)
+makeLenses ''RNApset
+
+instance NFData RNApset
+
+-- | Transform an 'RNAss' into a set of base pairs @(i,j)@. The pairs are
+-- 0-based.
+
+rnassPairSet
+  ∷ (MonadError String m)
+  ⇒ RNAss
+  → m RNApset
+rnassPairSet (RNAss s2) = do
+  let go (set,ks  ) (i,'(') = return (set,i:ks)
+      go (set,i:is) (j,')') = return (Set.insert (i,j) set, is)
+      go (set,[]  ) (j,')') = throwError $ "unequal brackets in \"" ++ BS8.unpack s2 ++ "\" at position: " ++ show j
+      go (set,ks  ) (_,'.') = return (set,ks)
+  (set,ss) ← foldM go (Set.empty,[]) . L.zip [0..] $ BS8.unpack s2
+  unless (null ss) $ throwError $ "unequal brackets in \"" ++ BS8.unpack s2 ++ "\" with opening bracket(s): " ++ show ss
+  return $ RNApset set
+{-# Inlinable rnassPairSet #-}
+
+-- | RNA pair set, but a transformation error calls @error@.
+
+rnassPairSet' ∷ RNAss → RNApset
+rnassPairSet' = either error id . rnassPairSet
+
+-- | Calculates the number of different base pairs betwwen two structures.
+
+pairDist ∷ RNApset → RNApset → Int
+pairDist (RNApset p1) (RNApset p2) = Set.size z1 + Set.size z2
+  where i = Set.intersection p1 p2
+        z1 = p1 `Set.difference` i
+        z2 = p2 `Set.difference` i
+
diff --git a/BiobaseTypes.cabal b/BiobaseTypes.cabal
--- a/BiobaseTypes.cabal
+++ b/BiobaseTypes.cabal
@@ -1,7 +1,7 @@
 name:           BiobaseTypes
-version:        0.1.2.1
-author:         Christian Hoener zu Siederdissen, 2015 - 2016
-copyright:      Christian Hoener zu Siederdissen, 2015 - 2016
+version:        0.1.3.0
+author:         Christian Hoener zu Siederdissen, 2015 - 2017
+copyright:      Christian Hoener zu Siederdissen, 2015 - 2017
 homepage:       https://github.com/choener/BiobaseTypes
 bug-reports:    https://github.com/choener/BiobaseTypes/issues
 maintainer:     choener@bioinf.uni-leipzig.de
@@ -11,7 +11,7 @@
 build-type:     Simple
 stability:      experimental
 cabal-version:  >= 1.10.0
-tested-with:    GHC == 7.10.3, GHC == 8.0.1
+tested-with:    GHC == 8.0.2, GHC == 8.2.1
 synopsis:       Collection of types for bioinformatics
 description:
                 Types used in a number of bioinformatics libraries.
@@ -21,6 +21,8 @@
                 * energies
                 .
                 * numerics
+                .
+                * biostring wrappers
 
 
 
@@ -34,18 +36,23 @@
   build-depends: base                     >= 4.7      &&  < 5.0
                , aeson                    >= 0.8
                , binary                   >= 0.7
+               , bytestring
                , cereal                   >= 0.4
                , cereal-text              >= 0.1
                , cereal-vector            >= 0.2
+               , containers
                , data-default             >= 0.5
-               , deepseq                  >= 1.3
+               , deepseq                  >= 1.4
                , hashable                 >= 1.2
                , intern                   >= 0.9
+               , lens                     >= 4.0
+               , mtl
                , primitive                >= 0.5
                , QuickCheck               >= 2.7
                , string-conversions       >= 0.4
                , text                     >= 1.0
                , text-binary              >= 0.2
+               , utf8-string              >= 1.0
                , vector                   >= 0.10
                , vector-binary-instances  >= 0.2
                , vector-th-unbox          >= 0.2
@@ -63,17 +70,21 @@
     Biobase.Types.Names.Internal
     Biobase.Types.NumericalExtremes
     Biobase.Types.Odds
+    Biobase.Types.Sequence
     Biobase.Types.Strand
+    Biobase.Types.Structure
     Biobase.Types.Taxonomy
   default-language:
     Haskell2010
   default-extensions: BangPatterns
                     , DataKinds
+                    , DeriveDataTypeable
                     , DeriveGeneric
                     , FlexibleContexts
                     , FlexibleInstances
                     , GeneralizedNewtypeDeriving
                     , KindSignatures
+                    , LambdaCase
                     , MultiParamTypeClasses
                     , OverloadedStrings
                     , PatternSynonyms
@@ -82,6 +93,7 @@
                     , TemplateHaskell
                     , TypeFamilies
                     , TypeOperators
+                    , UnicodeSyntax
   ghc-options:
     -O2 -funbox-strict-fields
 
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,8 @@
+0.1.3.0
+-------
+
+- "biostring" wrappers (ByteString based RNA, DNA, ... sequences)
+
 0.1.2.1
 -------
 
