diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Joe Hermaszewski (c) 2016
+
+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 Joe Hermaszewski 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/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/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,4 @@
+# Change Log
+
+## [0.1.0.0] - 2016-02-28
+Initial release.
diff --git a/readme.md b/readme.md
new file mode 100644
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,13 @@
+# Vector Sized
+
+This package exports a newtype tagging the vectors from the
+[vector](https://hackage.haskell.org/package/vector) package with a type level
+natural representing their size.
+
+It also exports a few functions from vector appropriately retyped.
+
+This package is fairly similar to the
+[fixed-vector](https://hackage.haskell.org/package/fixed-vector) package. The
+difference is that fixed-vector uses Peano naturals to represent the size tag
+on the vectors and this package uses typelits.
+
diff --git a/src/Data/Vector/Generic/Sized.hs b/src/Data/Vector/Generic/Sized.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Generic/Sized.hs
@@ -0,0 +1,175 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
+
+module Data.Vector.Generic.Sized
+ ( Vector
+    -- * Construction
+  , fromVector
+  , replicate
+  , singleton
+  , generate
+    -- * Monadic Construction
+  , generateM
+    -- * Elimination
+  , length
+  , index
+  , head
+  , last
+    -- * Extract subsets
+  , tail
+  , init
+  , take
+  , drop
+    -- * Mapping
+  , map
+    -- * Monadic Mapping
+  , imapM_
+    -- * Folding
+  , foldl'
+  , foldl1'
+  ) where
+
+import qualified Data.Vector.Generic as VG
+import qualified Data.Vector.Storable as VS
+import GHC.TypeLits
+import Data.Proxy
+import Control.DeepSeq
+import Foreign.Storable
+import Foreign.Ptr (castPtr)
+import Prelude hiding (replicate, head, last,
+                       tail, init, map, length, drop, take)
+
+newtype Vector v (n :: Nat) a = Vector (v a)
+  deriving (Show, Eq, Ord, Foldable, NFData)
+
+instance (KnownNat n, Storable a) 
+      => Storable (Vector VS.Vector n a) where
+  sizeOf _ = sizeOf (undefined :: a) * fromIntegral (natVal (Proxy :: Proxy n))
+  alignment _ = alignment (undefined :: a)
+  peek ptr = generateM (Proxy :: Proxy n) (peekElemOff (castPtr ptr))
+  poke ptr = imapM_ (pokeElemOff (castPtr ptr))
+
+-- | Convert a 'Data.Vector.Generic.Vector' into a
+-- 'Data.Vector.Generic.Sized.Vector' if it has the correct size, otherwise
+-- return Nothing.
+fromVector :: forall a v (n :: Nat). (KnownNat n, VG.Vector v a)
+           => v a -> Maybe (Vector v n a)
+fromVector v
+  | n' == fromIntegral (VG.length v) = Just (Vector v)
+  | otherwise                        = Nothing
+  where n' = natVal (Proxy :: Proxy n)
+{-# INLINE fromVector #-}
+
+-- | /O(1)/ construct a single element vector.
+singleton :: forall a v. (VG.Vector v a)
+          => a -> Vector v 1 a
+singleton a = Vector (VG.singleton a)
+{-# INLINE singleton #-}
+
+-- | /O(n)/ construct a vector of the given length by applying the function to
+-- each index.
+generate :: forall (n :: Nat) a v. (VG.Vector v a, KnownNat n)
+         => Proxy n -> (Int -> a) -> Vector v n a
+generate n f = Vector (VG.generate (fromIntegral $ natVal n) f)
+{-# INLINE generate #-}
+
+-- | /O(n)/ construct a vector of the given length by applying the monadic
+-- action to each index.
+generateM :: forall (n :: Nat) a v m. (VG.Vector v a, KnownNat n, Monad m)
+         => Proxy n -> (Int -> m a) -> m (Vector v n a)
+generateM n f = Vector <$> VG.generateM (fromIntegral $ natVal n) f
+{-# INLINE generateM #-}
+
+-- | Apply a function on unsized vectors to a sized vector. The function must
+-- preserve the size of the vector, this is not checked.
+withVectorUnsafe :: forall a b v (n :: Nat). (VG.Vector v a, VG.Vector v b)
+                 => (v a -> v b) -> Vector v n a -> Vector v n b
+withVectorUnsafe f (Vector v) = Vector (f v)
+{-# INLINE withVectorUnsafe #-}
+
+-- | /O(1)/ Index safely into the vector using a type level index.
+index :: forall (m :: Nat) a v (n :: Nat). (KnownNat n, KnownNat m, VG.Vector v a)
+      => Vector v (m+n) a -> Proxy n -> a
+index (Vector v) i = v `VG.unsafeIndex` fromIntegral (natVal i)
+{-# INLINE index #-}
+
+-- | /O(1)/ Yield the first n elements. The resultant vector always contains
+-- this many elements.
+take :: forall (m :: Nat) a v (n :: Nat). (KnownNat n, KnownNat m, VG.Vector v a)
+     => Proxy n -> Vector v (m+n) a -> Vector v n a
+take i (Vector v) = Vector (VG.take (fromIntegral $ natVal i) v)
+{-# INLINE take #-}
+
+-- | /O(1)/ Yield all but the first n elements.
+drop :: forall (m :: Nat) a v (n :: Nat). (KnownNat n, KnownNat m, VG.Vector v a)
+     => Proxy n -> Vector v (m+n) a -> Vector v m a
+drop i (Vector v) = Vector (VG.drop (fromIntegral $ natVal i) v)
+{-# INLINE drop #-}
+
+-- | /O(1)/ Get the length of the vector.
+length :: forall a v (n :: Nat). (VG.Vector v a)
+       => Vector v n a -> Int
+length (Vector v) = VG.length v
+{-# INLINE length #-}
+
+-- | /O(1)/ Get the first element of a non-empty vector.
+head :: forall a v (n :: Nat). (VG.Vector v a)
+     => Vector v (n+1) a -> a
+head (Vector v) = VG.head v
+{-# INLINE head #-}
+
+-- | /O(1)/ Get the last element of a non-empty vector.
+last :: forall a v (n :: Nat). (VG.Vector v a)
+     => Vector v (n+1) a -> a
+last (Vector v) = VG.last v
+{-# INLINE last #-}
+
+-- | /O(1)/ Yield all but the first element of a non-empty vector without
+-- copying.
+tail :: forall a v (n :: Nat). (VG.Vector v a)
+     => Vector v (n+1) a -> Vector v n a
+tail (Vector v) = Vector (VG.tail v)
+{-# INLINE tail #-}
+
+-- | /O(1)/ Yield all but the last element of a non-empty vector without
+-- copying.
+init :: forall a v (n :: Nat). (VG.Vector v a)
+     => Vector v (n+1) a -> Vector v n a
+init (Vector v) = Vector (VG.init v)
+{-# INLINE init #-}
+
+-- | /O(n)/ Construct a vector with the same element in each position.
+replicate :: forall a v (n :: Nat). (VG.Vector v a, KnownNat n)
+          => a -> Vector v n a
+replicate a = Vector (VG.replicate (fromIntegral $ natVal (Proxy :: Proxy n)) a)
+{-# INLINE replicate #-}
+
+-- | /O(n)/ Map a function over the vector.
+map :: forall a b v (n :: Nat). (VG.Vector v a, VG.Vector v b)
+    => (a -> b) -> Vector v n a -> Vector v n b
+map f = withVectorUnsafe (VG.map f)
+{-# INLINE map #-}
+
+-- | /O(n)/ Apply the monadic action to every element of a vector and its
+-- index, ignoring the results.
+imapM_ :: forall a v n b m. (VG.Vector v a, Monad m)
+       => (Int -> a -> m b) -> Vector v n a -> m ()
+imapM_ f (Vector v) = VG.imapM_ f v
+{-# INLINE imapM_ #-}
+
+-- | /O(n)/ Left fold with a strict accumulator.
+foldl' :: forall a b v (n :: Nat). VG.Vector v b
+       => (a -> b -> a) -> a -> Vector v n b -> a
+foldl' f z (Vector v) = VG.foldl' f z v
+{-# INLINE foldl' #-}
+
+-- | /O(n)/ Left fold on a non-empty vector with a strict accumulator.
+foldl1' :: forall a v (n :: Nat). (VG.Vector v a)
+        => (a -> a -> a) -> Vector v (n+1) a -> a
+foldl1' f (Vector v) = VG.foldl1' f v
+{-# INLINE foldl1' #-}
diff --git a/src/Data/Vector/Storable/Sized.hs b/src/Data/Vector/Storable/Sized.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Storable/Sized.hs
@@ -0,0 +1,136 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DataKinds #-}
+
+module Data.Vector.Storable.Sized
+ ( Vector
+    -- * Construction
+  , fromVector
+  , replicate
+  , singleton
+  , generate
+    -- * Elimination
+  , length
+  , index
+  , head
+  , last
+    -- * Extract subsets
+  , tail
+  , init
+  , take
+  , drop
+    -- * Mapping
+  , map
+    -- * Folding
+  , foldl'
+  , foldl1'
+  ) where
+
+import qualified Data.Vector.Generic.Sized as VGS
+import qualified Data.Vector.Storable as VS
+import GHC.TypeLits
+import Data.Proxy
+import Foreign.Storable
+import Prelude hiding (replicate, head, last,
+                       tail, init, map, length, drop, take)
+
+type Vector = VGS.Vector VS.Vector
+
+-- | Convert a 'Data.Vector.Generic.Vector' into a
+-- 'Data.Vector.Generic.Sized.Vector' if it has the correct size, otherwise
+-- return Nothing.
+fromVector :: forall a (n :: Nat). (KnownNat n, Storable a)
+           => VS.Vector a -> Maybe (Vector n a)
+fromVector = VGS.fromVector
+{-# INLINE fromVector #-}
+
+-- | /O(1)/ construct a single element vector.
+singleton :: forall a. Storable a
+          => a -> Vector 1 a
+singleton = VGS.singleton
+{-# INLINE singleton #-}
+
+-- | /O(n)/ construct a vector of the given length by applying the function to
+-- each index.
+generate :: forall (n :: Nat) a. (Storable a, KnownNat n)
+         => Proxy n -> (Int -> a) -> Vector n a
+generate = VGS.generate
+{-# INLINE generate #-}
+
+-- | /O(1)/ Index safely into the vector using a type level index.
+index :: forall (m :: Nat) a (n :: Nat). (KnownNat n, KnownNat m, Storable a)
+      => Vector (m+n) a -> Proxy n -> a
+index = VGS.index
+{-# INLINE index #-}
+
+-- | /O(1)/ Yield the first n elements. The resultant vector always contains
+-- this many elements.
+take :: forall (m :: Nat) a (n :: Nat). (KnownNat n, KnownNat m, Storable a)
+     => Proxy n -> Vector (m+n) a -> Vector n a
+take = VGS.take
+{-# INLINE take #-}
+
+-- | /O(1)/ Yield all but the first n elements.
+drop :: forall (m :: Nat) a (n :: Nat). (KnownNat n, KnownNat m, Storable a)
+     => Proxy n -> Vector (m+n) a -> Vector m a
+drop = VGS.drop
+{-# INLINE drop #-}
+
+-- | /O(1)/ Get the length of the vector.
+length :: forall a (n :: Nat). (Storable a)
+       => Vector n a -> Int
+length = VGS.length
+{-# INLINE length #-}
+
+-- | /O(1)/ Get the first element of a non-empty vector.
+head :: forall a (n :: Nat). (Storable a)
+     => Vector (n+1) a -> a
+head = VGS.head
+{-# INLINE head #-}
+
+-- | /O(1)/ Get the last element of a non-empty vector.
+last :: forall a (n :: Nat). (Storable a)
+     => Vector (n+1) a -> a
+last = VGS.last
+{-# INLINE last #-}
+
+-- | /O(1)/ Yield all but the first element of a non-empty vector without
+-- copying.
+tail :: forall a (n :: Nat). (Storable a)
+     => Vector (n+1) a -> Vector n a
+tail = VGS.tail
+{-# INLINE tail #-}
+
+-- | /O(1)/ Yield all but the last element of a non-empty vector without
+-- copying.
+init :: forall a (n :: Nat). (Storable a)
+     => Vector (n+1) a -> Vector n a
+init = VGS.init
+{-# INLINE init #-}
+
+-- | /O(n)/ Construct a vector with the same element in each position.
+replicate :: forall a (n :: Nat). (Storable a, KnownNat n)
+          => a -> Vector n a
+replicate = VGS.replicate
+{-# INLINE replicate #-}
+
+-- | /O(n)/ Map a function over the vector.
+map :: forall a b (n :: Nat). (Storable a, Storable b)
+    => (a -> b) -> Vector n a -> Vector n b
+map = VGS.map
+{-# INLINE map #-}
+
+-- | /O(n)/ Left fold with a strict accumulator.
+foldl' :: forall a b (n :: Nat). Storable b
+       => (a -> b -> a) -> a -> Vector n b -> a
+foldl' = VGS.foldl'
+{-# INLINE foldl' #-}
+
+-- | /O(n)/ Left fold on a non-empty vector with a strict accumulator.
+foldl1' :: forall a (n :: Nat). Storable a
+        => (a -> a -> a) -> Vector (n+1) a -> a
+foldl1' = VGS.foldl1'
+{-# INLINE foldl1' #-}
diff --git a/vector-sized.cabal b/vector-sized.cabal
new file mode 100644
--- /dev/null
+++ b/vector-sized.cabal
@@ -0,0 +1,28 @@
+name:                vector-sized
+version:             0.1.0.0
+synopsis:            Size tagged vectors
+description:         Please see README.md
+homepage:            http://github.com/expipiplus1/vector-sized#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Joe Hermaszewski
+maintainer:          whats.our.vector.victor@monoid.al
+copyright:           2016 Joe Hermaszewski
+category:            Data
+build-type:          Simple
+extra-source-files:  readme.md
+                   , changelog.md
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Data.Vector.Generic.Sized
+                     , Data.Vector.Storable.Sized
+  build-depends:       base >= 4.7 && < 5
+                     , vector >= 0.11 && < 0.12
+                     , deepseq >= 1.1 && < 1.5
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/expipiplus1/vector-sized
