Skip to content

fix: declare each framework as an optional peer dependency (open-ended ranges) - #245

Open
jestes0623 wants to merge 1 commit into
formkit:masterfrom
jestes0623:fix/optional-framework-peer-dependencies
Open

jestes0623 wants to merge 1 commit into
formkit:masterfrom
jestes0623:fix/optional-framework-peer-dependencies

Conversation

@jestes0623

Copy link
Copy Markdown

Declare each framework as an optional peer dependency (open-ended ranges)

Every shipped entry imports exactly one framework at runtime — react/ imports react, vue/ imports vue, preact/ imports preact/hooks, solid/ imports solid-js, angular/ imports @angular/core, nuxt/ imports @nuxt/kit — but package.json declares none of them. This PR declares all six as optional peer dependencies with open-ended ranges whose minimum is the version each entry's API needs. No runtime code changes; pnpm-lock.yaml is unchanged (verified with the pinned pnpm 10.14.0).

Why this matters for strict package managers

With no declaration, pnpm and Yarn PnP cannot link a framework to this package, so import … from "react" inside react/index.mjs resolves through whatever happens to be hoisted. In a monorepo that holds two React versions (one app on 19.2.0, another on 19.2.6) the hoisted copy was the other app's React, which gave the consumer two React instances in one render — Cannot read properties of null (reading 'useState') from useAutoAnimate — and the hoist pick changed between installs, so the same lockfile passed CI once and failed the next time. The documented workaround today is a per-project packageExtensions entry (as @RomainLanz pointed out in #4); declaring the peers here makes that unnecessary for everyone.

Why this doesn't bring back the 2022 install errors

Peers were removed in 029b1a6 after #4 / #32 / #64: react: "^16.8.0" made npm 7 fail with Conflicting peer dependency for anyone on React 17/18, and bumping the caret every major is a treadmill. These ranges are >= with no upper bound, so every stable release of each framework satisfies them and npm has nothing to conflict about — while pnpm / Yarn gain the declaration they need to link the right copy. They are also marked optional, so a Vue project is never asked about React and vice versa, and npm does not auto-install any of them. (Prerelease / canary builds don't satisfy a >= range under strict semver; that is the one case where a consumer could still see npm's peer-resolution notice, as they would with any declared range.)

Minimums

peer range why
react >=16.8.0 hooks (useState, useEffect, …)
vue >=3.0.0 composition API (ref, onMounted, watchEffect)
preact >=10.0.0 preact/hooks
solid-js >=1.0.0 createSignal, onMount, onCleanup
@angular/core >=16.0.0 standalone: true directive (14) + effect() signals (16)
@nuxt/kit >=3.0.0 defineNuxtModule (Nuxt 3 kit)

Happy to drop @nuxt/kit or adjust any minimum if you prefer a narrower first step.

Every shipped entry imports one framework at runtime (react, vue,
preact/hooks, solid-js, @angular/core, @nuxt/kit) but package.json declared
none of them, so strict package managers (pnpm, Yarn PnP) could not link a
framework to this package and the import resolved through whatever happened
to be hoisted. In a workspace holding two React versions that produced two
React instances in one render ("Cannot read properties of null (reading
'useState')" from useAutoAnimate), and the hoist pick changed between
installs.

Peers were removed in 029b1a6 after formkit#4 / formkit#32 / formkit#64 because a caret range
(react ^16.8.0) made npm 7 fail on React 17/18. These ranges are open-ended
(>=) with the minimum each entry's API needs, so every stable release
satisfies them and npm has nothing to conflict about, and they are optional
so no framework is ever auto-installed or asked about in another framework's
project. No runtime change; pnpm-lock.yaml unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 7, 2026

Copy link
Copy Markdown

@jestes0623 is attempting to deploy a commit to the Formkit Team on Vercel.

A member of the Team first needs to authorize it.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant