diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,12 @@
+# Change Log
+All notable changes to this project will be documented in this file. This file
+follows the formatting recommendations from [Keep a
+CHANGELOG](http://keepachangelog.com/). This project adheres to [Semantic
+Versioning](http://semver.org/).
+
+## [0.1] - 2015-4-27
+### Added
+- Initial set of utilities for creating `ByteString` and `Text` `Series`.
+- `Serial` `ByteString` and `Text` instances.
+
+[0.1]: https://github.com/jdnavarro/smallcheck-series/compare/49b5b0...v0.1
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2015, J Daniel Navarro
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of J. Daniel Navarro nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+OWNER 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/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+# SmallCheck Series
+
+[![Hackage Version](https://img.shields.io/hackage/v/smallcheck-series.svg)](https://hackage.haskell.org/package/smallcheck-series) [![Build Status](https://img.shields.io/travis/jdnavarro/smallcheck-series.svg)](https://travis-ci.org/jdnavarro/smallcheck-series)
+
+Utilities for creating `Series` and orphan instances for frequently
+used types coming with GHC core libraries.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/Test/SmallCheck/Series/ByteString.hs b/Test/SmallCheck/Series/ByteString.hs
new file mode 100644
--- /dev/null
+++ b/Test/SmallCheck/Series/ByteString.hs
@@ -0,0 +1,87 @@
+{-|
+Following the convention from "Data.ByteString", this module is intended to be
+imported @qualified@. For example:
+
+> import qualified Test.SmallCheck.Series.ByteString as B.Series
+-}
+module Test.SmallCheck.Series.ByteString
+  (
+  -- * Replication
+    aaa
+  , zzz
+  , replicated
+  -- * Enumeration
+  , ascii
+  , alpha
+  , enumerated
+  -- * Printing
+  , jack
+  ) where
+
+import Prelude hiding (replicate)
+import Control.Applicative ((<$>))
+import Data.Char (ord)
+import Data.Word (Word8)
+import Data.ByteString (ByteString, pack, replicate)
+import qualified Data.ByteString.Char8 as B8 (pack)
+import Test.SmallCheck.Series
+
+-- | Create a 'Data.ByteString.ByteString' 'Series' growing with an extra
+--   /byte/ representing the 'a' 'Char' in @ASCII@.
+--
+-- >>> list 4 aaa
+-- ["","a","aa","aaa","aaaa"]
+--
+-- Use this when you don't care about the /byte/ inside 'Data.ByteString.ByteString'.
+aaa :: Series m ByteString
+aaa = replicated . fromIntegral $ ord 'a'
+
+-- | Create a 'Data.ByteString.ByteString' 'Series' growing with an extra @NUL@ byte.
+--
+-- >>> list 4 zzz
+-- ["","\NUL","\NUL\NUL","\NUL\NUL\NUL","\NUL\NUL\NUL\NUL"]
+zzz :: Series m ByteString
+zzz = replicated 0
+
+-- | Create a 'Data.ByteString.ByteString' 'Series' growing with an extra custom byte.
+--
+-- >>> list 4 . replicated . fromIntegral $ ord '@'
+-- ["","@","@@","@@@","@@@@"]
+replicated :: Word8 -> Series m ByteString
+replicated c = generate $ \d -> (`replicate` c) <$> [0..d]
+
+-- | Create a 'Data.ByteString.ByteString' 'Series' growing with the @ASCII@
+--   representation of the alphabet.
+--
+-- >>> list 4 alpha
+-- ["","a","ab","abc","abcd"]
+alpha :: Series m ByteString
+alpha = enumerated $ fromIntegral . ord <$> ['a'..'z']
+
+-- | Create a 'Data.ByteString.ByteString' 'Series' growing by counting bytes.
+--
+-- >>> list 4 ascii
+-- ["","\NUL","\NUL\SOH","\NUL\SOH\STX","\NUL\SOH\STX\ETX"]
+ascii :: Series m ByteString
+ascii = enumerated [0..255]
+
+-- | Create a 'Data.ByteString.ByteString' 'Series' growing with the given byte set.
+--
+-- >>> list 4 . enumerated $ fromIntegral . ord <$> "abc"
+-- ["","a","ab","abc","abc"]
+enumerated  :: [Word8] -> Series m ByteString
+enumerated cs = generate $ \d -> (\n -> pack $ take n cs) <$> [0..d]
+
+-- | Create a 'Data.ByteString.ByteString' 'Series' with a dummy @ASCII@ sentence.
+--   This can be used when you want to print a 'Series' to the screen.
+--
+-- >>> let s = list 20 jack
+-- >>> take 3 s
+-- ["","All","All work"]
+-- >>> s !! 10
+-- "All work and no play makes Jack a dull boy"
+jack :: Series m ByteString
+jack = generate $ \d ->
+    (\n -> B8.pack . unwords . take n . words $ sentence) <$> [0..d]
+  where
+    sentence = "All work and no play makes Jack a dull boy"
diff --git a/Test/SmallCheck/Series/ByteString/Lazy.hs b/Test/SmallCheck/Series/ByteString/Lazy.hs
new file mode 100644
--- /dev/null
+++ b/Test/SmallCheck/Series/ByteString/Lazy.hs
@@ -0,0 +1,90 @@
+{-|
+Following the convention from "Data.ByteString.Lazy", this module is intended to be
+imported @qualified@. For example:
+
+> import qualified Test.SmallCheck.Series.ByteString.Lazy as L.Series
+-}
+module Test.SmallCheck.Series.ByteString.Lazy
+  (
+  -- * Replication
+    aaa
+  , zzz
+  , replicated
+  -- * Enumeration
+  , ascii
+  , alpha
+  , enumerated
+  -- * Printing
+  , jack
+  ) where
+
+import Prelude hiding (replicate)
+import Control.Applicative ((<$>))
+import Data.Char (ord)
+import Data.Word (Word8)
+import Data.ByteString.Lazy (ByteString, pack, replicate)
+import qualified Data.ByteString.Lazy.Char8 as L8 (pack)
+import Test.SmallCheck.Series
+
+-- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing with an extra
+--   /byte/ representing the 'a' 'Char' in @ASCII@.
+--
+-- >>> list 4 aaa
+-- ["","a","aa","aaa","aaaa"]
+--
+-- Use this when you don't care about the /byte/ inside 'Data.ByteString.Lazy.ByteString'.
+aaa :: Series m ByteString
+aaa = replicated . fromIntegral $ ord 'a'
+
+-- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing with an extra @NUL@ byte.
+--
+-- >>> list 4 zzz
+-- ["","\NUL","\NUL\NUL","\NUL\NUL\NUL","\NUL\NUL\NUL\NUL"]
+zzz :: Series m ByteString
+zzz = replicated 0
+
+replicated :: Word8 -> Series m ByteString
+replicated c = generate $ \d -> (`rep` c) <$> [0..d]
+  where
+    rep = replicate . fromIntegral
+
+-- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing with an extra custom byte.
+--
+-- >>> list 4 . replicated . fromIntegral $ ord '@'
+-- ["","@","@@","@@@","@@@@"]
+
+-- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing with the @ASCII@
+--   representation of the alphabet.
+--
+-- >>> list 4 alpha
+-- ["","a","ab","abc","abcd"]
+alpha :: Series m ByteString
+alpha = enumerated $ fromIntegral . ord <$> ['a'..'z']
+
+-- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing by counting bytes.
+--
+-- >>> list 4 ascii
+-- ["","\NUL","\NUL\SOH","\NUL\SOH\STX","\NUL\SOH\STX\ETX"]
+ascii :: Series m ByteString
+ascii = enumerated [0..255]
+
+-- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing with the given byte set.
+--
+-- >>> list 4 . enumerated $ fromIntegral . ord <$> "abc"
+-- ["","a","ab","abc","abc"]
+enumerated  :: [Word8] -> Series m ByteString
+enumerated cs = generate $ \d -> (\n -> pack $ take n cs) <$> [0..d]
+
+-- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' with a dummy @ASCII@ sentence.
+--   This can be used when you want to print a 'Series' to the screen.
+--
+-- >>> let s = list 20 jack
+-- >>> take 3 s
+-- ["","All","All work"]
+-- >>> s !! 10
+-- "All work and no play makes Jack a dull boy"
+jack :: Series m ByteString
+jack = generate $ \d ->
+    (\n -> L8.pack . unwords . take n . words $ sentence) <$> [0..d]
+  where
+    sentence = "All work and no play makes Jack a dull boy"
diff --git a/Test/SmallCheck/Series/Instances.hs b/Test/SmallCheck/Series/Instances.hs
new file mode 100644
--- /dev/null
+++ b/Test/SmallCheck/Series/Instances.hs
@@ -0,0 +1,43 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-|
+'Serial' instances are provided for the following types:
+
+* 'Data.ByteString.ByteString'
+* 'Data.ByteString.Lazy.ByteString'
+* 'Data.Text.Text'
+* 'Data.Text.Lazy.Text'
+
+By default the most economical but less exhaustive series are provided.
+You may want to create your own instances for your own tests if this setting
+doesn't apply for your own tests. Check the utilities in the other modules
+in this package to create custom 'Series'.
+
+Make sure the module where you import these instances is not meant to be
+imported, otherwise the orphan instances might create issues.
+-}
+module Test.SmallCheck.Series.Instances () where
+
+import qualified Data.ByteString as B
+import qualified Data.ByteString.Lazy as BL
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
+import Test.SmallCheck.Series
+
+import Test.SmallCheck.Series.ByteString as Series.ByteString
+import Test.SmallCheck.Series.ByteString.Lazy as Series.ByteString.Lazy
+import Test.SmallCheck.Series.Text as Series.Text
+import Test.SmallCheck.Series.Text.Lazy as Series.Text.Lazy
+
+instance Monad m => Serial m B.ByteString where
+    series = Series.ByteString.aaa
+
+instance Monad m => Serial m BL.ByteString where
+    series = Series.ByteString.Lazy.aaa
+
+instance Monad m => Serial m T.Text where
+    series = Series.Text.aaa
+
+instance Monad m => Serial m TL.Text where
+    series = Series.Text.Lazy.aaa
diff --git a/Test/SmallCheck/Series/Text.hs b/Test/SmallCheck/Series/Text.hs
new file mode 100644
--- /dev/null
+++ b/Test/SmallCheck/Series/Text.hs
@@ -0,0 +1,97 @@
+{-|
+Following the convention from "Data.Text", this module is intended to be
+imported @qualified@. For example:
+
+> import qualified Test.SmallCheck.Series.Text as T.Series
+-}
+module Test.SmallCheck.Series.Text
+  (
+  -- * Replication
+    aaa
+  , zzz
+  , replicated
+  -- * Enumeration
+  , ascii
+  , alpha
+  , enumerated
+  -- * Printing
+  , jack
+  -- * Extra Unicode planes
+  , nonBmp
+  ) where
+
+import Prelude hiding (replicate)
+import Control.Applicative ((<$>))
+import Data.Text (Text, pack, singleton, replicate)
+import Test.SmallCheck.Series
+
+-- | Create a 'Data.Text.Text' 'Series' growing with an extra 'a' 'Char'.
+--
+-- >>> list 4 aaa
+-- ["","a","aa","aaa","aaaa"]
+--
+-- Use this when you don't care about the 'Char's inside 'Data.Text.Text'.
+aaa :: Series m Text
+aaa = replicated 'a'
+
+-- | Create a 'Data.Text.Text' 'Series' growing with an extra @NUL@ 'Char'.
+--
+-- >>> list 4 zzz
+-- ["","\NUL","\NUL\NUL","\NUL\NUL\NUL","\NUL\NUL\NUL\NUL"]
+zzz :: Series m Text
+zzz = replicated '\0'
+
+-- | Create a 'Data.Text.Text' 'Series' growing with an extra custom 'Char'.
+--
+-- >>> list 4 $ replicated '☃'
+-- ["","\9731","\9731\9731","\9731\9731\9731","\9731\9731\9731\9731"]
+replicated :: Char -> Series m Text
+replicated c = generate $ \d -> (`replicate` singleton c) <$> [0..d]
+
+-- | Create a 'Data.Text.Text' 'Series' growing with the alphabet.
+--
+-- >>> list 4 alpha
+-- ["","a","ab","abc","abcd"]
+alpha :: Series m Text
+alpha = enumerated ['a'..'z']
+
+-- | Create a 'Data.Text.Text' 'Series' growing with @ASCII@ 'Char's set.
+--
+-- >>> list 4 ascii
+-- ["","\NUL","\NUL\SOH","\NUL\SOH\STX","\NUL\SOH\STX\ETX"]
+ascii :: Series m Text
+ascii = enumerated ['\0'..'\255']
+
+-- | Create a 'Data.Text.Text' 'Series' growing with the given 'Char' set.
+--
+-- >>> list 4 $ enumerated "abc"
+-- ["","a","ab","abc","abc"]
+enumerated :: String -> Series m Text
+enumerated cs = generate $ \d -> (\n -> pack $ take n cs) <$> [0..d]
+
+-- | Create a 'Data.Text.Text' 'Series' with a dummy sentence. This can
+--   be used when you want to print a 'Series' to the screen.
+--
+-- >>> let s = list 20 jack
+-- >>> take 3 s
+-- ["","All","All work"]
+-- >>> s !! 10
+-- "All work and no play makes Jack a dull boy"
+jack :: Series m Text
+jack = generate $ \d ->
+    (\n -> pack . unwords . take n . words $ sentence) <$> [0..d]
+  where
+    sentence = "All work and no play makes Jack a dull boy"
+
+-- | Create a 'Data.Text.Text' 'Series' with the first character of each
+--   <https://en.wikipedia.org/wiki/Plane_(Unicode) Unicode plane>.
+--
+-- >>> list 3 nonBmp
+-- ["","\NUL","\NUL\65536","\NUL\65536\131072"]
+--
+-- Notice that this covers the 16 unicode planes.
+--
+-- >>> last (list 16 nonBmp) == last (list 17 nonBmp)
+-- True
+nonBmp :: Series m Text
+nonBmp = enumerated ['\0','\x10000'..'\xF0000']
diff --git a/Test/SmallCheck/Series/Text/Lazy.hs b/Test/SmallCheck/Series/Text/Lazy.hs
new file mode 100644
--- /dev/null
+++ b/Test/SmallCheck/Series/Text/Lazy.hs
@@ -0,0 +1,99 @@
+{-|
+Following the convention from "Data.Text.Lazy", this module is intended to be
+imported @qualified@. For example:
+
+> import qualified Test.SmallCheck.Series.Text.Lazy as L.Series
+-}
+module Test.SmallCheck.Series.Text.Lazy
+  (
+  -- * Replication
+    aaa
+  , zzz
+  , replicated
+  -- * Enumeration
+  , ascii
+  , alpha
+  , enumerated
+  -- * Printing
+  , jack
+  -- * Extra Unicode planes
+  , nonBmp
+  ) where
+
+import Prelude hiding (replicate)
+import Control.Applicative ((<$>))
+import Data.Text.Lazy (Text, pack, singleton, replicate)
+import Test.SmallCheck.Series
+
+-- | Create a 'Data.Text.Lazy.Text' 'Series' growing with an extra 'a' 'Char'.
+--
+-- >>> list 4 aaa
+-- ["","a","aa","aaa","aaaa"]
+--
+-- Use this when you don't care about the 'Char's inside 'Data.Text.Lazy.Text'.
+aaa :: Series m Text
+aaa = replicated 'a'
+
+-- | Create a 'Data.Text.Lazy.Text' 'Series' growing with an extra @NUL@ 'Char'.
+--
+-- >>> list 4 zzz
+-- ["","\NUL","\NUL\NUL","\NUL\NUL\NUL","\NUL\NUL\NUL\NUL"]
+zzz :: Series m Text
+zzz = replicated '\0'
+
+-- | Create a 'Data.Text.Lazy.Text' 'Series' growing with an extra custom 'Char'.
+--
+-- >>> list 4 $ replicated '☃'
+-- ["","\9731","\9731\9731","\9731\9731\9731","\9731\9731\9731\9731"]
+replicated :: Char -> Series m Text
+replicated c = generate $ \d -> (`rep` singleton c) <$> [0..d]
+  where
+    rep = replicate . fromIntegral
+
+-- | Create a 'Data.Text.Lazy.Text' 'Series' growing with the alphabet.
+--
+-- >>> list 4 alpha
+-- ["","a","ab","abc","abcd"]
+alpha :: Series m Text
+alpha = enumerated ['a'..'z']
+
+-- | Create a 'Data.Text.Lazy.Text' 'Series' growing with @ASCII@ 'Char's set.
+--
+-- >>> list 4 ascii
+-- ["","\NUL","\NUL\SOH","\NUL\SOH\STX","\NUL\SOH\STX\ETX"]
+ascii :: Series m Text
+ascii = enumerated ['\0'..'\255']
+
+-- | Create a 'Data.Text.Lazy.Text' 'Series' growing with the given 'Char' set.
+--
+-- >>> list 4 $ enumerated "abc"
+-- ["","a","ab","abc","abc"]
+enumerated :: String -> Series m Text
+enumerated cs = generate $ \d -> (\n -> pack $ take n cs) <$> [0..d]
+
+-- | Create a 'Data.Text.Lazy.Text' 'Series' with a dummy sentence. This can
+--   be used when you want to print a 'Series' to the screen.
+--
+-- >>> let s = list 20 jack
+-- >>> take 3 s
+-- ["","All","All work"]
+-- >>> s !! 10
+-- "All work and no play makes Jack a dull boy"
+jack :: Series m Text
+jack = generate $ \d ->
+    (\n -> pack . unwords . take n . words $ sentence) <$> [0..d]
+  where
+    sentence = "All work and no play makes Jack a dull boy"
+
+-- | Create a 'Data.Text.Lazy.Text' 'Series' with the first character of each
+--   <https://en.wikipedia.org/wiki/Plane_(Unicode) Unicode plane>.
+--
+-- >>> list 3 nonBmp
+-- ["","\NUL","\NUL\65536","\NUL\65536\131072"]
+--
+-- Notice that this covers the 16 unicode planes.
+--
+-- >>> last (list 16 nonBmp) == last (list 17 nonBmp)
+-- True
+nonBmp :: Series m Text
+nonBmp = enumerated ['\0','\x10000'..'\xF0000']
diff --git a/smallcheck-series.cabal b/smallcheck-series.cabal
new file mode 100644
--- /dev/null
+++ b/smallcheck-series.cabal
@@ -0,0 +1,44 @@
+name:                smallcheck-series
+version:             0.1
+synopsis:            Extra series for smallcheck
+description:
+  Utilities for creating @SmallCheck@ @Series@ and orphan @Serial@
+  instances for frequently used types coming with GHC core libraries.
+homepage:            https://github.com/jdnavarro/smallcheck-series
+bug-reports:         https://github.com/jdnavarro/smallcheck-series/issues
+license:             BSD3
+license-file:        LICENSE
+author:              Danny Navarro
+maintainer:          j@dannynavarro.net
+category:            Testing
+build-type:          Simple
+extra-source-files:  README.md CHANGELOG.md
+cabal-version:       >=1.10
+
+source-repository head
+  type: git
+  location: git://github.com/jdnavarro/smallcheck-series.git
+
+
+library
+  exposed-modules:     Test.SmallCheck.Series.ByteString
+                       Test.SmallCheck.Series.ByteString.Lazy
+                       Test.SmallCheck.Series.Instances
+                       Test.SmallCheck.Series.Text
+                       Test.SmallCheck.Series.Text.Lazy
+  build-depends:       base >=4.6 && <4.9,
+                       bytestring >= 0.10.0,
+                       text >= 0.11.3,
+                       smallcheck >= 1.1
+  default-language:    Haskell2010
+  ghc-options:         -Wall
+
+test-suite doctests
+  default-language:    Haskell2010
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      tests
+  main-is:             doctests.hs
+  ghc-options:         -Wall -threaded
+  build-depends:       base >= 4.6 && <4.9,
+                       Glob >= 0.7.5,
+                       doctest >= 0.9.10
diff --git a/tests/doctests.hs b/tests/doctests.hs
new file mode 100644
--- /dev/null
+++ b/tests/doctests.hs
@@ -0,0 +1,10 @@
+module Main where
+
+import System.FilePath.Glob (glob)
+import Test.DocTest (doctest)
+
+main :: IO ()
+main = doctest . ([ "-idist/build/autogen"
+                  , "-optP-include"
+                  , "-optPdist/build/autogen/cabal_macros.h"
+                  ] ++) =<< glob "Test/**/*.hs"
