Repository: pmndrs/zustand
Pull request #1512 (2023-01-06 13:49:11)

doc: update documentation of persist
## Related Issues

Fixes #1510 

## Summary

Update doc to include how to handle Map and Set with the new persist API.

issue since i have yarn v3 installed, it creates `.yarn` and `.yarnrc.yml` and need me to set pacakge to v1 with `yarn set version classic` so not sure i can run prettier easily but i will run it and delete the files we don't want commited.

## Check List

- [x] `yarn run prettier` for formatting code and docs


codesandbox-ci[bot]: This pull request is automatically built and testable in [CodeSandbox](https://codesandbox.io).

  To see build info of the built libraries, click [here](https://ci.codesandbox.io/status/pmndrs/zustand/pr/1512/builds/332782) or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 9c2e9d7b4b70e98382b571903cbe5cd74d17c3b7:

|Sandbox| Source |
|--|--|
|[React](https://codesandbox.io/s/react-iwxxy7)| Configuration |
|[React Typescript](https://codesandbox.io/s/react-typescript-d86beo)| Configuration |
|[React Browserify](https://codesandbox.io/s/react-browserify-0eewxc)| Configuration |
|[React Snowpack](https://codesandbox.io/s/react-snowpack-zhrdbu)| Configuration |
|[React Parcel](https://codesandbox.io/s/react-parcel-hrkl4m)| Configuration |
|[Next.js](https://codesandbox.io/s/next-js-5u65c4)| Configuration |
|[@pavlobu/zustand demo](https://codesandbox.io/s/pavlobu-zustand-demo-1n3ud6)| Configuration |


Patch:
diff --git a/docs/getting-started/comparison.md b/docs/getting-started/comparison.md
index 1a779a0..adcae06 100644
--- a/docs/getting-started/comparison.md
+++ b/docs/getting-started/comparison.md
@@ -20,7 +20,7 @@ immutable state model. However, Redux, requires your app to be wrapped in
 context providers; Zustand does not.
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 type State = {
   count: number
@@ -39,7 +39,7 @@ const useCountStore = create<State & Actions>((set) => ({
 ```
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 type State = {
   count: number
@@ -129,7 +129,7 @@ recommended that you manually apply render optimizations by using selectors.
 **Zustand**
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 type State = {
   count: number
@@ -234,7 +234,7 @@ Zustand is based on the **immutable** state model, while Valtio is based on the
 **Zustand**
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 type State = {
   obj: { count: number }
@@ -264,7 +264,7 @@ that you manually apply render optimizations by using selectors.
 **Zustand**
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 type State = {
   count: number
@@ -307,7 +307,7 @@ suitable when access outside of React is required.
 **Zustand**
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 type State = {
   count: number
@@ -343,7 +343,7 @@ selectors.
 **Zustand**
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 type State = {
   count: number
@@ -392,7 +392,7 @@ identities, additionally, Recoil needs to wrap your app in a context provider.
 **Zustand**
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 type State = {
   count: number
@@ -429,7 +429,7 @@ manually apply render optimizations by using selectors.
 **Zustand**
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 type State = {
   count: number
diff --git a/docs/getting-started/introduction.mdx b/docs/getting-started/introduction.mdx
index f525d9b..d65591d 100644
--- a/docs/getting-started/introduction.mdx
+++ b/docs/getting-started/introduction.mdx
@@ -36,7 +36,7 @@ yarn add zustand
 Your store is a hook! You can put anything in it: primitives, objects, functions. The `set` function _merges_ state.
 
 ```jsx
-import create from 'zustand'
+import { create } from 'zustand'
 
 const useStore = create((set) => ({
   bears: 0,
diff --git a/docs/guides/connect-to-state-with-url-hash.md b/docs/guides/connect-to-state-with-url-hash.md
index fc1bddf..967e768 100644
--- a/docs/guides/connect-to-state-with-url-hash.md
+++ b/docs/guides/connect-to-state-with-url-hash.md
@@ -8,7 +8,7 @@ nav: 12
 If you want to connect state of a store to URL hash, you can create your own hash storage.
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 import { persist, StateStorage } from 'zustand/middleware'
 
 const hashStorage: StateStorage = {
diff --git a/docs/guides/how-to-reset-state.md b/docs/guides/how-to-reset-state.md
index b7257ed..65dbe4f 100644
--- a/docs/guides/how-to-reset-state.md
+++ b/docs/guides/how-to-reset-state.md
@@ -6,7 +6,7 @@ nav: 13
 The following pattern can be used to reset the state to its initial value.
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 // define types for state values and actions separately
 type State = {
@@ -47,7 +47,7 @@ const useSlice = create<State & Actions>()((set, get) => ({
 Resetting multiple stores at once
 
 ```ts
-import _create, { StateCreator } from 'zustand'
+import { create: _create, StateCreator } from 'zustand'
 
 const resetters: (() => void)[] = []
 
diff --git a/docs/guides/immutable-state-and-merging.md b/docs/guides/immutable-state-and-merging.md
index 4cc86bd..aa74ad0 100644
--- a/docs/guides/immutable-state-and-merging.md
+++ b/docs/guides/immutable-state-and-merging.md
@@ -8,7 +8,7 @@ Like with React's `useState`, we need to update state immutably.
 Here's a typical example:
 
 ```jsx
-import create from 'zustand'
+import { create } from 'zustand'
 
 const useCountStore = create((set) => ({
   count: 0,
@@ -36,7 +36,7 @@ The `set` function merges state at only one level.
 If you have a nested object, you need to merge them explicitly. You will use the spread operator pattern like so:
 
 ```jsx
-import create from 'zustand'
+import { create } from 'zustand'
 
 const useCountStore = create((set) => ({
   nested: { count: 0 },
diff --git a/docs/guides/maps-and-sets-usage.md b/docs/guides/maps-and-sets-usage.md
index 4ae4722..dbf04a1 100644
--- a/docs/guides/maps-and-sets-usage.md
+++ b/docs/guides/maps-and-sets-usage.md
@@ -9,7 +9,7 @@ you do it by calling `setState` on it:
 **You can view a codesandbox here: https://codesandbox.io/s/late-https-bxz9qy**
 
 ```js
-import create from 'zustand'
+import { create } from 'zustand'
 
 const useFooBar = create(() => ({ foo: new Map(), bar: new Set() }))
 
diff --git a/docs/guides/slices-pattern.md b/docs/guides/slices-pattern.md
index 2244548..0c4b425 100644
--- a/docs/guides/slices-pattern.md
+++ b/docs/guides/slices-pattern.md
@@ -31,7 +31,7 @@ export const createBearSlice = (set) => ({
 You can now combine both the stores into **one bounded store**:
 
 ```js
-import create from 'zustand'
+import { create } from 'zustand'
 import { createBearSlice } from './bearSlice'
 import { createFishSlice } from './fishSlice'
 
@@ -81,7 +81,7 @@ export const createBearFishSlice = (set) => ({
 Combining all the stores together is the same as before.
 
 ```js
-import create from 'zustand'
+import { create } from 'zustand'
 import { createBearSlice } from './bearSlice'
 import { createFishSlice } from './fishSlice'
 import { createBearFishSlice } from './createBearFishSlice'
@@ -100,7 +100,7 @@ Adding middlewares to a combined store is the same as with other normal stores.
 Adding `persist` middleware to our `useBoundStore`:
 
 ```js
-import create from 'zustand'
+import { create } from 'zustand'
 import { createBearSlice } from './bearSlice'
 import { createFishSlice } from './fishSlice'
 import { persist } from 'zustand/middleware'
diff --git a/docs/guides/typescript.md b/docs/guides/typescript.md
index 51b9972..a16ad3f 100644
--- a/docs/guides/typescript.md
+++ b/docs/guides/typescript.md
@@ -8,7 +8,7 @@ nav: 8
 The difference when using TypeScript is that instead of writing `create(...)`, you have to write `create<T>()(...)` (notice the extra parenthesis `()` too along with the type parameter) where `T` is the type of the state to annotate it. For example:
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 interface BearState {
   bears: number
@@ -71,7 +71,7 @@ So what we're saying is, the inference failure in case of `createFoo` is not rea
 Zustand lies that it implemented `create`'s type, it implemented only the most part of it. Here's a simple proof by showing unsoundness. Consider the following code:
 
 ```ts
-import create from 'zustand/vanilla'
+import { create } from 'zustand'
 
 const useBoundStore = create<{ foo: number }>()((_, get) => ({
   foo: get().foo,
@@ -136,7 +136,7 @@ This way, `T` gets inferred and you get to annotate `E`. Zustand has the same us
 Alternatively, you can also use `combine`, which infers the state so that you do not need to type it.
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 import { combine } from 'zustand/middleware'
 
 const useBearStore = create(
@@ -166,7 +166,7 @@ Note that we don't use the curried version when using `combine` because `combine
 You do not have to do anything special to use middlewares in TypeScript.
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 import { devtools, persist } from 'zustand/middleware'
 
 interface BearState {
@@ -187,7 +187,7 @@ const useBearStore = create<BearState>()(
 Just make sure you are using them immediately inside `create` so as to make the contextual inference work. Doing something even remotely fancy like the following `myMiddlewares` would require more advanced types.
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 import { devtools, persist } from 'zustand/middleware'
 
 const myMiddlewares = (f) => devtools(persist(f))
@@ -212,7 +212,7 @@ Also, we recommend using `devtools` middleware as last as possible. For example,
 Imagine you had to write this hypothetical middleware.
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 
 const foo = (f, bar) => (set, get, store) => {
   store.foo = bar
@@ -234,7 +234,7 @@ If you are eager to know what the answer is to this particular problem then you
 ### Middleware that doesn't change the store type
 
 ```ts
-import create, { State, StateCreator, StoreMutatorIdentifier } from 'zustand'
+import { create, State, StateCreator, StoreMutatorIdentifier } from 'zustand'
 
 type Logger = <
   T extends State,
@@ -279,7 +279,8 @@ const useBearStore = create<BearState>()(
 ### Middleware that changes the store type
 
 ```ts
-import create, {
+import {
+  create,
   State,
   StateCreator,
   StoreMutatorIdentifier,
@@ -334,7 +335,7 @@ console.log(useBearStore.foo.toUpperCase())
 The recommended way to use `create` is using the curried workaround like so: `create<T>()(...)`. This is because it enables you to infer the store type. But if for some reason you do not want to use the workaround, you can pass the type parameters like the following. Note that in some cases, this acts as an assertion instead of annotation, so we don't recommend it.
 
 ```ts
-import create from "zustand"
+import { create } from "zustand"
 
 interface BearState {
   bears: number
@@ -356,7 +357,7 @@ const useBearStore = create<
 ### Slices pattern
 
 ```ts
-import create, { StateCreator } from 'zustand'
+import { create, StateCreator } from 'zustand'
 
 interface BearSlice {
   bears: number
diff --git a/docs/integrations/immer-middleware.md b/docs/integrations/immer-middleware.md
index c455a92..c8c9c10 100644
--- a/docs/integrations/immer-middleware.md
+++ b/docs/integrations/immer-middleware.md
@@ -22,7 +22,7 @@ npm install immer
 Updating simple states
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 import { immer } from 'zustand/middleware/immer'
 
 type State = {
@@ -52,7 +52,7 @@ export const useCountStore = create(
 Updating complex states
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 import { immer } from 'zustand/middleware/immer'
 
 interface Todo {
diff --git a/docs/integrations/persisting-store-data.md b/docs/integrations/persisting-store-data.md
index f2a3f4b..a64fc77 100644
--- a/docs/integrations/persisting-store-data.md
+++ b/docs/integrations/persisting-store-data.md
@@ -18,7 +18,7 @@ for more details.
 ## Simple example
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 import { persist, createJSONStorage } from 'zustand/middleware'
 
 export const useBearStore = create(
@@ -300,7 +300,7 @@ Or even to change the storage engine:
 
 ```ts
 useBoundStore.persist.setOptions({
-  getStorage: () => sessionStorage,
+  storage: createJSONStorage(() => sessionStorage),
 })
 ```
 
@@ -483,7 +483,7 @@ const useHydration = () => {
 If the storage you want to use does not match the expected API, you can create your own storage:
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 import { persist, StateStorage } from 'zustand/middleware'
 import { get, set, del } from 'idb-keyval' // can use anything: IndexedDB, Ionic Storage, etc.
 
@@ -511,7 +511,7 @@ export const useBoundStore = create(
     }),
     {
       name: 'food-storage', // unique name
-      getStorage: () => storage,
+      storage: createJSONStorage(() => storage),
     }
   )
 )
@@ -549,7 +549,7 @@ Basic typescript usage doesn't require anything special
 except for writing `create<State>()(...)` instead of `create(...)`.
 
 ```tsx
-import create from 'zustand'
+import { create } from 'zustand'
 import { persist } from 'zustand/middleware'
 
 interface MyState {
@@ -565,9 +565,45 @@ export const useBearStore = create<MyState>()(
     }),
     {
       name: 'food-storage', // name of item in the storage (must be unique)
-      getStorage: () => sessionStorage, // (optional) by default the 'localStorage' is used
+      storage: createJSONStorage(() => sessionStorage), // (optional) by default the 'localStorage' is used
       partialize: (state) => ({ bears: state.bears }),
     }
   )
 )
 ```
+
+### How do I use it with Map and Set?
+
+With the previous persist API, you would use `serialize`/`deserialize`
+to deal with `Map` and `Set` and convert them into
+an Array so they could be parsed into proper JSON.
+
+The new persist API has deprecated `serialize`/`deserialize`.
+
+Now, you will need to use the `storage` prop.
+Let's say your state uses `Map` to handle a list of `transactions`,
+then you can convert the Map into an Array in the storage prop:
+
+```ts
+  storage: {
+    getItem: (name) => {
+      const str = localStorage.getItem(name)
+      return {
+        state: {
+          ...JSON.parse(str).state,
+          transactions: new Map(JSON.parse(str).state.transactions),
+        },
+      }
+    },
+    setItem: (name, newValue) => {
+      const str = JSON.stringify({
+        state: {
+          ...newValue.state,
+          transactions: Array.from(newValue.state.transactions.entries()),
+        },
+      })
+      localStorage.setItem(name, str)
+    },
+    removeItem: (name) => localStorage.removeItem(name),
+  },
+```
diff --git a/docs/migrations/migrating-to-v4.md b/docs/migrations/migrating-to-v4.md
new file mode 100644
index 0000000..f0243a6
--- /dev/null
+++ b/docs/migrations/migrating-to-v4.md
@@ -0,0 +1,362 @@
+---
+title: Migrating to v4
+nav: 19
+---
+
+The only breaking changes are in types.
+If you are using Zustand with TypeScript
+or JSDoc type annotations,
+this guide applies.
+Otherwise, no migration is required.
+
+Also, it's recommended to first read
+the new [TypeScript Guide](../guides/typescript.md),
+so that the migration is easier to understand.
+
+In addition to this migration guide,
+you can also check the
+[diff](https://github.com/pmndrs/zustand/compare/v3.7.2...v4.0.0?short_path=37e5b4c#diff-c21e24854115b390eccde717da83f91feb2d5927a76c1485e5f0fdd0135c2afa)
+of the test files in the Zustand repository from v3 to v4.
+
+## `create`
+
+**Applicable imports**
+
+```ts
+import create from 'zustand'
+import create from 'zustand/vanilla'
+```
+
+**Change**
+
+```diff
+- create:
+-   < State
+-   , StoreSetState = StoreApi<State>["set"]
+-   , StoreGetState = StoreApi<State>["get"]
+-   , Store = StoreApi<State>
+-   >
+-     (f: ...) => ...
++ create:
++   { <State>(): (f: ...) => ...
++   , <State, Mutators>(f: ...) => ...
++   }
+```
+
+**Migration**
+
+If you are not passing any type parameters to `create`,
+no migration is required.
+
+If you are using a "leaf" middleware like `combine` or `redux`,
+remove all type parameters from `create`.
+
+Else, replace `create<T, ...>(...)` with `create<T>()(...)`.
+
+## `StateCreator`
+
+**Applicable imports**
+
+```ts
+import type { StateCreator } from 'zustand'
+import type { StateCreator } from 'zustand/vanilla'
+```
+
+**Change**
+
+```diff
+- type StateCreator
+-   < State
+-   , StoreSetState = StoreApi<State>["set"]
+-   , StoreGetState = StoreApi<State>["get"]
+-   , Store = StoreApi<State>
+-   > =
+-     ...
++ type StateCreator
++   < State
++   , InMutators extends [StoreMutatorIdentifier, unknown][] = []
++   , OutMutators extends [StoreMutatorIdentifier, unknown][] = []
++   , Return = State
++   > =
++     ...
+```
+
+**Migration**
+
+If you are using `StateCreator`,
+you are likely authoring a middleware
+or using the "slices" pattern.
+For that check the
+[Authoring middlewares and advanced usage](../guides/typescript.md#authoring-middlewares-and-advanced-usage)
+and [Common recipes](../guides/typescript.md#common-recipes)
+sections of the TypeScript Guide.
+
+## `PartialState`
+
+**Applicable imports**
+
+```ts
+import type { PartialState } from 'zustand'
+import type { PartialState } from 'zustand/vanilla'
+```
+
+**Change**
+
+```diff
+- type PartialState
+-   < T extends State
+-   , K1 extends keyof T = keyof T
+-   , K2 extends keyof T = K1
+-   , K3 extends keyof T = K2
+-   , K4 extends keyof T = K3
+-   > =
+-   | (Pick<T, K1> | Pick<T, K2> | Pick<T, K3> | Pick<T, K4> | T)
+-   | ((state: T) => Pick<T, K1> | Pick<T, K2> | Pick<T, K3> | Pick<T, K4> | T)
++ type PartialState<T> =
++   | Partial<T>
++   | ((state: T) => Partial<T>)
+```
+
+**Migration**
+
+Replace `PartialState<T, ...>` with `PartialState<T>`
+and preferably turn on [`exactOptionalPropertyTypes`](https://www.typescriptlang.org/tsconfig#exactOptionalPropertyTypes)
+in your `tsconfig.json`:
+
+```json
+{
+  "compilerOptions": {
+    "exactOptionalPropertyTypes": true
+  }
+}
+```
+
+We're no longer using the trick to disallow `{ foo: undefined }`
+to be assigned to `Partial<{ foo: string }>`.
+Instead, we're relying on the users to turn on `exactOptionalPropertyTypes`.
+
+## `useStore`
+
+**Applicable imports**
+
+```ts
+import { useStore } from 'zustand'
+import { useStore } from 'zustand/react'
+```
+
+**Change**
+
+```diff
+- useStore:
+-   { <State>(store: StoreApi<State>): State
+-   , <State, StateSlice>
+-       ( store: StoreApi<State>
+-       , selector: StateSelector<State, StateSlice>,
+-       , equals?: EqualityChecker<StateSlice>
+-       ): StateSlice
+-   }
++ useStore:
++   <Store, StateSlice = ExtractState<Store>>
++     ( store: Store
++     , selector?: StateSelector<State, StateSlice>,
++     , equals?: EqualityChecker<StateSlice>
++     )
++       => StateSlice
+```
+
+**Migration**
+
+If you are not passing any type parameters to `useStore`,
+no migration is required.
+
+If you are,
+it's recommended to remove all the type parameters,
+or pass the **store** type instead of the **state** type as the first parameter.
+
+## `UseBoundStore`
+
+**Applicable imports**
+
+```ts
+import type { UseBoundStore } from 'zustand'
+import type { UseBoundStore } from 'zustand/react'
+```
+
+**Change**
+
+```diff
+- type UseBoundStore<
+-   State,
+-   Store = StoreApi<State>
+- > =
+-   & { (): T
+-     , <StateSlice>
+-         ( selector: StateSelector<State, StateSlice>
+-         , equals?: EqualityChecker<StateSlice>
+-         ): U
+-     }
+-   & Store
++ type UseBoundStore<Store> =
++   & (<StateSlice = ExtractState<S>>
++       ( selector?: (state: ExtractState<S>) => StateSlice
++       , equals?: (a: StateSlice, b: StateSlice) => boolean
++       ) => StateSlice
++     )
++   & S
+```
+
+**Migration**
+
+Replace `UseBoundStore<T>` with `UseBoundStore<StoreApi<T>>`,
+and `UseBoundStore<T, S>` with `UseBoundStore<S>`
+
+## `UseContextStore`
+
+**Applicable imports**
+
+```ts
+import type { UseContextStore } from 'zustand/context'
+```
+
+**Change**
+
+```diff
+- type UseContextStore
+```
+
+**Migration**
+
+Use `typeof MyContext.useStore` instead
+
+## `createContext`
+
+**Applicable imports**
+
+```ts
+import createContext from 'zustand/context'
+```
+
+**Change**
+
+```diff
+  createContext:
+-   <State, Store = StoreApi<State>>() => ...
++   <Store>() => ...
+```
+
+**Migration**
+
+Replace `createContext<T>()` with `createContext<StoreApi<T>>()`,
+and `createContext<T, S>()` with `createContext<S>()`.
+
+## `combine`, `devtools`, `subscribeWithSelector`
+
+**Applicable imports**
+
+```ts
+import { combine } from 'zustand/middleware'
+import { devtools } from 'zustand/middleware'
+import { subscribeWithSelector } from 'zustand/middleware'
+```
+
+**Change**
+
+```diff
+- combine:
+-   <T, U>(...) => ...
++ combine:
++   <T, U, Mps, Mcs>(...) => ...
+
+- devtools:
+-   <T>(...) => ...
++ devtools:
++   <T, Mps, Mcs>(...) => ...
+
+- subscribeWithSelector:
+-   <T>(...) => ...
++ subscribeWithSelector:
++   <T, Mps, Mcs>(...) => ...
+```
+
+**Migration**
+
+If you are not passing any type parameters
+to `combine`, `devtools`, or `subscribeWithSelector`,
+no migration is required.
+
+If you are,
+remove all the type parameters,
+as they are inferred automatically.
+
+## `persist`
+
+**Applicable imports**
+
+```ts
+import { persist } from 'zustand/middleware'
+```
+
+**Change**
+
+```diff
+- persist:
+-   <T, U = Partial<T>>(...) => ...
++ persist:
++   <T, Mps, Mcs, U = T>(...) => ...
+```
+
+**Migration**
+
+If you are passing any type parameters,
+remove them as they are inferred automatically.
+
+Next, if you are passing the `partialize` option,
+there is no further steps required for migration.
+
+If you are **not** passing the `partialize` option,
+you might see some compilation errors.
+If you do not see any,
+there is no further migration required.
+
+The type of partialized state is now `T` instead of `Partial<T>`,
+which aligns with the runtime behavior of the default `partialize`,
+which is an identity (`s => s`).
+
+If you see some compilation errors,
+you have to find and fix the errors yourself,
+because they might be indicative of unsound code.
+Alternatively, the workaround will be passing
+`s => s as Partial<typeof s>` to `partialize`.
+If your partialized state is truly `Partial<T>`,
+you should not encounter any bugs.
+
+The runtime behavior has not changed,
+only the types are now correct.
+
+## `redux`
+
+**Applicable imports**
+
+```ts
+import { redux } from 'zustand/middleware'
+```
+
+**Change**
+
+```diff
+- redux:
+-   <T, A>(...) => ...
++ redux:
++   <T, A, Mps, Mcs>(...) => ...
+```
+
+**Migration**
+
+If you are not passing any type parameters to `redux`,
+no migration is required.
+
+If you are,
+remove all the type parameters,
+and annotate only the second (action) parameter.
+That is, replace `redux<T, A>((state, action) => ..., ...)`
+with `redux((state, action: A) => ..., ...)`.
diff --git a/docs/migrations/v4-migration.md b/docs/migrations/v4-migration.md
deleted file mode 100644
index 86830ab..0000000
--- a/docs/migrations/v4-migration.md
+++ /dev/null
@@ -1,222 +0,0 @@
----
-title: v4 Migrations
-nav: 19
----
-
-If you're not using the typed version (either via TypeScript or via JSDoc) then there are no breaking changes for you and hence no migration is needed either.
-
-Also it's recommended to first read the new [TypeScript Guide](../guides/typescript.md), it'll be easier to understand the migration.
-
-In addition to this migration guide you can also check the diff of the test files in the repo from v3 to v4.
-
-## `create` (from `zustand` and `zustand/vanilla`)
-
-### Change
-
-```diff
-- create:
--   < State
--   , StoreSetState = StoreApi<State>["set"]
--   , StoreGetState = StoreApi<State>["get"]
--   , Store = StoreApi<State>
--   >
--     (f: ...) => ...
-+ create:
-+   { <State>(): (f: ...) => ...
-+   , <State, Mutators>(f: ...) => ...
-+   }
-```
-
-### Migration
-
-If you're not passing any type parameters to `create` then there is no migration needed. If you're using a "leaf" middleware like `combine` or `redux` then remove all type parameters from `create`. Else replace `create<T, ...>(...)` with `create<T>()(...)`.
-
-## `StateCreator` (from `zustand` and `zustand/vanilla`)
-
-### Change
-
-```diff
-- type StateCreator
--   < State
--   , StoreSetState = StoreApi<State>["set"]
--   , StoreGetState = StoreApi<State>["get"]
--   , Store = StoreApi<State>
--   > =
--     ...
-+ type StateCreator
-+   < State
-+   , InMutators extends [StoreMutatorIdentifier, unknown][] = []
-+   , OutMutators extends [StoreMutatorIdentifier, unknown][] = []
-+   , Return = State
-+   > =
-+     ...
-```
-
-### Migration
-
-If you're using `StateCreator` you're likely authoring a middleware or using the "slices" pattern, for that check the TypeScript Guide's ["Authoring middlewares and advanced usage"](../guides/typescript.md#authoring-middlewares-and-advanced-usage) and ["Common recipes"](../guides/typescript.md#common-recipes) sections.
-
-## `PartialState` (from `zustand` and `zustand/vanilla`)
-
-### Change
-
-```diff
-- type PartialState
--   < T extends State
--   , K1 extends keyof T = keyof T
--   , K2 extends keyof T = K1
--   , K3 extends keyof T = K2
--   , K4 extends keyof T = K3
--   > =
--   | (Pick<T, K1> | Pick<T, K2> | Pick<T, K3> | Pick<T, K4> | T)
--   | ((state: T) => Pick<T, K1> | Pick<T, K2> | Pick<T, K3> | Pick<T, K4> | T)
-+ type PartialState<T> =
-+   | Partial<T>
-+   | ((state: T) => Partial<T>)
-```
-
-### Migration
-
-Replace `PartialState<T, ...>` with `PartialState<T>` and preferably turn on [`--exactOptionalPropertyTypes`](https://www.typescriptlang.org/tsconfig#exactOptionalPropertyTypes).
-
-We're no longer using the trick to disallow `{ foo: undefined }` to be assigned to `Partial<{ foo: string }>` instead now we're relying on the users to turn on `--exactOptionalPropertyTypes`.
-
-## `useStore` (from `zustand` and `zustand/react`)
-
-### Change
-
-```diff
-- useStore:
--   { <State>(store: StoreApi<State>): State
--   , <State, StateSlice>
--       ( store: StoreApi<State>
--       , selector: StateSelector<State, StateSlice>,
--       , equals?: EqualityChecker<StateSlice>
--       ): StateSlice
--   }
-+ useStore:
-+   <Store, StateSlice = ExtractState<Store>>
-+     ( store: Store
-+     , selector?: StateSelector<State, StateSlice>,
-+     , equals?: EqualityChecker<StateSlice>
-+     )
-+       => StateSlice
-```
-
-### Migration
-
-If you're not passing any type parameters to `useStore` then there is no migration needed. If you are then it's recommended to remove them, or pass the store type instead of the state type as the first parameter.
-
-## `UseBoundStore` (from `zustand` and `zustand/react`)
-
-### Change
-
-```diff
-- type UseBoundStore<
--   State,
--   Store = StoreApi<State>
-- > =
--   & { (): T
--     , <StateSlice>
--         ( selector: StateSelector<State, StateSlice>
--         , equals?: EqualityChecker<StateSlice>
--         ): U
--     }
--   & Store
-+ type UseBoundStore<Store> =
-+   & (<StateSlice = ExtractState<S>>
-+       ( selector?: (state: ExtractState<S>) => StateSlice
-+       , equals?: (a: StateSlice, b: StateSlice) => boolean
-+       ) => StateSlice
-+     )
-+   & S
-```
-
-### Migration
-
-Replace `UseBoundStore<T>` with `UseBoundStore<StoreApi<T>>` and `UseBoundStore<T, S>` with `UseBoundStore<S>`
-
-## `UseContextStore` (from `zustand/context`)
-
-### Change
-
-```diff
-- type UseContextStore
-```
-
-### Migration
-
-Use `typeof MyContext.useStore` instead
-
-## `createContext` (from `zustand/context`)
-
-### Change
-
-```diff
-  createContext:
--   <State, Store = StoreApi<State>>() => ...
-+   <Store>() => ...
-```
-
-### Migration
-
-Replace `createContext<T>()` with `createContext<StoreApi<T>>()` and `createContext<T, S>()` with `createContext<S>()`.
-
-## `combine`, `devtools`, `subscribeWithSelector` (from `zustand/middleware`)
-
-### Change
-
-```diff
-- combine:
--   <T, U>(...) => ...
-+ combine:
-+   <T, U, Mps, Mcs>(...) => ...
-
-- devtools:
--   <T>(...) => ...
-+ devtools:
-+   <T, Mps, Mcs>(...) => ...
-
-- subscribeWithSelector:
--   <T>(...) => ...
-+ subscribeWithSelector:
-+   <T, Mps, Mcs>(...) => ...
-```
-
-### Migration
-
-If you're not passing any type parameters then there is no migration needed. If you're passing any type parameters, remove them as are inferred.
-
-## `persist` (from `zustand/middleware`)
-
-### Change
-
-```diff
-- persist:
--   <T, U = Partial<T>>(...) => ...
-+ persist:
-+   <T, Mps, Mcs, U = T>(...) => ...
-```
-
-### Migration
-
-If you're passing any type parameters, then remove them because they will be inferred. Next, if you're passing the `partialize` option then there's no further steps required for migration.
-
-But if you're not passing the `partialize` option then you might be seeing some compilation errors. If you're not seeing any compilation errors then there's no further steps requierd for migration.
-
-But if you're seeing some compilation errors—because now the type of partialized state is `T` instead of `Partial<T>` which is in alignment with the runtime behavior of default `partialize` being `s => s`—then in that case you should fix the errors because they might be indicative of unsound code. To be clear the runtime behavior has not changed, the types have gotten more correct, but if your partialised state is truly `Partial<T>` then you can pass the `partialize` option as `s => s as Partial<typeof s>`. You can do this for a quickfix too.
-
-## `redux` (from `zustand/middleware`)
-
-### Change
-
-```diff
-- redux:
--   <T, A>(...) => ...
-+ redux:
-+   <T, A, Mps, Mcs>(...) => ...
-```
-
-### Migration
-
-If you're not passing any type parameters then there is no migration needed. If you're passing type parameters them remove them and annotate the second (action) parameter. That is replace `redux<T, A>((state, action) => ..., ...)` with `redux((state, action: A) => ..., ...)`.
diff --git a/docs/previous-versions/zustand-v3-create-context.md b/docs/previous-versions/zustand-v3-create-context.md
index 11d1607..d763315 100644
--- a/docs/previous-versions/zustand-v3-create-context.md
+++ b/docs/previous-versions/zustand-v3-create-context.md
@@ -6,7 +6,7 @@ nav: 18
 A special `createContext` is provided since v3.5,
 which avoids misusing the store hook.
 
-> **Note**: This function will likely be deprecated in v4 and removed in v5.
+> **Note**: This function will be deprecated in v4 and removed in v5.
 
 ```jsx
 import create from 'zustand'
diff --git a/docs/recipes/recipes.mdx b/docs/recipes/recipes.mdx
index 442d633..7bb664f 100644
--- a/docs/recipes/recipes.mdx
+++ b/docs/recipes/recipes.mdx
@@ -35,7 +35,7 @@ const treats = useStore(
 For instance, if you want to construct a single object with multiple state-picks inside, similar to redux's mapStateToProps, you can tell zustand that you want the object to be diffed shallowly by passing the `shallow` equality function.
 
 ```jsx
-import shallow from 'zustand/shallow'
+import { shallow } from 'zustand/shallow'
 
 // Object pick, re-renders the component when either state.nuts or state.honey change
 const { nuts, honey } = useStore(
@@ -131,7 +131,7 @@ subscribe(selector, callback, options?: { equalityFn, fireImmediately }): Unsubs
 ```
 
 ```jsx
-import create from 'zustand';
+import { create } from 'zustand';
 import { subscribeWithSelector, shallow } from 'zustand/middleware'
 const useStore = create(subscribeWithSelector(() => ({ paw: true, snout: true, fur: true })))
 
@@ -173,17 +173,17 @@ function Component() {
 Zustands core can be imported and used without the React dependency. The only difference is that the create function does not return a hook, but the api utilities.
 
 ```jsx
-import create from 'zustand/vanilla'
+import { createStore } from 'zustand/vanilla'
 
-const store = create(() => ({ ... }))
+const store = createStore(() => ({ ... }))
 const { getState, setState, subscribe, destroy } = store
 ```
 
 You can even consume an existing vanilla store with React:
 
 ```jsx
-import create from 'zustand'
-import vanillaStore from './vanillaStore'
+import { create } from 'zustand'
+import { vanillaStore } from './vanillaStore'
 
 const useStore = create(vanillaStore)
 ```
@@ -258,7 +258,7 @@ const useStore = create(
 <summary>How to pipe middlewares</summary>
 
 ```js
-import create from 'zustand'
+import { create } from 'zustand'
 import produce from 'immer'
 import pipe from 'ramda/es/pipe'
 
@@ -309,7 +309,7 @@ const immer =
 You can persist your store's data using any kind of storage.
 
 ```jsx
-import create from 'zustand'
+import { create } from 'zustand'
 import { persist } from 'zustand/middleware'
 
 export const useStore = create(
diff --git a/readme.md b/readme.md
index 4d76d4b..4395e65 100644
--- a/readme.md
+++ b/readme.md
@@ -25,7 +25,7 @@ npm install zustand # or yarn add zustand
 Your store is a hook! You can put anything in it: primitives, objects, functions. State has to be updated immutably and the `set` function [merges state](./docs/guides/immutable-state-and-merging.md) to help it.
 
 ```jsx
-import create from 'zustand'
+import { create } from 'zustand'
 
 const useBearStore = create((set) => ({
   bears: 0,
@@ -87,7 +87,7 @@ const honey = useBearStore((state) => state.honey)
 If you want to construct a single object with multiple state-picks inside, similar to redux's mapStateToProps, you can tell zustand that you want the object to be diffed shallowly by passing the `shallow` equality function.
 
 ```jsx
-import shallow from 'zustand/shallow'
+import { shallow } from 'zustand/shallow'
 
 // Object pick, re-renders the component when either state.nuts or state.honey change
 const { nuts, honey } = useBearStore(
@@ -172,8 +172,6 @@ const unsub1 = useDogStore.subscribe(console.log)
 useDogStore.setState({ paw: false })
 // Unsubscribe listeners
 unsub1()
-// Destroying the store (removing all listeners)
-useDogStore.destroy()
 
 // You can of course use the hook as you always would
 const Component = () => {
@@ -222,19 +220,21 @@ const unsub5 = useDogStore.subscribe((state) => state.paw, console.log, {
 Zustand core can be imported and used without the React dependency. The only difference is that the create function does not return a hook, but the API utilities.
 
 ```jsx
-import create from 'zustand/vanilla'
+import { createStore } from 'zustand/vanilla'
 
-const store = create(() => ({ ... }))
-const { getState, setState, subscribe, destroy } = store
+const store = createStore(() => ({ ... }))
+const { getState, setState, subscribe } = store
+
+export default store
 ```
 
-You can even consume an existing vanilla store with React:
+You can use a vanilla store with `useStore` hook available since v4.
 
 ```jsx
-import create from 'zustand'
-import vanillaStore from './vanillaStore'
+import { useStore } from 'zustand'
+import { vanillaStore } from './vanillaStore'
 
-const useBoundStore = create(vanillaStore)
+const useBoundStore = (selector) => useStore(vanillaStore, selector)
 ```
 
 :warning: Note that middlewares that modify `set` or `get` are not applied to `getState` and `setState`.
@@ -309,7 +309,7 @@ const useBeeStore = create(
 You can persist your store's data using any kind of storage.
 
 ```jsx
-import create from 'zustand'
+import { create } from 'zustand'
 import { persist, createJSONStorage } from 'zustand/middleware'
 
 const useFishStore = create(
@@ -333,7 +333,7 @@ const useFishStore = create(
 Immer is available as middleware too.
 
 ```jsx
-import create from 'zustand'
+import { create } from 'zustand'
 import { immer } from 'zustand/middleware/immer'
 
 const useBeeStore = create(
@@ -477,14 +477,12 @@ const Component = () => {
   ...
 ```
 
-[Alternatively, a special createContext is provided.](./docs/previous-versions/zustand-v3-create-context.md)
-
 ## TypeScript Usage
 
 Basic typescript usage doesn't require anything special except for writing `create<State>()(...)` instead of `create(...)`...
 
 ```ts
-import create from 'zustand'
+import { create } from 'zustand'
 import { devtools, persist } from 'zustand/middleware'
 
 interface BearState {
diff --git a/src/context.ts b/src/context.ts
index 9ffd924..341a909 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -21,7 +21,15 @@ type ExtractState<S> = S extends { getState: () => infer T } ? T : never
 
 type WithoutCallSignature<T> = { [K in keyof T]: T[K] }
 
+/**
+ * @deprecated Use `createStore` and `useStore` for context usage
+ */
 function createContext<S extends StoreApi<unknown>>() {
+  if (__DEV__) {
+    console.warn(
+      '[DEPRECATED] zustand/context will be removed in the future version. Please use `import { createStore, useStore } from "zustand"` for context usage. See: https://github.com/pmndrs/zustand/discussions/1180'
+    )
+  }
   const ZustandContext = reactCreateContext<S | undefined>(undefined)
 
   const Provider = ({
diff --git a/src/index.ts b/src/index.ts
index bfca890..b4d7737 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,4 +1,3 @@
 export * from './vanilla'
 export * from './react'
-export { default as createStore } from './vanilla'
 export { default } from './react'
diff --git a/src/react.ts b/src/react.ts
index 12f41fc..ac22100 100644
--- a/src/react.ts
+++ b/src/react.ts
@@ -4,7 +4,7 @@ import { useDebugValue } from 'react'
 // See: https://github.com/pmndrs/valtio/issues/452
 // The following is a workaround until ESM is supported.
 import useSyncExternalStoreExports from 'use-sync-external-store/shim/with-selector'
-import createStore from './vanilla'
+import { createStore } from './vanilla'
 import type {
   Mutate,
   StateCreator,
@@ -61,10 +61,18 @@ type Create = {
   <T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(
     initializer: StateCreator<T, [], Mos>
   ) => UseBoundStore<Mutate<StoreApi<T>, Mos>>
+  /**
+   * @deprecated Use `useStore` hook to bind store
+   */
   <S extends StoreApi<unknown>>(store: S): UseBoundStore<S>
 }
 
 const createImpl = <T>(createState: StateCreator<T, [], []>) => {
+  if (__DEV__ && typeof createState !== 'function') {
+    console.warn(
+      '[DEPRECATED] Passing a vanilla store will be unsupported in the future version. Please use `import { useStore } from "zustand"` to use the vanilla store in React.'
+    )
+  }
   const api =
     typeof createState === 'function' ? createStore(createState) : createState
 
@@ -76,7 +84,15 @@ const createImpl = <T>(createState: StateCreator<T, [], []>) => {
   return useBoundStore
 }
 
-const create = (<T>(createState: StateCreator<T, [], []> | undefined) =>
+export const create = (<T>(createState: StateCreator<T, [], []> | undefined) =>
   createState ? createImpl(createState) : createImpl) as Create
 
-export default create
+/**
+ * @deprecated Use `import { create } from 'zustand'`
+ */
+export default ((createState: any) => {
+  console.warn(
+    "[DEPRECATED] default export is deprecated, instead import { create } from'zustand'"
+  )
+  return create(createState)
+}) as Create
diff --git a/src/shallow.ts b/src/shallow.ts
index 0e7f59e..98ae05c 100644
--- a/src/shallow.ts
+++ b/src/shallow.ts
@@ -1,4 +1,4 @@
-function shallow<T>(objA: T, objB: T) {
+export function shallow<T>(objA: T, objB: T) {
   if (Object.is(objA, objB)) {
     return true
   }
@@ -48,4 +48,12 @@ function shallow<T>(objA: T, objB: T) {
   return true
 }
 
-export default shallow
+/**
+ * @deprecated Use `import { shallow } from 'zustand/shallow'`
+ */
+export default ((objA, objB) => {
+  console.warn(
+    "[DEPRECATED] default export is deprecated, instead import { shallow } from'zustand/shallow'"
+  )
+  return shallow(objA, objB)
+}) as typeof shallow
diff --git a/src/vanilla.ts b/src/vanilla.ts
index 469ac70..d07dfe5 100644
--- a/src/vanilla.ts
+++ b/src/vanilla.ts
@@ -9,6 +9,9 @@ export interface StoreApi<T> {
   setState: SetStateInternal<T>
   getState: () => T
   subscribe: (listener: (state: T, prevState: T) => void) => () => void
+  /**
+   * @deprecated Use `unsubscribe` returned by `subscribe`
+   */
   destroy: () => void
 }
 
@@ -85,16 +88,32 @@ const createStoreImpl: CreateStoreImpl = (createState) => {
     return () => listeners.delete(listener)
   }
 
-  const destroy: StoreApi<TState>['destroy'] = () => listeners.clear()
+  const destroy: StoreApi<TState>['destroy'] = () => {
+    if (__DEV__) {
+      console.warn(
+        '[DEPRECATED] The destroy method will be unsupported in the future version. You should use unsubscribe function returned by subscribe. Everything will be garbage collected if store is garbage collected.'
+      )
+    }
+    listeners.clear()
+  }
+
   const api = { setState, getState, subscribe, destroy }
   state = createState(setState, getState, api)
   return api as any
 }
 
-const createStore = ((createState) =>
+export const createStore = ((createState) =>
   createState ? createStoreImpl(createState) : createStoreImpl) as CreateStore
 
-export default createStore
+/**
+ * @deprecated Use `import { createStore } from ...`
+ */
+export default ((createState) => {
+  console.warn(
+    '[DEPRECATED] default export is deprecated, instead import { createStore } ...'
+  )
+  return createStore(createState)
+}) as CreateStore
 
 // ---------------------------------------------------------
 


Test patch:
diff --git a/docs/guides/testing.mdx b/docs/guides/testing.mdx
index 33008f3..eb142ca 100644
--- a/docs/guides/testing.mdx
+++ b/docs/guides/testing.mdx
@@ -11,7 +11,7 @@ When running tests, the stores are not automatically reset before each test run.
 Thus, there can be cases where the state of one test can affect another. To make sure all tests run with a pristine store state, you can mock `zustand` during testing and use the following code to create your store:
 
 ```jsx
-import actualCreate from 'zustand'
+import { create: actualCreate } from 'zustand'
 // const actualCreate = jest.requireActual('zustand') // if using jest
 import { act } from 'react-dom/test-utils'
 
@@ -43,7 +43,7 @@ In [jest](https://jestjs.io/), you can create a `__mocks__/zustand.js` and place
 If you are using zustand, as documented in [TypeScript Guide](./typescript.md), use the following code:
 
 ```tsx
-import actualCreate, { StateCreator } from 'zustand'
+import { create: actualCreate, StateCreator } from 'zustand'
 // const actualCreate = jest.requireActual('zustand') // if using jest
 import { act } from 'react-dom/test-utils'
 
diff --git a/tests/basic.test.tsx b/tests/basic.test.tsx
index 41aec90..21c4ba9 100644
--- a/tests/basic.test.tsx
+++ b/tests/basic.test.tsx
@@ -8,7 +8,8 @@ import {
 } from 'react'
 import { act, fireEvent, render } from '@testing-library/react'
 import ReactDOM from 'react-dom'
-import create, { StoreApi } from 'zustand'
+import { create } from 'zustand'
+import type { StoreApi } from 'zustand'
 
 const consoleError = console.error
 afterEach(() => {
diff --git a/tests/context.test.tsx b/tests/context.test.tsx
index 2f41f10..39705fa 100644
--- a/tests/context.test.tsx
+++ b/tests/context.test.tsx
@@ -7,7 +7,8 @@ import {
   useState,
 } from 'react'
 import { render } from '@testing-library/react'
-import create, { StoreApi } from 'zustand'
+import { create } from 'zustand'
+import type { StoreApi } from 'zustand'
 import createContext from 'zustand/context'
 import { subscribeWithSelector } from 'zustand/middleware'
 
diff --git a/tests/devtools.test.tsx b/tests/devtools.test.tsx
index ea133d0..30827d1 100644
--- a/tests/devtools.test.tsx
+++ b/tests/devtools.test.tsx
@@ -2,8 +2,8 @@ import { StoreApi } from 'zustand/vanilla'
 
 const getImports = async () => {
   const { devtools } = await import('zustand/middleware')
-  const create = (await import('zustand/vanilla')).default
-  return { create, devtools }
+  const { createStore } = await import('zustand/vanilla')
+  return { createStore, devtools }
 }
 
 type TupleOfEqualLengthH<
@@ -125,10 +125,10 @@ beforeEach(() => {
 })
 
 it('connects to the extension by passing the options and initializes', async () => {
-  const { devtools, create } = await getImports()
+  const { devtools, createStore } = await getImports()
   const options = { name: 'test', foo: 'bar' }
   const initialState = { count: 0 }
-  create(devtools(() => initialState, { enabled: true, ...options }))
+  createStore(devtools(() => initialState, { enabled: true, ...options }))
 
   expect(extensionConnector.connect).toHaveBeenLastCalledWith(options)
 
@@ -152,48 +152,48 @@ describe('If there is no extension installed...', () => {
   })
 
   it('does not throw', async () => {
-    const { devtools, create } = await getImports()
+    const { devtools, createStore } = await getImports()
     expect(() => {
-      create(devtools(() => ({ count: 0 })))
+      createStore(devtools(() => ({ count: 0 })))
     }).not.toThrow()
   })
 
   it('does not warn if not enabled', async () => {
-    const { devtools, create } = await getImports()
-    create(devtools(() => ({ count: 0 })))
+    const { devtools, createStore } = await getImports()
+    createStore(devtools(() => ({ count: 0 })))
     expect(console.warn).not.toBeCalled()
   })
 
   it('[DEV-ONLY] warns if enabled in dev mode', async () => {
-    const { devtools, create } = await getImports()
+    const { devtools, createStore } = await getImports()
     __DEV__ = true
-    create(devtools(() => ({ count: 0 }), { enabled: true }))
+    createStore(devtools(() => ({ count: 0 }), { enabled: true }))
     expect(console.warn).toBeCalled()
   })
 
   it('[PRD-ONLY] does not warn if not in dev env', async () => {
-    const { devtools, create } = await getImports()
+    const { devtools, createStore } = await getImports()
     __DEV__ = false
-    create(devtools(() => ({ count: 0 })))
+    createStore(devtools(() => ({ count: 0 })))
     expect(console.warn).not.toBeCalled()
   })
 
   it('[PRD-ONLY] does not warn if not in dev env even if enabled', async () => {
-    const { devtools, create } = await getImports()
+    const { devtools, createStore } = await getImports()
     __DEV__ = false
-    create(devtools(() => ({ count: 0 }), { enabled: true }))
+    createStore(devtools(() => ({ count: 0 }), { enabled: true }))
     expect(console.warn).not.toBeCalled()
   })
 })
 
 describe('When state changes...', () => {
   it("sends { type: setStateName || 'anonymous`, ...rest } as the action with current state", async () => {
-    const { devtools, create } = await getImports()
+    const { devtools, createStore } = await getImports()
     const options = {
       name: 'testOptionsName',
       enabled: true,
     }
-    const api = create(devtools(() => ({ count: 0, foo: 'bar' }), options))
+    const api = createStore(devtools(() => ({ count: 0, foo: 'bar' }), options))
 
     api.setState({ count: 10 }, false, 'testSetStateName')
     const [connection] = getNamedConnectionApis(options.name)
@@ -222,9 +222,9 @@ describe('When state changes...', () => {
 describe('when it receives a message of type...', () => {
   describe('ACTION...', () => {
     it('does nothing', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const initialState = { count: 0 }
-      const api = create(devtools(() => initialState, { enabled: true }))
+      const api = createStore(devtools(() => initialState, { enabled: true }))
       const setState = jest.spyOn(api, 'setState')
 
       const [subscriber] = getNamedConnectionSubscribers(undefined)
@@ -238,9 +238,9 @@ describe('when it receives a message of type...', () => {
     })
 
     it('unless action type is __setState', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const initialState = { count: 0 }
-      const api = create(devtools(() => initialState, { enabled: true }))
+      const api = createStore(devtools(() => initialState, { enabled: true }))
 
       const [connectionSubscriber] = getNamedConnectionSubscribers(undefined)
       connectionSubscriber({
@@ -252,9 +252,9 @@ describe('when it receives a message of type...', () => {
     })
 
     it('does nothing even if there is `api.dispatch`', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const initialState = { count: 0 }
-      const api = create(devtools(() => initialState, { enabled: true }))
+      const api = createStore(devtools(() => initialState, { enabled: true }))
       ;(api as any).dispatch = jest.fn()
       const setState = jest.spyOn(api, 'setState')
 
@@ -270,9 +270,9 @@ describe('when it receives a message of type...', () => {
     })
 
     it('dispatches with `api.dispatch` when `api.dispatchFromDevtools` is set to true', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const initialState = { count: 0 }
-      const api = create(devtools(() => initialState, { enabled: true }))
+      const api = createStore(devtools(() => initialState, { enabled: true }))
       ;(api as any).dispatch = jest.fn()
       ;(api as any).dispatchFromDevtools = true
       const setState = jest.spyOn(api, 'setState')
@@ -291,9 +291,9 @@ describe('when it receives a message of type...', () => {
     })
 
     it('does not throw for unsupported payload', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const initialState = { count: 0 }
-      const api = create(devtools(() => initialState, { enabled: true }))
+      const api = createStore(devtools(() => initialState, { enabled: true }))
       ;(api as any).dispatch = jest.fn()
       ;(api as any).dispatchFromDevtools = true
       const setState = jest.spyOn(api, 'setState')
@@ -340,9 +340,9 @@ describe('when it receives a message of type...', () => {
 
   describe('DISPATCH and payload of type...', () => {
     it('RESET, it inits with initial state', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const initialState = { count: 0 }
-      const api = create(devtools(() => initialState, { enabled: true }))
+      const api = createStore(devtools(() => initialState, { enabled: true }))
       api.setState({ count: 1 })
 
       const [connection] = getNamedConnectionApis(undefined)
@@ -359,9 +359,9 @@ describe('when it receives a message of type...', () => {
     })
 
     it('COMMIT, it inits with current state', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const initialState = { count: 0 }
-      const api = create(devtools(() => initialState, { enabled: true }))
+      const api = createStore(devtools(() => initialState, { enabled: true }))
       api.setState({ count: 2 })
       const currentState = api.getState()
 
@@ -379,9 +379,9 @@ describe('when it receives a message of type...', () => {
 
     describe('ROLLBACK...', () => {
       it('it updates state without recording and inits with `message.state`', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const initialState = { count: 0, increment: () => {} }
-        const api = create(devtools(() => initialState, { enabled: true }))
+        const api = createStore(devtools(() => initialState, { enabled: true }))
         const newState = { foo: 'bar' }
 
         const [connection] = getNamedConnectionApis(undefined)
@@ -402,10 +402,10 @@ describe('when it receives a message of type...', () => {
       })
 
       it('does not throw for unparsable `message.state`', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const increment = () => {}
         const initialState = { count: 0, increment }
-        const api = create(devtools(() => initialState, { enabled: true }))
+        const api = createStore(devtools(() => initialState, { enabled: true }))
         const originalConsoleError = console.error
         console.error = jest.fn()
 
@@ -440,9 +440,9 @@ describe('when it receives a message of type...', () => {
     describe('JUMP_TO_STATE...', () => {
       const increment = () => {}
       it('it updates state without recording with `message.state`', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const initialState = { count: 0, increment }
-        const api = create(devtools(() => initialState, { enabled: true }))
+        const api = createStore(devtools(() => initialState, { enabled: true }))
         const newState = { foo: 'bar' }
 
         const [connection] = getNamedConnectionApis(undefined)
@@ -458,9 +458,9 @@ describe('when it receives a message of type...', () => {
       })
 
       it('does not throw for unparsable `message.state`', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const initialState = { count: 0, increment: () => {} }
-        const api = create(devtools(() => initialState, { enabled: true }))
+        const api = createStore(devtools(() => initialState, { enabled: true }))
         const originalConsoleError = console.error
         console.error = jest.fn()
 
@@ -492,9 +492,9 @@ describe('when it receives a message of type...', () => {
 
     describe('JUMP_TO_ACTION...', () => {
       it('it updates state without recording with `message.state`', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const initialState = { count: 0, increment: () => {} }
-        const api = create(devtools(() => initialState, { enabled: true }))
+        const api = createStore(devtools(() => initialState, { enabled: true }))
         const newState = { foo: 'bar' }
 
         const [connection] = getNamedConnectionApis(undefined)
@@ -510,10 +510,10 @@ describe('when it receives a message of type...', () => {
       })
 
       it('does not throw for unparsable `message.state`', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const increment = () => {}
         const initialState = { count: 0, increment }
-        const api = create(devtools(() => initialState, { enabled: true }))
+        const api = createStore(devtools(() => initialState, { enabled: true }))
         const originalConsoleError = console.error
         console.error = jest.fn()
 
@@ -544,9 +544,9 @@ describe('when it receives a message of type...', () => {
     })
 
     it('IMPORT_STATE, it updates state without recording and inits the last computedState', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const initialState = { count: 0, increment: () => {} }
-      const api = create(devtools(() => initialState, { enabled: true }))
+      const api = createStore(devtools(() => initialState, { enabled: true }))
       const nextLiftedState = {
         computedStates: [{ state: { count: 4 } }, { state: { count: 5 } }],
       }
@@ -569,8 +569,8 @@ describe('when it receives a message of type...', () => {
     })
 
     it('PAUSE_RECORDING, it toggles the sending of actions', async () => {
-      const { devtools, create } = await getImports()
-      const api = create(devtools(() => ({ count: 0 }), { enabled: true }))
+      const { devtools, createStore } = await getImports()
+      const api = createStore(devtools(() => ({ count: 0 }), { enabled: true }))
 
       api.setState({ count: 1 }, false, 'increment')
       const [connection] = getNamedConnectionApis(undefined)
@@ -613,8 +613,8 @@ describe('with redux middleware', () => {
 
   it('works as expected', async () => {
     const { devtools, redux } = await import('zustand/middleware')
-    const create = (await import('zustand/vanilla')).default
-    api = create(
+    const { createStore } = await import('zustand/vanilla')
+    api = createStore(
       devtools(
         redux(
           (
@@ -660,32 +660,32 @@ describe('with redux middleware', () => {
 })
 
 it('works in non-browser env', async () => {
-  const { devtools, create } = await getImports()
+  const { devtools, createStore } = await getImports()
   const originalWindow = global.window
   global.window = undefined as any
 
   expect(() => {
-    create(devtools(() => ({ count: 0 }), { enabled: true }))
+    createStore(devtools(() => ({ count: 0 }), { enabled: true }))
   }).not.toThrow()
 
   global.window = originalWindow
 })
 
 it('works in react native env', async () => {
-  const { devtools, create } = await getImports()
+  const { devtools, createStore } = await getImports()
   const originalWindow = global.window
   global.window = {} as any
 
   expect(() => {
-    create(devtools(() => ({ count: 0 }), { enabled: true }))
+    createStore(devtools(() => ({ count: 0 }), { enabled: true }))
   }).not.toThrow()
 
   global.window = originalWindow
 })
 
 it('preserves isRecording after setting from devtools', async () => {
-  const { devtools, create } = await getImports()
-  const api = create(devtools(() => ({ count: 0 }), { enabled: true }))
+  const { devtools, createStore } = await getImports()
+  const api = createStore(devtools(() => ({ count: 0 }), { enabled: true }))
   const [connection] = getNamedConnectionApis(undefined)
   const [connectionSubscriber] = getNamedConnectionSubscribers(undefined)
   connectionSubscriber({
@@ -716,28 +716,28 @@ it('preserves isRecording after setting from devtools', async () => {
 
 describe('when redux connection was called on multiple stores with `name` undefined in `devtools` options', () => {
   it('should create separate connection for each devtools store with .connect call', async () => {
-    const { devtools, create } = await getImports()
+    const { devtools, createStore } = await getImports()
     const options1 = { foo: 'bar', testConnectionId: 'asdf' }
     const options2 = { foo: 'barr', testConnectionId: '123asd' }
     const initialState1 = { count: 0 }
     const initialState2 = { count1: 1 }
 
-    create(devtools(() => initialState1, { enabled: true, ...options1 }))
-    create(devtools(() => initialState2, { enabled: true, ...options2 }))
+    createStore(devtools(() => initialState1, { enabled: true, ...options1 }))
+    createStore(devtools(() => initialState2, { enabled: true, ...options2 }))
 
     expect(extensionConnector.connect).toHaveBeenNthCalledWith(1, options1)
     expect(extensionConnector.connect).toHaveBeenNthCalledWith(2, options2)
   })
 
   it('should call .init on each different connection object', async () => {
-    const { devtools, create } = await getImports()
+    const { devtools, createStore } = await getImports()
     const options1 = { foo: 'bar', testConnectionId: 'asdf' }
     const options2 = { foo: 'barr', testConnectionId: '123asd' }
     const initialState1 = { count: 0 }
     const initialState2 = { count1: 1 }
 
-    create(devtools(() => initialState1, { enabled: true, ...options1 }))
-    create(devtools(() => initialState2, { enabled: true, ...options2 }))
+    createStore(devtools(() => initialState1, { enabled: true, ...options1 }))
+    createStore(devtools(() => initialState2, { enabled: true, ...options2 }))
 
     const [conn1, conn2] = getUnnamedConnectionApis(
       options1.testConnectionId,
@@ -749,14 +749,14 @@ describe('when redux connection was called on multiple stores with `name` undefi
 
   describe('when `store` property was provided in `devtools` call in options', () => {
     it('should create single connection for all indernal calls of .connect and `store` is not passed to .connect', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const options1 = { store: 'store1123', foo: 'bar1' }
       const options2 = { store: 'store2313132', foo: 'bar2' }
       const initialState1 = { count: 0 }
       const initialState2 = { count1: 1 }
 
-      create(devtools(() => initialState1, { enabled: true, ...options1 }))
-      create(devtools(() => initialState2, { enabled: true, ...options2 }))
+      createStore(devtools(() => initialState1, { enabled: true, ...options1 }))
+      createStore(devtools(() => initialState2, { enabled: true, ...options2 }))
 
       expect(extensionConnector.connect).toHaveBeenCalledTimes(1)
       expect(extensionConnector.connect).toHaveBeenCalledWith({
@@ -765,14 +765,14 @@ describe('when redux connection was called on multiple stores with `name` undefi
     })
 
     it('should call `.init` on single connection with combined states after each `create(devtools` call', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const options1 = { store: 'store12' }
       const options2 = { store: 'store21' }
       const initialState1 = { count1: 0 }
       const initialState2 = { count2: 1 }
 
-      create(devtools(() => initialState1, { enabled: true, ...options1 }))
-      create(devtools(() => initialState2, { enabled: true, ...options2 }))
+      createStore(devtools(() => initialState1, { enabled: true, ...options1 }))
+      createStore(devtools(() => initialState2, { enabled: true, ...options2 }))
 
       expect(extensionConnector.connect).toHaveBeenCalledTimes(1)
       const [connection] = getNamedConnectionApis(undefined)
@@ -791,15 +791,15 @@ describe('when redux connection was called on multiple stores with `name` undefi
 describe('when redux connection was called on multiple stores with `name` provided in `devtools` options', () => {
   describe('when same `name` is provided to all stores in devtools options', () => {
     it('should call .connect of redux extension with `name` that was passed from `devtools` options', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const connectionName = 'test'
       const options1 = { name: connectionName, store: 'store1123', foo: 'bar1' }
       const options2 = { name: connectionName, store: 'store1414', foo: 'bar1' }
       const initialState1 = { count: 0 }
       const initialState2 = { count: 2 }
 
-      create(devtools(() => initialState1, { enabled: true, ...options1 }))
-      create(devtools(() => initialState2, { enabled: true, ...options2 }))
+      createStore(devtools(() => initialState1, { enabled: true, ...options1 }))
+      createStore(devtools(() => initialState2, { enabled: true, ...options2 }))
 
       expect(extensionConnector.connect).toHaveBeenCalledTimes(1)
       expect(extensionConnector.connect).toHaveBeenCalledWith({
@@ -811,7 +811,7 @@ describe('when redux connection was called on multiple stores with `name` provid
 
   describe('when different `name` props were provided for different group of stores in devtools options', () => {
     it('should call .connect of redux extension with `name` that was passed from `devtools` options', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const connectionNameGroup1 = 'test1'
       const connectionNameGroup2 = 'test2'
       const options1 = {
@@ -839,10 +839,10 @@ describe('when redux connection was called on multiple stores with `name` provid
       const initialState3 = { count: 5 }
       const initialState4 = { count: 7 }
 
-      create(devtools(() => initialState1, { enabled: true, ...options1 }))
-      create(devtools(() => initialState2, { enabled: true, ...options2 }))
-      create(devtools(() => initialState3, { enabled: true, ...options3 }))
-      create(devtools(() => initialState4, { enabled: true, ...options4 }))
+      createStore(devtools(() => initialState1, { enabled: true, ...options1 }))
+      createStore(devtools(() => initialState2, { enabled: true, ...options2 }))
+      createStore(devtools(() => initialState3, { enabled: true, ...options3 }))
+      createStore(devtools(() => initialState4, { enabled: true, ...options4 }))
 
       expect(extensionConnector.connect).toHaveBeenCalledTimes(2)
       expect(extensionConnector.connect).toHaveBeenNthCalledWith(1, {
@@ -856,7 +856,7 @@ describe('when redux connection was called on multiple stores with `name` provid
     })
 
     it('should call `.init` on single connection with combined states after each `create(devtools` call', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const connectionNameGroup1 = 'test1'
       const connectionNameGroup2 = 'test2'
       const options1 = {
@@ -884,10 +884,10 @@ describe('when redux connection was called on multiple stores with `name` provid
       const initialState3 = { count: 5 }
       const initialState4 = { count: 7 }
 
-      create(devtools(() => initialState1, { enabled: true, ...options1 }))
-      create(devtools(() => initialState2, { enabled: true, ...options2 }))
-      create(devtools(() => initialState3, { enabled: true, ...options3 }))
-      create(devtools(() => initialState4, { enabled: true, ...options4 }))
+      createStore(devtools(() => initialState1, { enabled: true, ...options1 }))
+      createStore(devtools(() => initialState2, { enabled: true, ...options2 }))
+      createStore(devtools(() => initialState3, { enabled: true, ...options3 }))
+      createStore(devtools(() => initialState4, { enabled: true, ...options4 }))
 
       expect(extensionConnector.connect).toHaveBeenCalledTimes(2)
       const [connection1, connection2] = getNamedConnectionApis(
@@ -913,13 +913,15 @@ describe('when redux connection was called on multiple stores with `name` provid
     })
 
     it('preserves isRecording after setting from devtools on proper connection subscriber', async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const options1 = { name: 'asdf1' }
       const options2 = { name: 'asdf2' }
-      const api1 = create(
+      const api1 = createStore(
         devtools(() => ({ count: 0 }), { enabled: true, ...options1 })
       )
-      create(devtools(() => ({ count: 0 }), { enabled: true, ...options2 }))
+      createStore(
+        devtools(() => ({ count: 0 }), { enabled: true, ...options2 })
+      )
       const connections = getNamedConnectionApis(options1.name, options2.name)
       const [connectionSubscriber] = getNamedConnectionSubscribers(
         options1.name
@@ -953,10 +955,10 @@ describe('when redux connection was called on multiple stores with `name` provid
 
       it('works as expected', async () => {
         const { devtools, redux } = await import('zustand/middleware')
-        const create = (await import('zustand/vanilla')).default
+        const { createStore } = await import('zustand/vanilla')
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
-        api1 = create(
+        api1 = createStore(
           devtools(
             redux(
               (
@@ -970,7 +972,7 @@ describe('when redux connection was called on multiple stores with `name` provid
             { enabled: true, ...options1 }
           )
         )
-        api2 = create(
+        api2 = createStore(
           devtools(
             redux(
               (
@@ -1028,7 +1030,7 @@ describe('when redux connection was called on multiple stores with `name` provid
 describe('when create devtools was called multiple times with `name` option undefined', () => {
   describe('When state changes...', () => {
     it("sends { type: setStateName || 'anonymous`, ...rest } as the action with current state, isolated from other connections", async () => {
-      const { devtools, create } = await getImports()
+      const { devtools, createStore } = await getImports()
       const options1 = {
         enabled: true,
         testConnectionId: '123',
@@ -1041,9 +1043,11 @@ describe('when create devtools was called multiple times with `name` option unde
         enabled: true,
         testConnectionId: '412',
       }
-      const api1 = create(devtools(() => ({ count: 0, foo: 'bar' }), options1))
-      create(devtools(() => ({ count: 0, foo: 'bar1' }), options2))
-      create(devtools(() => ({ count: 0, foo: 'bar2' }), options3))
+      const api1 = createStore(
+        devtools(() => ({ count: 0, foo: 'bar' }), options1)
+      )
+      createStore(devtools(() => ({ count: 0, foo: 'bar1' }), options2))
+      createStore(devtools(() => ({ count: 0, foo: 'bar2' }), options3))
 
       api1.setState({ count: 10 }, false, 'testSetStateName')
       const [connection1, connection2, connection3] = getUnnamedConnectionApis(
@@ -1082,26 +1086,26 @@ describe('when create devtools was called multiple times with `name` option unde
   describe('when it receives a message of type...', () => {
     describe('ACTION...', () => {
       it('does nothing, connections isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: '123' }
         const options2 = { testConnectionId: '231' }
         const options3 = { testConnectionId: '4342' }
         const initialState1 = { count: 0 }
         const initialState2 = { count: 2 }
         const initialState3 = { count: 3 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, {
             enabled: true,
             ...options1,
           })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, {
             enabled: true,
             ...options2,
           })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, {
             enabled: true,
             ...options3,
@@ -1128,20 +1132,20 @@ describe('when create devtools was called multiple times with `name` option unde
       })
 
       it('unless action type is __setState, connections isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0 }
         const initialState2 = { count: 2 }
         const initialState3 = { count: 5 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
 
@@ -1159,20 +1163,20 @@ describe('when create devtools was called multiple times with `name` option unde
       })
 
       it('does nothing even if there is `api.dispatch`, connections isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0 }
         const initialState2 = { count: 2 }
         const initialState3 = { count: 5 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         ;(api1 as any).dispatch = jest.fn()
@@ -1205,20 +1209,20 @@ describe('when create devtools was called multiple times with `name` option unde
       })
 
       it('dispatches with `api.dispatch` when `api.dispatchFromDevtools` is set to true, connections are isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0 }
         const initialState2 = { count: 2 }
         const initialState3 = { count: 5 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         ;(api1 as any).dispatch = jest.fn()
@@ -1260,20 +1264,20 @@ describe('when create devtools was called multiple times with `name` option unde
       })
 
       it('does not throw for unsupported payload, connections are isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0 }
         const initialState2 = { count: 2 }
         const initialState3 = { count: 5 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         ;(api1 as any).dispatch = jest.fn()
@@ -1398,20 +1402,20 @@ describe('when create devtools was called multiple times with `name` option unde
 
     describe('DISPATCH and payload of type...', () => {
       it('RESET, it inits with initial state, connections are isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0 }
         const initialState2 = { count: 2 }
         const initialState3 = { count: 5 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         api1.setState({ count: 1 })
@@ -1446,20 +1450,20 @@ describe('when create devtools was called multiple times with `name` option unde
       })
 
       it('COMMIT, it inits with current state, connections are isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0 }
         const initialState2 = { count: 2 }
         const initialState3 = { count: 5 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         api1.setState({ count: 1 })
@@ -1496,20 +1500,20 @@ describe('when create devtools was called multiple times with `name` option unde
 
     describe('ROLLBACK...', () => {
       it('it updates state without recording and inits with `message.state, connections are isolated from each other`', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0, increment: () => {} }
         const initialState2 = { count: 2, increment: () => {} }
         const initialState3 = { count: 5, increment: () => {} }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         const newState1 = { foo: 'bar1' }
@@ -1576,7 +1580,7 @@ describe('when create devtools was called multiple times with `name` option unde
       })
 
       it('does not throw for unparsable `message.state`, connections are isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const increment1 = () => {}
         const increment2 = () => {}
         const increment3 = () => {}
@@ -1586,13 +1590,13 @@ describe('when create devtools was called multiple times with `name` option unde
         const initialState1 = { count: 0, increment: increment1 }
         const initialState2 = { count: 2, increment: increment2 }
         const initialState3 = { count: 5, increment: increment3 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         const originalConsoleError = console.error
@@ -1678,20 +1682,20 @@ describe('when create devtools was called multiple times with `name` option unde
       const increment3 = () => {}
 
       it('it updates state without recording with `message.state`, connections are isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0, increment: increment1 }
         const initialState2 = { count: 2, increment: increment2 }
         const initialState3 = { count: 5, increment: increment3 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         const newState1 = { foo: 'bar1' }
@@ -1745,20 +1749,20 @@ describe('when create devtools was called multiple times with `name` option unde
       })
 
       it('does not throw for unparsable `message.state`, connections are isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0, increment: increment1 }
         const initialState2 = { count: 2, increment: increment2 }
         const initialState3 = { count: 5, increment: increment3 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         const originalConsoleError = console.error
@@ -1841,20 +1845,20 @@ describe('when create devtools was called multiple times with `name` option unde
       const increment3 = () => {}
 
       it('it updates state without recording with `message.state`, connections are isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0, increment: increment1 }
         const initialState2 = { count: 2, increment: increment2 }
         const initialState3 = { count: 5, increment: increment3 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         const newState1 = { foo: 'bar1' }
@@ -1909,20 +1913,20 @@ describe('when create devtools was called multiple times with `name` option unde
       })
 
       it('does not throw for unparsable `message.state`, connections are isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0, increment: increment1 }
         const initialState2 = { count: 2, increment: increment2 }
         const initialState3 = { count: 5, increment: increment3 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         const originalConsoleError = console.error
@@ -1998,20 +2002,20 @@ describe('when create devtools was called multiple times with `name` option unde
       })
 
       it('IMPORT_STATE, it updates state without recording and inits the last computedState, connections are isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
         const initialState1 = { count: 0, increment: increment1 }
         const initialState2 = { count: 2, increment: increment2 }
         const initialState3 = { count: 5, increment: increment3 }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => initialState1, { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => initialState2, { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => initialState3, { enabled: true, ...options3 })
         )
         const nextLiftedState1 = {
@@ -2090,17 +2094,17 @@ describe('when create devtools was called multiple times with `name` option unde
       })
 
       it('PAUSE_RECORDING, it toggles the sending of actions, connections are isolated from each other', async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options1 = { testConnectionId: 'asdf' }
         const options2 = { testConnectionId: '2f' }
         const options3 = { testConnectionId: 'd2e' }
-        const api1 = create(
+        const api1 = createStore(
           devtools(() => ({ count: 0 }), { enabled: true, ...options1 })
         )
-        const api2 = create(
+        const api2 = createStore(
           devtools(() => ({ count: 2 }), { enabled: true, ...options2 })
         )
-        const api3 = create(
+        const api3 = createStore(
           devtools(() => ({ count: 4 }), { enabled: true, ...options3 })
         )
 
@@ -2204,13 +2208,15 @@ describe('when create devtools was called multiple times with `name` and `store`
   describe('when `type` was provided in store state methods as option', () => {
     describe('When state changes...', () => {
       it("sends { type: setStateName || 'anonymous`, ...rest } as the action with current state", async () => {
-        const { devtools, create } = await getImports()
+        const { devtools, createStore } = await getImports()
         const options = {
           name: 'testOptionsName',
           store: 'someStore',
           enabled: true,
         }
-        const api = create(devtools(() => ({ count: 0, foo: 'bar' }), options))
+        const api = createStore(
+          devtools(() => ({ count: 0, foo: 'bar' }), options)
+        )
 
         const testStateActionType = 'testSetStateName'
 
@@ -2241,32 +2247,32 @@ describe('when create devtools was called multiple times with `name` and `store`
     describe('when it receives a message of type...', () => {
       describe('ACTION...', () => {
         it('does nothing, connections isolated from each other', async () => {
-          const { devtools, create } = await getImports()
+          const { devtools, createStore } = await getImports()
           const options1 = { testConnectionId: '123', store: 'store1' }
           const options2 = { testConnectionId: '231', store: 'store2' }
           const initialState1 = { count: 0 }
           const initialState2 = { count: 2 }
           const initialState3 = { count: 5 }
           const initialState4 = { count: 6 }
-          const api1 = create(
+          const api1 = createStore(
             devtools(() => initialState1, {
               enabled: true,
               ...options1,
             })
           )
-          const api2 = create(
+          const api2 = createStore(
             devtools(() => initialState2, {
               enabled: true,
               ...options1,
             })
           )
-          const api3 = create(
+          const api3 = createStore(
             devtools(() => initialState3, {
               enabled: true,
               ...options2,
             })
           )
-          const api4 = create(
+          const api4 = createStore(
             devtools(() => initialState4, {
               enabled: true,
               ...options2,
@@ -2296,7 +2302,7 @@ describe('when create devtools was called multiple times with `name` and `store`
         })
 
         it('unless action type is __setState, connections isolated from each other', async () => {
-          const { devtools, create } = await getImports()
+          const { devtools, createStore } = await getImports()
           const name1 = 'name1'
           const name2 = 'name2'
           const store1 = 'someStore1'
@@ -2313,10 +2319,10 @@ describe('when create devtools was called multiple times with `name` and `store`
           }
           const initialState1 = { count: 0 }
           const initialState2 = { count: 2 }
-          const api1 = create(
+          const api1 = createStore(
             devtools(() => initialState1, { enabled: true, ...options1 })
           )
-          const api2 = create(
+          const api2 = createStore(
             devtools(() => initialState2, { enabled: true, ...options2 })
           )
           const originalConsoleError = console.error
@@ -2353,7 +2359,7 @@ describe('when create devtools was called multiple times with `name` and `store`
         })
 
         it('does nothing even if there is `api.dispatch`, connections isolated from each other', async () => {
-          const { devtools, create } = await getImports()
+          const { devtools, createStore } = await getImports()
           const name1 = 'name1'
           const name2 = 'name2'
           const store1 = 'someStore1'
@@ -2370,10 +2376,10 @@ describe('when create devtools was called multiple times with `name` and `store`
           }
           const initialState1 = { count: 0 }
           const initialState2 = { count: 2 }
-          const api1 = create(
+          const api1 = createStore(
             devtools(() => initialState1, { enabled: true, ...options1 })
           )
-          const api2 = create(
+          const api2 = createStore(
             devtools(() => initialState2, { enabled: true, ...options2 })
           )
           ;(api1 as any).dispatch = jest.fn()
@@ -2400,7 +2406,7 @@ describe('when create devtools was called multiple times with `name` and `store`
         })
 
         it('dispatches with `api.dispatch` when `api.dispatchFromDevtools` is set to true, connections are isolated from each other', async () => {
-          const { devtools, create } = await getImports()
+          const { devtools, createStore } = await getImports()
           const name1 = 'name1'
           const name2 = 'name2'
           const store1 = 'someStore1'
@@ -2417,10 +2423,10 @@ describe('when create devtools was called multiple times with `name` and `store`
           }
           const initialState1 = { count: 0 }
           const initialState2 = { count: 2 }
-          const api1 = create(
+          const api1 = createStore(
             devtools(() => initialState1, { enabled: true, ...options1 })
           )
-          const api2 = create(
+          const api2 = createStore(
             devtools(() => initialState2, { enabled: true, ...options2 })
           )
           ;(api1 as any).dispatch = jest.fn()
diff --git a/tests/middlewareTypes.test.tsx b/tests/middlewareTypes.test.tsx
index a1bcc6e..200132d 100644
--- a/tests/middlewareTypes.test.tsx
+++ b/tests/middlewareTypes.test.tsx
@@ -1,4 +1,5 @@
-import create, { StoreApi } from 'zustand'
+import { create } from 'zustand'
+import type { StoreApi } from 'zustand'
 import {
   combine,
   devtools,
@@ -7,7 +8,7 @@ import {
   subscribeWithSelector,
 } from 'zustand/middleware'
 import { immer } from 'zustand/middleware/immer'
-import createVanilla from 'zustand/vanilla'
+import { createStore } from 'zustand/vanilla'
 
 type CounterState = {
   count: number
@@ -63,7 +64,7 @@ describe('counter state spec (single middleware)', () => {
     }
     TestComponent
 
-    const _testSubtyping: StoreApi<object> = createVanilla(
+    const _testSubtyping: StoreApi<object> = createStore(
       immer(() => ({ count: 0 }))
     )
   })
@@ -91,7 +92,7 @@ describe('counter state spec (single middleware)', () => {
     }
     TestComponent
 
-    const _testSubtyping: StoreApi<object> = createVanilla(
+    const _testSubtyping: StoreApi<object> = createStore(
       redux((x) => x, { count: 0 })
     )
   })
@@ -119,7 +120,7 @@ describe('counter state spec (single middleware)', () => {
     }
     TestComponent
 
-    const _testSubtyping: StoreApi<object> = createVanilla(
+    const _testSubtyping: StoreApi<object> = createStore(
       devtools(() => ({ count: 0 }))
     )
   })
@@ -146,7 +147,7 @@ describe('counter state spec (single middleware)', () => {
     }
     TestComponent
 
-    const _testSubtyping: StoreApi<object> = createVanilla(
+    const _testSubtyping: StoreApi<object> = createStore(
       subscribeWithSelector(() => ({ count: 0 }))
     )
   })
@@ -168,7 +169,7 @@ describe('counter state spec (single middleware)', () => {
     }
     TestComponent
 
-    const _testSubtyping: StoreApi<object> = createVanilla(
+    const _testSubtyping: StoreApi<object> = createStore(
       combine({ count: 0 }, () => ({}))
     )
   })
@@ -195,7 +196,7 @@ describe('counter state spec (single middleware)', () => {
     }
     TestComponent
 
-    const _testSubtyping: StoreApi<object> = createVanilla(
+    const _testSubtyping: StoreApi<object> = createStore(
       persist(() => ({ count: 0 }), { name: 'prefix' })
     )
   })
diff --git a/tests/persistAsync.test.tsx b/tests/persistAsync.test.tsx
index 684de6e..ae6f1db 100644
--- a/tests/persistAsync.test.tsx
+++ b/tests/persistAsync.test.tsx
@@ -1,6 +1,6 @@
 import { StrictMode, useEffect } from 'react'
 import { act, render, waitFor } from '@testing-library/react'
-import create from 'zustand'
+import { create } from 'zustand'
 import { persist } from 'zustand/middleware'
 
 const createPersistantStore = (initialValue: string | null) => {
diff --git a/tests/persistSync.test.tsx b/tests/persistSync.test.tsx
index 7bbd2b3..3e2a7a1 100644
--- a/tests/persistSync.test.tsx
+++ b/tests/persistSync.test.tsx
@@ -1,4 +1,4 @@
-import create from 'zustand'
+import { create } from 'zustand'
 import { persist } from 'zustand/middleware'
 
 const createPersistentStore = (initialValue: string | null) => {
diff --git a/tests/shallow.test.tsx b/tests/shallow.test.tsx
index a60008e..6f45206 100644
--- a/tests/shallow.test.tsx
+++ b/tests/shallow.test.tsx
@@ -1,5 +1,5 @@
-import create from 'zustand'
-import shallow from 'zustand/shallow'
+import { create } from 'zustand'
+import { shallow } from 'zustand/shallow'
 
 describe('shallow', () => {
   it('compares primitive values', () => {
diff --git a/tests/subscribe.test.tsx b/tests/subscribe.test.tsx
index 154aa12..fa5a5db 100644
--- a/tests/subscribe.test.tsx
+++ b/tests/subscribe.test.tsx
@@ -1,4 +1,4 @@
-import create from 'zustand'
+import { create } from 'zustand'
 import { subscribeWithSelector } from 'zustand/middleware'
 
 describe('subscribe()', () => {
diff --git a/tests/types.test.tsx b/tests/types.test.tsx
index 2b78749..a24317c 100644
--- a/tests/types.test.tsx
+++ b/tests/types.test.tsx
@@ -1,4 +1,4 @@
-import create from 'zustand'
+import { create } from 'zustand'
 import type {
   StateCreator,
   StoreApi,