diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,19 +3,25 @@
 [![Build Status](https://travis-ci.com/emilypi/base16.svg?branch=master)](https://travis-ci.com/emilypi/base16)
 [![Hackage](https://img.shields.io/hackage/v/base16.svg)](https://hackage.haskell.org/package/base16)
 
-Padded and unpadded base16 and base16hex encoding and decoding for `Text` and `ByteString` values.
+RFC 4648-compliant Base16 encoding and decoding.
 
 For the companion optics and pattern synonyms, see [base16-lens](https://hackage.haskell.org/package/base16-lens).
 
-
 ### Summary
 
-What does this library provide? Here is the summary:
+The following types are supported for Hex alphabet codecs:
 
-- *Great* encoding performance compared to existing libraries (e.g. `memory`, `base16-bytestring`)
-- Better decoding performance compared to existing libraries.
-- Support for `Text` encodings and decodings
-- Optics for handling more complex structures with Base16 representations via the `base16-lens` package
-- Checks for both valid Base16 and correct Base16 and Base16hex encodings
+- `Data.ByteString`
+- `Data.ByteString.Lazy`
+- `Data.ByteString.Short`
+- `Data.Text`
+- `Data.Text.Lazy`
+- `Data.Text.Short`
+
+Additionally this library has
+
+- Much better performance than `base16-bytestring` for encode and decode, with a more conventional api.
+- Optics for handling more complex structures with Base64 representations via the `base16-lens` package
+- Checks for both validity and correctness of Base16 encodings.
 
 There are no dependencies aside from those bundled with GHC.
diff --git a/base16.cabal b/base16.cabal
--- a/base16.cabal
+++ b/base16.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.0
 name:               base16
-version:            0.2.0.1
+version:            0.2.1.0
 synopsis:           RFC 4648-compliant Base16 encodings/decodings
 description:
   RFC 4648-compliant Base16 encodings and decodings.
@@ -30,9 +30,11 @@
   exposed-modules:
     Data.ByteString.Base16
     Data.ByteString.Lazy.Base16
+    Data.ByteString.Short.Base16
     Data.Text.Encoding.Base16
     Data.Text.Encoding.Base16.Error
     Data.Text.Lazy.Encoding.Base16
+    Data.Text.Short.Encoding.Base16
 
   other-modules:
     Data.ByteString.Base16.Internal.Head
@@ -44,6 +46,7 @@
     , bytestring  ^>=0.10
     , primitive
     , text        ^>=1.2
+    , text-short  ^>=0.1
 
   hs-source-dirs:   src
   default-language: Haskell2010
diff --git a/src/Data/ByteString/Lazy/Base16.hs b/src/Data/ByteString/Lazy/Base16.hs
--- a/src/Data/ByteString/Lazy/Base16.hs
+++ b/src/Data/ByteString/Lazy/Base16.hs
@@ -22,6 +22,7 @@
 ) where
 
 
+
 import Prelude hiding (all, elem)
 
 import qualified Data.ByteString as B
@@ -30,8 +31,8 @@
 import qualified Data.ByteString.Base16.Internal.Head as B16
 import Data.ByteString.Base16.Internal.Utils (reChunk)
 import Data.Either
-import qualified Data.Text as T
 import Data.Text.Lazy (Text)
+import qualified Data.Text as T
 import qualified Data.Text.Lazy.Encoding as TL
 
 
diff --git a/src/Data/ByteString/Short/Base16.hs b/src/Data/ByteString/Short/Base16.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/ByteString/Short/Base16.hs
@@ -0,0 +1,110 @@
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE OverloadedStrings #-}
+-- |
+-- Module       : Data.ByteString.Short.Base16
+-- Copyright 	: (c) 2020 Emily Pillmore
+-- License	: BSD-style
+--
+-- Maintainer	: Emily Pillmore <emilypi@cohomolo.gy>
+-- Stability	: Experimental
+-- Portability	: portable
+--
+-- This module contains the combinators implementing the
+-- RFC 4648 specification for the Base16 encoding including
+-- unpadded and lenient variants for bytestrings
+--
+module Data.ByteString.Short.Base16
+( encodeBase16
+, encodeBase16'
+, decodeBase16
+, decodeBase16Lenient
+, isBase16
+, isValidBase16
+) where
+
+
+import Prelude hiding (all, elem)
+
+import Data.ByteString.Short (ShortByteString, toShort, fromShort)
+import qualified Data.ByteString.Base16 as B16
+import Data.Text (Text)
+
+
+-- | Encode a 'ShortByteString' value as Base16 'Text' with padding.
+--
+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>
+--
+encodeBase16 :: ShortByteString -> Text
+encodeBase16 = B16.encodeBase16 . fromShort
+{-# INLINE encodeBase16 #-}
+
+-- | Encode a 'ShortByteString' value as a Base16 'ShortByteString'  value with padding.
+--
+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>
+--
+encodeBase16' :: ShortByteString -> ShortByteString
+encodeBase16' = toShort . B16.encodeBase16' . fromShort
+{-# INLINE encodeBase16' #-}
+
+-- | Decode a Base16-encoded 'ShortByteString' value.
+--
+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>
+--
+decodeBase16 :: ShortByteString -> Either Text ShortByteString
+decodeBase16 = fmap toShort . B16.decodeBase16 . fromShort
+{-# INLINE decodeBase16 #-}
+
+-- | Decode a Base16-encoded 'ShortByteString' value leniently, using a
+-- strategy that never fails
+--
+-- N.B.: this is not RFC 4648-compliant
+--
+decodeBase16Lenient :: ShortByteString -> ShortByteString
+decodeBase16Lenient = toShort . B16.decodeBase16Lenient . fromShort
+{-# INLINE decodeBase16Lenient #-}
+
+-- | Tell whether a 'ShortByteString' value is base16 encoded.
+--
+-- Examples:
+--
+-- This example will fail. It conforms to the alphabet, but
+-- is not valid because it has an incorrect (odd) length.
+--
+-- >>> isBase16 "666f6"
+-- False
+--
+-- This example will succeed because it satisfies the alphabet
+-- and is considered "valid" (i.e. of the correct size and shape).
+--
+-- >>> isBase16 "666f"
+-- True
+--
+isBase16 :: ShortByteString -> Bool
+isBase16 = B16.isBase16 . fromShort
+{-# INLINE isBase16 #-}
+
+-- | Tell whether a 'ShortByteString' value is a valid Base16 format.
+--
+-- This will not tell you whether or not this is a correct Base16 representation,
+-- only that it conforms to the correct alphabet. To check whether it is a true
+-- Base16 encoded 'ShortByteString' value, use 'isBase16'.
+--
+-- Examples:
+--
+-- This example will fail because it does not conform to the Hex
+-- alphabet.
+--
+-- >>> isValidBase16 "666f+/6"
+-- False
+--
+-- This example will succeed because it satisfies the alphabet
+-- and is considered "valid" (i.e. of the correct size and shape), but
+-- is not correct base16 because it is the wrong shape.
+--
+-- >>> isValidBase16 "666f6"
+-- True
+--
+isValidBase16 :: ShortByteString -> Bool
+isValidBase16 = B16.isValidBase16 . fromShort
+{-# INLINE isValidBase16 #-}
diff --git a/src/Data/Text/Short/Encoding/Base16.hs b/src/Data/Text/Short/Encoding/Base16.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Text/Short/Encoding/Base16.hs
@@ -0,0 +1,128 @@
+-- |
+-- Module       : Data.Text.Short.Encoding.Base16
+-- Copyright 	: (c) 2019 Emily Pillmore
+-- License	: BSD-style
+--
+-- Maintainer	: Emily Pillmore <emilypi@cohomolo.gy>
+-- Stability	: Experimental
+-- Portability	: portable
+--
+-- This module contains the combinators implementing the
+-- RFC 4648 specification for the Base16 encoding including
+-- unpadded and lenient variants for text values
+--
+module Data.Text.Short.Encoding.Base16
+( encodeBase16
+, decodeBase16
+, decodeBase16With
+, decodeBase16Lenient
+, isBase16
+, isValidBase16
+) where
+
+
+import Data.Bifunctor (first)
+import qualified Data.ByteString.Base16 as B16
+import Data.ByteString.Short (ShortByteString)
+import qualified Data.ByteString.Short.Base16 as BS16
+import Data.Text (Text)
+import qualified Data.Text.Encoding.Base16 as B16T
+import Data.Text.Encoding.Base16.Error
+import Data.Text.Short
+import Data.Text.Short.Unsafe
+
+
+-- | Encode a 'ShortText' value in Base16 with padding.
+--
+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>
+--
+encodeBase16 :: ShortText -> ShortText
+encodeBase16 = fromByteStringUnsafe . B16.encodeBase16' . toByteString
+{-# INLINE encodeBase16 #-}
+
+-- | Decode a Base16-encoded lazy 'ShortText' value.
+--
+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>
+--
+decodeBase16 :: ShortText -> Either Text ShortText
+decodeBase16 = fmap fromText . B16T.decodeBase16 . toText
+{-# INLINE decodeBase16 #-}
+
+-- | Attempt to decode a lazy 'ShortText' value as Base16, converting from
+-- 'ByteString' to 'ShortText' according to some encoding function. In practice,
+-- This is something like 'decodeUtf8'', which may produce an error.
+--
+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>
+--
+-- Example:
+--
+-- @
+-- 'decodeBase16With' 'T.decodeUtf8''
+--   :: 'ShortText' -> 'Either' ('Base16Error' 'UnicodeException') 'ShortText'
+-- @
+--
+decodeBase16With
+    :: (ShortByteString -> Either err ShortText)
+      -- ^ convert a bytestring to text (e.g. 'T.decodeUtf8'')
+    -> ShortText
+      -- ^ Input text to decode
+    -> Either (Base16Error err) ShortText
+decodeBase16With f t = case BS16.decodeBase16 (toShortByteString t) of
+  Left de -> Left $ DecodeError de
+  Right a -> first ConversionError (f a)
+{-# INLINE decodeBase16With #-}
+
+-- | Decode a Base16-encoded lazy 'ShortText' value leniently, using a
+-- strategy that never fails, catching unicode exceptions raised in the
+-- process of converting to text values.
+--
+-- N.B.: this is not RFC 4648-compliant.
+--
+decodeBase16Lenient :: ShortText -> ShortText
+decodeBase16Lenient = fromText . B16T.decodeBase16Lenient . toText
+{-# INLINE decodeBase16Lenient #-}
+
+-- | Tell whether a 'ShortText' value is Base16-encoded.
+--
+-- Examples:
+--
+-- This example will fail. It conforms to the alphabet, but
+-- is not valid because it has an incorrect (odd) length.
+--
+-- >>> isBase16 "666f6"
+-- False
+--
+-- This example will succeed because it satisfies the alphabet
+-- and is considered "valid" (i.e. of the correct size and shape).
+--
+-- >>> isBase16 "666f"
+-- True
+--
+isBase16 :: ShortText -> Bool
+isBase16 = B16.isBase16 . toByteString
+{-# INLINE isBase16 #-}
+
+-- | Tell whether a 'ShortText' value is a valid Base16 format.
+--
+-- This will not tell you whether or not this is a correct Base16 representation,
+-- only that it conforms to the correct shape. To check whether it is a true
+-- Base16 encoded 'ShortText' value, use 'isBase16'.
+--
+-- Examples:
+--
+-- This example will fail because it does not conform to the Hex
+-- alphabet.
+--
+-- >>> isValidBase16 "666f+/6"
+-- False
+--
+-- This example will succeed because it satisfies the alphabet
+-- and is considered "valid" (i.e. of the correct size and shape), but
+-- is not correct base16 because it is the wrong shape.
+--
+-- >>> isValidBase16 "666f6"
+-- True
+--
+isValidBase16 :: ShortText -> Bool
+isValidBase16 = B16.isValidBase16 . toByteString
+{-# INLINE isValidBase16 #-}
