Skip to content

design(react): nothing can be imported from @ic-reactor/react in a React Server Component, not even the core classes it re-exports #679

Description

@b3hr4d

What happens

@ic-reactor/react has one entry, dist/index.js, which re-exports @ic-reactor/core and every hook module. A React Server Component that imports anything from it, including only ClientManager and Reactor, pulls in useSyncExternalStore, useEffect, useRef and useState, and the App Router build fails. Measured in examples/nextjs-app-router (Next 16, Turbopack) with one server-component page:

page imports next build
defineReactor from @ic-reactor/react fails: "You're importing a module that depends on useSyncExternalStore into a React Server Component module"
ClientManager, Reactor from @ic-reactor/react fails: 6 errors, "depends on useEffect" / useRef / useState
ClientManager, Reactor from @ic-reactor/core (listed in package.json) builds, exit 0

The README says the package "re-exports everything from @ic-reactor/core" so users "can import these from a single package", and until the docs fix in docs/react-readme-rsc-auth it said a server component may import Reactor / ClientManager from it.

Options

A. Docs only (done in docs/react-readme-rsc-auth). Server components import from @ic-reactor/core and list it as a dependency. No package change. Cost: React apps need a second runtime dependency for server code, and the "single package" promise has an exception.

B. A react-server export condition. Add "react-server": "./dist/server.js" to exports["."], where server.js re-exports @ic-reactor/core and nothing that imports a React hook. Next.js, and any bundler that honours the condition, resolves that entry in the server graph, so import { Reactor } from "@ic-reactor/react" works in a server component. Importing defineReactor or a hook there fails at build time with a missing-export error rather than a hook error. Types are unchanged (TypeScript does not read react-server). Needs pnpm verify:packages (publint/attw) and an App Router build check in CI.

C. "use client" on the hook modules. Marks the hooks as client references. Server imports of ClientManager would then compile, but a server component calling defineReactor or a hook would get a client-reference proxy and fail at runtime instead of at build time. This also changes how every bundler treats the package, so I would not choose it.

Recommendation

A now, which is already on a branch. Consider B if App Router users are a target audience: it is additive, keeps one import path, and turns a confusing hook error into a clear missing-export one. Not implemented, because it changes the published exports map.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions