diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,11 @@
+# Changelog for `zlib-core`
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to the
+[Haskell Package Versioning Policy](https://pvp.haskell.org/).
+
+## Unreleased
+
+## 0.1.0.0 - YYYY-MM-DD
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2025 Yoshikuni Jujo
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1.  Redistributions of source code must retain the above copyright notice, this
+    list of conditions and the following disclaimer.
+
+2.  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.
+
+3.  Neither the name of the copyright holder 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 EVENT 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/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# zlib-core
+
+This package used by package zlib-yaftee.
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/src/Codec/Compression/Zlib/Advanced/Core.hsc b/src/Codec/Compression/Zlib/Advanced/Core.hsc
new file mode 100644
--- /dev/null
+++ b/src/Codec/Compression/Zlib/Advanced/Core.hsc
@@ -0,0 +1,62 @@
+{-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Codec.Compression.Zlib.Advanced.Core (
+
+	deflateInit2,
+	inflateInit2,
+
+	WindowBits,
+	pattern WindowBitsZlibHeader,
+	pattern WindowBitsZlib, pattern WindowBitsRaw,
+	pattern WindowBitsGzip, pattern WindowBitsZlibAndGzip,
+
+	) where
+
+import Foreign.Ptr
+import Control.Monad.Primitive
+import Data.Word.ToolsYj
+import Data.Int
+
+import Codec.Compression.Zlib.Structure.Core
+import Codec.Compression.Zlib.Constant.Core
+
+newtype WindowBits = WindowBits #{type int} deriving Show
+
+pattern WindowBitsZlibHeader :: WindowBits
+pattern WindowBitsZlibHeader = WindowBits 0
+
+pattern WindowBitsZlib :: Word4 -> WindowBits
+pattern WindowBitsZlib bs <- WindowBits (fromIntegral -> bs) where
+	WindowBitsZlib bs = WindowBits $ fromIntegral bs
+
+pattern WindowBitsRaw :: Word4 -> WindowBits
+pattern WindowBitsRaw bs <- WindowBits (fromIntegral . negate -> bs) where
+	WindowBitsRaw bs = WindowBits . negate $ fromIntegral bs
+
+pattern WindowBitsGzip :: Word4 -> WindowBits
+pattern WindowBitsGzip bs <- WindowBits (fromIntegral . subtract 16 -> bs) where
+	WindowBitsGzip bs = WindowBits $ fromIntegral bs + 16
+
+pattern WindowBitsZlibAndGzip :: Word4 -> WindowBits
+pattern WindowBitsZlibAndGzip bs <- WindowBits (fromIntegral . subtract 32 -> bs) where
+	WindowBitsZlibAndGzip bs = WindowBits $ fromIntegral bs + 32
+
+deflateInit2 :: PrimBase m =>
+	StreamPrim (PrimState m) -> CompressionLevel -> CompressionMethod ->
+	WindowBits -> MemLevel -> CompressionStrategy -> m ReturnCode
+deflateInit2 strm lvl mtd wbs ml str = withStreamPtr strm
+	$ unsafeIOToPrim . (\pstrm -> c_deflateInit2 pstrm lvl mtd wbs ml str)
+
+foreign import capi "zlib.h deflateInit2" c_deflateInit2 ::
+	Ptr Stream -> CompressionLevel -> CompressionMethod -> WindowBits ->
+	MemLevel -> CompressionStrategy -> IO ReturnCode
+
+inflateInit2 :: PrimBase m =>
+	StreamPrim (PrimState m) -> WindowBits -> m ReturnCode
+inflateInit2 strm wbs =
+	withStreamPtr strm $ unsafeIOToPrim . (`c_inflateInit2` wbs)
+
+foreign import capi "zlib.h inflateInit2" c_inflateInit2 ::
+	Ptr Stream -> WindowBits -> IO ReturnCode
diff --git a/src/Codec/Compression/Zlib/Basic/Core.hsc b/src/Codec/Compression/Zlib/Basic/Core.hsc
new file mode 100644
--- /dev/null
+++ b/src/Codec/Compression/Zlib/Basic/Core.hsc
@@ -0,0 +1,56 @@
+{-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE BlockArguments #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Codec.Compression.Zlib.Basic.Core (
+
+	zlibVersion,
+
+	deflateInit, deflate, deflateEnd,
+	inflateInit, inflate, inflateEnd
+
+	) where
+
+import Foreign.Ptr
+import Foreign.C.String
+import Control.Monad.Primitive
+import System.IO.Unsafe
+
+import Codec.Compression.Zlib.Structure.Core
+import Codec.Compression.Zlib.Constant.Core
+
+zlibVersion :: String
+zlibVersion = unsafePerformIO $ peekCString c_zlibVersion
+
+deflateInit :: PrimBase m =>
+	StreamPrim (PrimState m) -> CompressionLevel -> m ReturnCode
+deflateInit strm cl = withStreamPtr strm $ unsafeIOToPrim . (`c_deflateInit` cl)
+
+deflate :: PrimBase m => StreamPrim (PrimState m) -> Flush -> m ReturnCode
+deflate strm fls = withStreamPtr strm $ unsafeIOToPrim . (`c_deflate` fls)
+
+deflateEnd :: PrimBase m => StreamPrim (PrimState m) -> m ReturnCode
+deflateEnd strm = withStreamPtr strm $ unsafeIOToPrim . c_deflateEnd
+
+inflateInit :: PrimBase m => StreamPrim (PrimState m) -> m ReturnCode
+inflateInit strm = withStreamPtr strm $ unsafeIOToPrim . c_inflateInit
+
+inflate :: PrimBase m => StreamPrim (PrimState m) -> Flush -> m ReturnCode
+inflate strm fls = withStreamPtr strm \s -> unsafeIOToPrim $ c_inflate s fls
+
+inflateEnd :: PrimBase m => StreamPrim (PrimState m) -> m ReturnCode
+inflateEnd strm = withStreamPtr strm $ unsafeIOToPrim . c_inflateEnd
+
+foreign import ccall "zlibVersion" c_zlibVersion :: CString
+
+foreign import capi "zlib.h deflateInit" c_deflateInit :: Ptr Stream -> CompressionLevel -> IO ReturnCode
+
+foreign import ccall "deflate" c_deflate :: Ptr Stream -> Flush -> IO ReturnCode
+
+foreign import ccall "deflateEnd" c_deflateEnd :: Ptr Stream -> IO ReturnCode
+
+foreign import capi "zlib.h inflateInit" c_inflateInit :: Ptr Stream -> IO ReturnCode
+
+foreign import ccall "inflate" c_inflate :: Ptr Stream -> Flush -> IO ReturnCode
+
+foreign import ccall "inflateEnd" c_inflateEnd :: Ptr Stream -> IO ReturnCode
diff --git a/src/Codec/Compression/Zlib/Constant/Core.hsc b/src/Codec/Compression/Zlib/Constant/Core.hsc
new file mode 100644
--- /dev/null
+++ b/src/Codec/Compression/Zlib/Constant/Core.hsc
@@ -0,0 +1,113 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Codec.Compression.Zlib.Constant.Core (
+
+	-- * RETURN CODE
+
+	ReturnCode(..),
+	pattern Ok,
+	pattern StreamEnd,
+	pattern NeedDict,
+	pattern Errno,
+	pattern StreamError,
+	pattern DataError,
+	pattern MemError,
+	pattern BufError,
+	pattern VersionError,
+
+	-- * FLUSH
+
+	Flush(..),
+	pattern NoFlush,
+	pattern PartialFlush,
+	pattern SyncFlush,
+	pattern FullFlush,
+	pattern Finish,
+	pattern Block,
+	pattern Trees,
+
+
+	-- * MEM LEVEL
+
+	MemLevel(..),
+
+	-- * COMPRESSION STRATEGY
+
+	CompressionStrategy(..),
+	pattern Filtered,
+	pattern HuffmanOnly,
+	pattern Rle,
+	pattern Fixed,
+	pattern DefaultStrategy,
+
+	-- * COMPRESSION LEVEL
+
+	CompressionLevel(..),
+	pattern NoCompression,
+	pattern BestSpeed,
+	pattern BestCompression,
+	pattern DefaultCompression,
+
+	-- * COMPRESSION METHOD
+
+	CompressionMethod(..),
+	pattern Deflated
+
+	) where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Control.Exception.Hierarchy
+import Data.Int
+
+#include <zlib.h>
+
+enum "Flush" ''#{type int} [''Show, ''Read, ''Eq] [
+	("NoFlush", #{const Z_NO_FLUSH}),
+	("PartialFlush", #{const Z_PARTIAL_FLUSH}),
+	("SyncFlush", #{const Z_SYNC_FLUSH}),
+	("FullFlush", #{const Z_FULL_FLUSH}),
+	("Finish", #{const Z_FINISH}),
+	("Block", #{const Z_BLOCK}),
+	("Trees", #{const Z_TREES}) ]
+
+enum "ReturnCode" ''#{type int} [''Show, ''Read, ''Eq] [
+	("Ok", #{const Z_OK}),
+	("StreamEnd", #{const Z_STREAM_END}),
+	("NeedDict", #{const Z_NEED_DICT}),
+	("Errno", #{const Z_ERRNO}),
+	("StreamError", #{const Z_STREAM_ERROR}),
+	("DataError", #{const Z_DATA_ERROR}),
+	("MemError", #{const Z_MEM_ERROR}),
+	("BufError", #{const Z_BUF_ERROR}),
+	("VersionError", #{const Z_VERSION_ERROR}) ]
+
+exceptionHierarchy Nothing (ExType ''ReturnCode)
+
+enum "CompressionLevel" ''#{type int} [''Show, ''Read, ''Eq] [
+	("NoCompression", #{const Z_NO_COMPRESSION}),
+	("BestSpeed", #{const Z_BEST_SPEED}),
+	("BestCompression", #{const Z_BEST_COMPRESSION}),
+	("DefaultCompression", #{const Z_DEFAULT_COMPRESSION}) ]
+
+enum "CompressionStrategy" ''#{type int} [''Show, ''Read, ''Eq] [
+	("Filtered", #{const Z_FILTERED}),
+	("HuffmanOnly", #{const Z_HUFFMAN_ONLY}),
+	("Rle", #{const Z_RLE}),
+	("Fixed", #{const Z_FIXED}),
+	("DefaultStrategy", #{const Z_DEFAULT_STRATEGY}) ]
+
+enum "DataType" ''#{type int} [''Show, ''Read, ''Eq, ''Storable] [
+	("Binary", #{const Z_BINARY}),
+	("Text", #{const Z_TEXT}),
+	("Ascii", #{const Z_ASCII}),
+	("Unknown", #{const Z_UNKNOWN}) ]
+
+enum "CompressionMethod" ''#{type int} [''Show, ''Read, ''Eq] [
+	("Deflated", #{const Z_DEFLATED}) ]
+
+enum "MemLevel" ''#{type int} [''Show, ''Read, ''Eq] [
+	]
diff --git a/src/Codec/Compression/Zlib/Gzip/Core.hsc b/src/Codec/Compression/Zlib/Gzip/Core.hsc
new file mode 100644
--- /dev/null
+++ b/src/Codec/Compression/Zlib/Gzip/Core.hsc
@@ -0,0 +1,30 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Codec.Compression.Zlib.Gzip.Core (
+
+	GzFile,
+	c_gzopen, c_gzgets, c_gzclose
+
+) where
+
+import Foreign.Ptr
+import Foreign.C.String
+import Data.Int
+
+import Codec.Compression.Zlib.Constant.Core
+
+#include <zlib.h>
+
+data GzFileTag
+
+type GzFile = Ptr GzFileTag
+
+foreign import ccall "gzopen" c_gzopen :: CString -> CString -> IO GzFile
+
+foreign import ccall "gzgets" c_gzgets ::
+	GzFile -> CString -> #{type int} -> IO CString
+
+foreign import ccall "gzclose" c_gzclose :: GzFile -> IO ReturnCode
diff --git a/src/Codec/Compression/Zlib/Structure/Core.hsc b/src/Codec/Compression/Zlib/Structure/Core.hsc
new file mode 100644
--- /dev/null
+++ b/src/Codec/Compression/Zlib/Structure/Core.hsc
@@ -0,0 +1,208 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Codec.Compression.Zlib.Structure.Core (
+
+	-- * STRUCTURE
+
+	-- ** IMMUTABLE
+
+	Stream, streamInitial,
+	PAllocFunc, AllocFunc, PFreeFunc, FreeFunc, PtrBytef,
+
+	streamNextIn, streamAvailIn, streamNextOut, streamAvailOut,
+	streamAlloc, streamFree, streamOpaque,
+
+
+	-- ** MUTABLE
+
+	StreamIO, StreamST, StreamPrim,
+	withStreamPtr, streamFreeze, streamThaw, streamCopy,
+
+	-- * IN/OUT
+
+	nextIn, availIn, nextOut, availOut, msg,
+	setNextIn, setNextOut,
+
+	) where
+
+import Foreign.Ptr
+import Foreign.ForeignPtr
+import Foreign.Marshal.Alloc
+import Foreign.Storable
+import Foreign.C.String
+import Foreign.C.Struct
+import Foreign.C.Struct.TypeSynonyms
+import Control.Monad.Primitive
+import Data.Word
+import Data.Int
+
+-- import Codec.Compression.Zlib.Constant.Core
+
+#include <zlib.h>
+
+type AllocFunc = Ptr () -> #{type uInt} -> #{type uInt} -> IO (Ptr ())
+type FreeFunc = Ptr () -> Ptr () -> IO ()
+
+type PAllocFunc = FunPtr AllocFunc
+type PFreeFunc = FunPtr FreeFunc
+
+type PtrBytef = Ptr #{type Bytef}
+
+struct "Stream" #{size z_stream} #{alignment z_stream}
+	[	("nextIn", ''PtrBytef,
+			[| #{peek z_stream, next_in} |],
+			[| #{poke z_stream, next_in} |]),
+		("availIn", ''#{type uInt},
+			[| #{peek z_stream, avail_in} |],
+			[| #{poke z_stream, avail_in} |]),
+			{-
+		("totalIn", ''#{type uLong},
+			[| #{peek z_stream, total_in} |],
+			[| #{poke z_stream, total_in} |]),
+			-}
+
+		("nextOut", ''PtrBytef,
+			[| #{peek z_stream, next_out} |],
+			[| #{poke z_stream, next_out} |]),
+		("availOut", ''#{type uInt},
+			[| #{peek z_stream, avail_out} |],
+			[| #{poke z_stream, avail_out} |]),
+			{-
+		("totalOut", ''#{type uLong},
+			[| #{peek z_stream, total_out} |],
+			[| #{poke z_stream, total_out} |]),
+			-}
+
+{-
+		("msg", ''CString,
+			[| #{peek z_stream, msg} |],
+			[| #{poke z_stream, msg} |]),
+			-}
+
+		("alloc", ''PAllocFunc,
+			[| #{peek z_stream, zalloc} |],
+			[| #{poke z_stream, zalloc} |]),
+		("free", ''PFreeFunc,
+			[| #{peek z_stream, zfree} |],
+			[| #{poke z_stream, zfree} |]),
+		("opaque", ''PtrVoid,
+			[| #{peek z_stream, opaque} |],
+			[| #{poke z_stream, opaque} |])
+
+{-
+		("dataType", ''DataType,
+			[| #{peek z_stream, data_type} |],
+			[| #{poke z_stream, data_type} |]),
+
+		("adler", ''#{type uLong},
+			[| #{peek z_stream, adler} |],
+			[| #{poke z_stream, adler} |])
+			-}
+		]
+	[''Show, ''Eq, ''Storable]
+
+streamInitial :: Stream
+streamInitial = Stream {
+	streamNextIn = nullPtr,
+	streamAvailIn = 0,
+	streamNextOut = nullPtr,
+	streamAvailOut = 0,
+	streamAlloc = nullFunPtr,
+	streamFree = nullFunPtr,
+	streamOpaque = nullPtr }
+
+streamCopyPtr :: Ptr Stream -> IO (Ptr Stream)
+streamCopyPtr src = do
+	dst <- malloc
+
+	(ni :: PtrBytef) <- #{peek z_stream, next_in} src
+	#{poke z_stream, next_in} dst ni
+	(ai :: #{type uInt}) <- #{peek z_stream, avail_in} src
+	#{poke z_stream, avail_in} dst ai
+	(ti :: #{type uLong}) <- #{peek z_stream, total_in} src
+	#{poke z_stream, total_in} dst ti
+
+	(no :: PtrBytef) <- #{peek z_stream, next_out} src
+	#{poke z_stream, next_out} dst no
+	(ao :: #{type uInt}) <- #{peek z_stream, avail_out} src
+	#{poke z_stream, avail_out} dst ao
+	(to :: #{type uLong}) <- #{peek z_stream, total_out} src
+	#{poke z_stream, total_out} dst to
+
+	(msg :: CString) <- #{peek z_stream, msg} src
+	#{poke z_stream, msg} dst msg
+	(stt :: Ptr ()) <- #{peek z_stream, state} src
+	#{poke z_stream, state} dst stt
+
+	(allc :: PAllocFunc) <- #{peek z_stream, zalloc} src
+	#{poke z_stream, zalloc} dst allc
+	(fr :: PFreeFunc) <- #{peek z_stream, zfree} src
+	#{poke z_stream, zfree} dst fr
+	(opq :: Ptr ()) <- #{peek z_stream, opaque} src
+	#{poke z_stream, opaque} dst opq
+
+	(dt :: #{type int}) <- #{peek z_stream, data_type} src
+	#{poke z_stream, data_type} dst dt
+
+	(ad :: #{type uLong}) <- #{peek z_stream, adler} src
+	#{poke z_stream, adler} dst ad
+	(rs :: #{type uLong}) <- #{peek z_stream, reserved} src
+	#{poke z_stream, reserved} dst rs
+
+	pure dst
+
+streamFreePtr :: Ptr Stream -> IO ()
+streamFreePtr = free
+
+structPrim "Stream" 'streamCopyPtr 'streamFreePtr [''Show]
+
+withStreamPtr ::
+	PrimBase m => StreamPrim (PrimState m) -> (Ptr Stream -> m a) -> m a
+withStreamPtr (StreamPrim s) f =
+	unsafeIOToPrim $ withForeignPtr s (unsafePrimToIO . f)
+
+nextIn :: PrimMonad m => StreamPrim (PrimState m) -> m (Ptr Word8)
+nextIn (StreamPrim s) = unsafeIOToPrim $ withForeignPtr s nextInPtr
+
+availIn :: PrimMonad m => StreamPrim (PrimState m) -> m #{type uInt}
+availIn (StreamPrim s) = unsafeIOToPrim $ withForeignPtr s availInPtr
+
+nextInPtr :: Ptr Stream -> IO (Ptr Word8)
+nextInPtr = #{peek z_stream, next_in}
+
+availInPtr :: Ptr Stream -> IO #{type uInt}
+availInPtr = #{peek z_stream, avail_in}
+
+nextOut :: PrimMonad m => StreamPrim (PrimState m) -> m (Ptr Word8)
+nextOut (StreamPrim s) = unsafeIOToPrim $ withForeignPtr s nextOutPtr
+
+availOut :: PrimMonad m => StreamPrim (PrimState m) -> m #{type uInt}
+availOut (StreamPrim s) = unsafeIOToPrim $ withForeignPtr s availOutPtr
+
+nextOutPtr :: Ptr Stream -> IO (Ptr Word8)
+nextOutPtr = #{peek z_stream, next_out}
+
+availOutPtr :: Ptr Stream -> IO #{type uInt}
+availOutPtr = #{peek z_stream, avail_out}
+
+msg :: PrimMonad m => StreamPrim (PrimState m) -> m CString
+msg (StreamPrim s) = unsafeIOToPrim $ withForeignPtr s msgPtr
+
+msgPtr :: Ptr Stream -> IO CString
+msgPtr = #{peek z_stream, msg}
+
+setNextIn :: PrimMonad m =>
+	StreamPrim (PrimState m) -> PtrBytef -> #{type uInt} -> m ()
+setNextIn (StreamPrim s) ni ai = unsafeIOToPrim $ withForeignPtr s \p -> do
+	#{poke z_stream, next_in} p ni
+	#{poke z_stream, avail_in} p ai
+
+setNextOut :: PrimMonad m =>
+	StreamPrim (PrimState m) -> PtrBytef -> #{type uInt} -> m ()
+setNextOut (StreamPrim s) no ao = unsafeIOToPrim $ withForeignPtr s \p -> do
+	#{poke z_stream, next_out} p no
+	#{poke z_stream, avail_out} p ao
diff --git a/src/Codec/Compression/Zlib/Utility/Core.hsc b/src/Codec/Compression/Zlib/Utility/Core.hsc
new file mode 100644
--- /dev/null
+++ b/src/Codec/Compression/Zlib/Utility/Core.hsc
@@ -0,0 +1,24 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Codec.Compression.Zlib.Utility.Core (
+	c_compress, c_compressBound, c_uncompress
+	) where
+
+import Foreign.Ptr
+import Data.Word
+
+import Codec.Compression.Zlib.Constant.Core
+
+#include <zlib.h>
+
+foreign import ccall "compress" c_compress ::
+	Ptr #{type Bytef} -> Ptr #{type uLongf} ->
+	Ptr #{type Bytef} -> #{type uLong} -> IO ReturnCode
+
+foreign import ccall "compressBound" c_compressBound ::
+	#{type uLong} -> #{type uLong}
+
+foreign import ccall "uncompress" c_uncompress ::
+	Ptr #{type Bytef} -> Ptr #{type uLongf} ->
+	Ptr #{type Bytef} -> #{type uLong} -> IO ReturnCode
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"
diff --git a/zlib-core.cabal b/zlib-core.cabal
new file mode 100644
--- /dev/null
+++ b/zlib-core.cabal
@@ -0,0 +1,71 @@
+cabal-version: 2.2
+
+-- This file has been generated from package.yaml by hpack version 0.38.1.
+--
+-- see: https://github.com/sol/hpack
+
+name:           zlib-core
+version:        0.1.0.0
+synopsis:       Thin wrapper for zlib
+description:    Please see the README on GitHub at <https://github.com/YoshikuniJujo/zlib-core#readme>
+category:       Codec
+homepage:       https://github.com/YoshikuniJujo/zlib-core#readme
+bug-reports:    https://github.com/YoshikuniJujo/zlib-core/issues
+author:         Yoshikuni Jujo
+maintainer:     yoshikuni.jujo@gmail.com
+copyright:      (c) 2025 Yoshikuni Jujo
+license:        BSD-3-Clause
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    README.md
+extra-doc-files:
+    CHANGELOG.md
+
+source-repository head
+  type: git
+  location: https://github.com/YoshikuniJujo/zlib-core
+
+library
+  exposed-modules:
+      Codec.Compression.Zlib.Advanced.Core
+      Codec.Compression.Zlib.Basic.Core
+      Codec.Compression.Zlib.Constant.Core
+      Codec.Compression.Zlib.Gzip.Core
+      Codec.Compression.Zlib.Structure.Core
+      Codec.Compression.Zlib.Utility.Core
+  other-modules:
+      Paths_zlib_core
+  autogen-modules:
+      Paths_zlib_core
+  hs-source-dirs:
+      src
+  ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints
+  build-depends:
+      base >=4.7 && <5
+    , c-enum ==0.1.*
+    , c-struct ==0.1.*
+    , exception-hierarchy ==0.1.*
+    , primitive ==0.9.*
+    , tools-yj ==0.1.*
+  default-language: Haskell2010
+
+test-suite zlib-core-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Paths_zlib_core
+  autogen-modules:
+      Paths_zlib_core
+  hs-source-dirs:
+      test
+  ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      base >=4.7 && <5
+    , c-enum ==0.1.*
+    , c-struct ==0.1.*
+    , exception-hierarchy ==0.1.*
+    , primitive ==0.9.*
+    , tools-yj ==0.1.*
+    , zlib-core
+  default-language: Haskell2010
