diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -20,10 +20,8 @@
 
 ## Requirements
 
-* A working haskell compiler system, GHC(>=8.6), cabal-install(>=2.4), here're some options:
-    * Mac users can get them via [homebew](//brew.sh/): `brew install ghc cabal-install`.
-    * Windows users can get them via [chocolatey](//chocolatey.org): `choco install ghc cabal`.
-    * Ubuntu users are recommended to use this [ppa](//launchpad.net/~hvr/+archive/ubuntu/ghc).
+* A working haskell compiler system, GHC(>=9.2), cabal-install(>=3.8), here're some options:
+    * Using [ghcup](https://www.haskell.org/ghcup/) to setup your haskell envrionment.
 * A working C/C++ compiler support C++11, here're some options:
     * Mac users can use the `clang` comes with the [XCode](https://developer.apple.com/xcode/) or [XCode Command Line Tools](https://developer.apple.com/downloads):
         * You can install XCode from app store, or XCode Command Line Tools with `sudo xcode-select --install`.
@@ -39,44 +37,44 @@
 > import qualified Z.Data.Array as A
 >
 > -- convert from list
-> let v = V.pack [1..10] :: V.PrimVector Int  
+> let v = V.pack [1..10] :: V.PrimVector Int
 > -- vector combinators works on arrays as well
-> let a = V.pack [1..10] :: A.Array Int   
+> let a = V.pack [1..10] :: A.Array Int
 > -- slicing vector(slice) is O(1)
-> V.take 3 v                              
+> V.take 3 v
 [1,2,3]
 -- slicing array is not O(1)
-> V.drop 3 a                              
+> V.drop 3 a
 fromListN 7 [4,5,6,7,8,9,10]
 >
 > V.intersperse 10 v
 [1,10,2,10,3,10,4,10,5,10,6,10,7,10,8,10,9,10,10]
 >
-> V.mergeSort (V.intersperse 10 v) 
+> V.mergeSort (V.intersperse 10 v)
 [1,2,3,4,5,6,7,8,9,10,10,10,10,10,10,10,10,10,10]
 > -- Generic KMP search on vectors
-> V.indices (V.singleton 10) (V.intersperse 10 v) True   
+> V.indices (V.singleton 10) (V.intersperse 10 v) True
 [1,3,5,7,9,11,13,15,17,18]
 >
 > -- quoter for writing numeric vector literals
-> :set -XQuasiQuotes 
-> :t [V.vecWord|1,2,3,4,5,4,3,2,1|]                     
+> :set -XQuasiQuotes
+> :t [V.vecWord|1,2,3,4,5,4,3,2,1|]
 [V.vecWord|1,2,3,4,5,4,3,2,1|] :: V.PrimVector Word
 >
 > import qualified Z.Data.Builder as B
 > import qualified Z.Data.Text as T
-> :set -XOverloadedStrings 
+> :set -XOverloadedStrings
 >
 > -- Builders can be used with OverloadedStrings
 > B.build $ "builders: " >> B.hex (3 :: Word16) >> B.comma >> B.double 1.2345678
 [98,117,105,108,100,101,114,115,58,32,48,48,48,51,44,49,46,50,51,52,53,54,55,56]
-> 
+>
 > B.buildText $ "builders: " >> B.hex (3 :: Word16) >> B.comma >> B.double 1.2345678
 "builders: 0003,1.2345678"
 >
 > import qualified Z.Data.JSON as JSON
 > import GHC.Generics
-> 
+>
 > JSON.parseValue "[1,2,3,4,5]"
 ([],Right (Array [Number 1.0,Number 2.0,Number 3.0,Number 4.0,Number 5.0]))
 >
@@ -93,13 +91,13 @@
 
 ```bash
 # get code
-git clone --recursive git@github.com:ZHaskell/z-data.git 
+git clone --recursive git@github.com:ZHaskell/z-data.git
 cd z-data
 # build
 cabal build
 # test
 cabal test --test-show-details=direct
-# install 
+# install
 cabal install
 # generate document
 cabal haddock
diff --git a/Z-Data.cabal b/Z-Data.cabal
--- a/Z-Data.cabal
+++ b/Z-Data.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               Z-Data
-version:            2.0.0.2
+version:            2.0.1.0
 synopsis:           Array, vector and text
 description:        This package provides array, slice and text operations
 license:            BSD-3-Clause
@@ -185,7 +185,7 @@
     , containers            ^>=0.6
     , deepseq               ^>=1.4
     , hashable              >=1.3 && < 1.5
-    , primitive             >=0.7.3  && <0.8
+    , primitive             >=0.7.3  && <1.0
     , QuickCheck            >=2.10
     , random                >=1.2.0  && <1.3
     , scientific            >=0.3.7  && <0.4
diff --git a/Z/Data/Array/Base.hs b/Z/Data/Array/Base.hs
--- a/Z/Data/Array/Base.hs
+++ b/Z/Data/Array/Base.hs
@@ -62,20 +62,27 @@
   , sizeOf
   ) where
 
-import           Control.Exception              (ArrayException (..), throw)
+import           Control.Exception          (ArrayException (..), throw)
 import           Control.Monad
 import           Control.Monad.Primitive
 import           Control.Monad.ST
-import           Data.Bits                      (unsafeShiftL)
-import           Data.Kind                      (Type)
+import           Data.Bits                  (unsafeShiftL)
+import           Data.Kind                  (Type)
 import           Data.Primitive.Array
 import           Data.Primitive.ByteArray
+#if !MIN_VERSION_primitive(0, 9, 0)
 import           Data.Primitive.PrimArray
-import           Data.Primitive.Ptr             (copyPtrToMutablePrimArray)
+#else
+import           Data.Primitive.PrimArray   hiding
+                                            (withMutablePrimArrayContents,
+                                             withPrimArrayContents)
+#endif
+import           Data.Primitive.Ptr         (copyPtrToMutablePrimArray)
 import           Data.Primitive.SmallArray
 import           Data.Primitive.Types
 import           GHC.Exts
-import           System.Random.Stateful  ( UniformRange(uniformRM), StatefulGen )
+import           System.Random.Stateful     (StatefulGen,
+                                             UniformRange (uniformRM))
 import           Z.Data.Array.Cast
 import           Z.Data.Array.UnliftedArray
 
@@ -589,6 +596,8 @@
 
 --------------------------------------------------------------------------------
 
+-- FIXME: directly use Data.Primitive.PrimArray.withPrimArrayContents
+-- when primitive>=0.9.0 ?
 -- | Obtain the pointer to the content of an array, and the pointer should only be used during the IO action.
 --
 -- This operation is only safe on /pinned/ primitive arrays (Arrays allocated by 'newPinnedPrimArray' or
@@ -604,6 +613,8 @@
     primitive_ (touch# ba#)
     return b
 
+-- FIXME: directly use Data.Primitive.PrimArray.withMutablePrimArrayContents
+-- when primitive>=0.9.0 ?
 -- | Obtain the pointer to the content of an mutable array, and the pointer should only be used during the IO action.
 --
 -- This operation is only safe on /pinned/ primitive arrays (Arrays allocated by 'newPinnedPrimArray' or
diff --git a/Z/Foreign.hs b/Z/Foreign.hs
--- a/Z/Foreign.hs
+++ b/Z/Foreign.hs
@@ -109,9 +109,15 @@
                                                  fromShort, toShort)
 import qualified Data.ByteString.Unsafe         as B
 import qualified Data.List                      as List
-import           Data.Primitive
 import           Data.Primitive.ByteArray
+import           Data.Primitive.Types
+#if !MIN_VERSION_primitive(0, 9, 0)
 import           Data.Primitive.PrimArray
+#else
+import           Data.Primitive.PrimArray       hiding
+                                                (withMutablePrimArrayContents,
+                                                 withPrimArrayContents)
+#endif
 import           Data.Primitive.Ptr
 import           Data.Word
 import           Foreign.C.Types
diff --git a/Z/Foreign/CPtr.hs b/Z/Foreign/CPtr.hs
--- a/Z/Foreign/CPtr.hs
+++ b/Z/Foreign/CPtr.hs
@@ -21,15 +21,19 @@
   , FunPtr
   ) where
 
-import Control.Monad
-import Control.Monad.Primitive
-import Data.Primitive.PrimArray
-import qualified Z.Data.Text                as T
-import GHC.Ptr
-import GHC.Exts
-import GHC.IO
-import Z.Data.Array                         hiding (newPinnedPrimArray)
-import Z.Foreign
+import           Control.Monad
+import           Control.Monad.Primitive
+#if !MIN_VERSION_primitive(0, 9, 0)
+import           Data.Primitive.PrimArray
+#else
+import           Data.Primitive.PrimArray hiding (withMutablePrimArrayContents)
+#endif
+import           GHC.Exts
+import           GHC.IO
+import           GHC.Ptr
+import           Z.Data.Array             hiding (newPinnedPrimArray)
+import qualified Z.Data.Text              as T
+import           Z.Foreign
 
 -- | Lightweight foreign pointers.
 newtype CPtr a = CPtr (PrimArray (Ptr a))
