diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2014, Yoshikuni Jujo
+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 the Yoshikuni Jujo nor the names of its
+    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 EVEN SHALL THE COPYRIGHT HOLDER 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/bytable.cabal b/bytable.cabal
new file mode 100644
--- /dev/null
+++ b/bytable.cabal
@@ -0,0 +1,37 @@
+cabal-version:	>= 1.6
+build-type:	Simple
+
+name:		bytable
+version:	0.0.0.0
+stability:	Experimental
+author:		Yoshikuni Jujo <PAF01143@nifty.ne.jp>
+maintainer:	Yoshikuni Jujo <PAF01143@nifty.ne.jp>
+
+license:	BSD3
+license-file:	LICENSE
+
+category:	Codec
+synopsis:	data from/to ByteString
+description:
+    You can read data from ByteString.
+    .
+    > some = do
+    >     x <- take 4
+    >     y <- take 8
+    >     return (x :: Int, y :: Integer)
+    .
+
+source-repository	head
+    type:	git
+    location:	git://github.com/YoshikuniJujo/forest
+
+source-repository	this
+    type:	git
+    location:	git://github.com/YoshikuniJujo/forest
+    tag:	bytable-0.0.0.0
+
+library
+    hs-source-dirs:	src
+    exposed-modules:	Codec.Bytable, Codec.Bytable.BigEndian
+    build-depends:	base == 4.*, bytestring == 0.10.*
+    ghc-options:	-Wall
diff --git a/src/Codec/Bytable.hs b/src/Codec/Bytable.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Bytable.hs
@@ -0,0 +1,45 @@
+{-# LANGUAGE TupleSections #-}
+
+module Codec.Bytable (BytableM(..), Bytable(..), head, take, null) where
+
+import Prelude hiding (take, head, null)
+import Control.Applicative(Applicative(..), (<$>))
+import Control.Monad (unless, liftM, ap)
+import Data.Word (Word8)
+import qualified Data.ByteString as BS
+
+data BytableM a = BytableM {
+	runBytableM :: BS.ByteString -> Either String (a, BS.ByteString) }
+
+instance Monad BytableM where
+	return x = BytableM $ \bs -> Right (x, bs)
+	BytableM m1 >>= f = BytableM $ \bs -> do
+		(x, bs') <- m1 bs
+		runBytableM (f x) bs'
+	fail = BytableM . const . Left
+
+instance Functor BytableM where
+	fmap = liftM
+
+instance Applicative BytableM where
+	pure = return
+	(<*>) = ap
+
+class Bytable b where
+	fromByteString :: BS.ByteString -> Either String b
+	toByteString :: b -> BS.ByteString
+
+head :: BytableM Word8
+head = BytableM $ \bs -> case BS.uncons bs of
+	Just (h, t) -> Right (h, t)
+	_ -> Left "Bytable.head: null"
+
+take :: Bytable b => Int -> BytableM b
+take n = BytableM $ \bs -> do
+	unless (BS.length bs >= n) .  Left $
+		"Bytable.take: length shorter than " ++ show n
+	let (x, bs') = BS.splitAt n bs
+	(, bs') <$> fromByteString x
+
+null :: BytableM Bool
+null  = BytableM $ \bs -> Right (BS.null bs, bs)
diff --git a/src/Codec/Bytable/BigEndian.hs b/src/Codec/Bytable/BigEndian.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Bytable/BigEndian.hs
@@ -0,0 +1,47 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Codec.Bytable.BigEndian () where
+
+import Data.Bits
+import Data.Word
+import Codec.Bytable
+import qualified Data.ByteString as BS
+
+instance Bytable Int where
+	fromByteString bs
+		| BS.length bs <= 4 = Right $ byteStringToNum bs
+		| otherwise = Left
+			"Codec.Bytable.BigEndian: Bytable Int: too large"
+	toByteString = integralToByteString
+
+instance Bytable Integer where
+	fromByteString bs = Right $ byteStringToNum bs
+	toByteString = integralToByteString
+
+instance Bytable Word16 where
+	fromByteString bs
+		| BS.length bs <= 2 = Right $ byteStringToNum bs
+		| otherwise = Left
+			"Codec.Bytable.BigEndian: Bytable Word16: too large"
+	toByteString = integralToByteString
+
+instance Bytable Word32 where
+	fromByteString bs
+		| BS.length bs <= 4 = Right $ byteStringToNum bs
+		| otherwise = Left
+			"Codec.Bytable.BigEndian: Bytable Word32: too large"
+	toByteString = integralToByteString
+
+byteStringToNum :: (Num n, Bits n) => BS.ByteString -> n
+byteStringToNum = wordsToNum . reverse . BS.unpack
+
+wordsToNum :: (Num n, Bits n) => [Word8] -> n
+wordsToNum [] = 0
+wordsToNum (w : ws) = fromIntegral w .|. wordsToNum ws `shiftL` 8
+
+integralToByteString :: (Integral n, Bits n) => n -> BS.ByteString
+integralToByteString = BS.pack . reverse . integralToWords
+
+integralToWords :: (Integral n, Bits n) => n -> [Word8]
+integralToWords 0 = []
+integralToWords n = fromIntegral n : integralToWords (n `shiftR` 8)
