diff --git a/.changeset/gentle-kiwis-promise.md b/.changeset/gentle-kiwis-promise.md
new file mode 100644
index 00000000000..dfe650df934
--- /dev/null
+++ b/.changeset/gentle-kiwis-promise.md
@@ -0,0 +1,5 @@
+---
+'@rest-hooks/react': minor
+---
+
+useController().fetch resolves to denormalized form
diff --git a/.changeset/good-spoons-look.md b/.changeset/good-spoons-look.md
new file mode 100644
index 00000000000..9d2e4c59cd7
--- /dev/null
+++ b/.changeset/good-spoons-look.md
@@ -0,0 +1,5 @@
+---
+'@rest-hooks/rest': patch
+---
+
+Add commonjs export for /next
diff --git a/.changeset/perfect-grapes-glow.md b/.changeset/perfect-grapes-glow.md
new file mode 100644
index 00000000000..c045680d7dc
--- /dev/null
+++ b/.changeset/perfect-grapes-glow.md
@@ -0,0 +1,6 @@
+---
+'@rest-hooks/react': minor
+'@rest-hooks/core': minor
+---
+
+Add /next export for early adoption of breaking changes
diff --git a/.changeset/smart-dragons-rhyme.md b/.changeset/smart-dragons-rhyme.md
new file mode 100644
index 00000000000..59b29127f75
--- /dev/null
+++ b/.changeset/smart-dragons-rhyme.md
@@ -0,0 +1,5 @@
+---
+'@rest-hooks/core': minor
+---
+
+Controller.fetch resolves to denormalized form and is fully typed
diff --git a/docs/core/api/Controller.md b/docs/core/api/Controller.md
index 53af9ddf051..8f79014f29d 100644
--- a/docs/core/api/Controller.md
+++ b/docs/core/api/Controller.md
@@ -113,16 +113,15 @@ function PostListItem({ post }: { post: PostResource }) {
:::tip
`fetch` has the same return value as the [Endpoint](/rest/api/Endpoint) passed to it.
-When using schemas, the denormalized value can be retrieved using a combination of
-[Controller.getResponse](#getResponse) and [Controller.getState](#getState)
+When using schemas, the denormalized value can be retrieved using the future-compatible /next import
```ts
-await controller.fetch(PostResource.create, createPayload);
-const { data: denormalizedResponse } = controller.getResponse(
- PostResource.create,
- createPayload,
- controller.getState(),
-);
+// highlight-next-line
+import { useController } from '@rest-hooks/react/next';
+
+const post = await controller.fetch(PostResource.create, createPayload);
+post.title;
+post.pk();
```
:::
diff --git a/docs/core/api/useController.md b/docs/core/api/useController.md
index 1e13256bc34..1f772b8c398 100644
--- a/docs/core/api/useController.md
+++ b/docs/core/api/useController.md
@@ -7,6 +7,8 @@ title: useController()
+import TypeScriptEditor from '@site/src/components/TypeScriptEditor';
+
[Controller](./Controller.md) provides type-safe methods to manipulate the store.
For instance [fetch](./Controller.md#fetch), [invalidate](./Controller.md#invalidate),
@@ -43,6 +45,19 @@ function MyComponent({ id }) {
## Examples
+### /next
+
+`@rest-hooks/react/next` contains the version of `useController()` that will ship with the next version.
+This provides a return value that matches [useSuspense()](./useSuspense.md) - utilizing the [Endpoint.schema](/rest/api/RestEndpoint#schema)
+
+```ts
+import { useController } from '@rest-hooks/react/next';
+
+const post = await controller.fetch(PostResource.create, createPayload);
+post.title;
+post.pk();
+```
+
### Todo App