You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #233 attempted to bring @wordpress/* packages up to latest within eslint@8 compatibility. The goal was simple: keep @wordpress/components and @wordpress/icons at latest, plus the obvious safe minor bumps.
The PR turned into a multi-day investigation of cascading transitive-dependency issues:
@wordpress/block-editor 15.6 → 15.18 brought @wordpress/commands → cmdk → @radix-ui/* requiring React 19, which conflicted with @wordpress/element's strict React 18 dependency, causing React duplication that broke 78 tests in newspack-plugin (hooks returned null because components and react-dom loaded different React copies).
@wordpress/dataviews (transitively pulled) ended up nested in some scenarios instead of hoisted, breaking consumer SCSS imports of @wordpress/dataviews/build-style/style.css.
@wordpress/ui@0.12.0 (transitively pulled by @wordpress/block-library@9.45.0) requires engines.node: ">=20.10.0", but the codebase declares >=18.12.0 — silent runtime mismatch.
Pinning packages tightly didn't propagate: ranges like ^15.6.0 allowed npm to resolve 15.18.x. Even narrowing to ~15.6.0 for direct deps was bypassed by transitive resolution chains (block-library → core-data → block-editor@^15.18).
npm overrides: only apply at the root install level — they do NOT propagate to packages that depend on us. So we cannot shape consumer trees from within newspack-scripts.
PR #233 was closed because the surgical revert that "worked" was only a partial fix dependent on consumers' existing lockfile state.
The structural observation
newspack-scripts declares ~25 @wordpress/* packages as direct dependencies, but only ~5 of them are imported by newspack-scripts's own code (@wordpress/scripts, @wordpress/eslint-plugin, @wordpress/browserslist-config, @wordpress/prettier-config, @wordpress/stylelint-config).
The rest (@wordpress/components, icons, element, data, block-editor, etc.) are listed "for testing environment" per the comment in config/eslintrc.js — referencing webpack's DependencyExtractionPlugin behavior where consumer builds extract these at runtime but tests need them locally.
The result: newspack-scripts is an ambient distributor of the WordPress editor ecosystem. Every transitive shift in WP-core land becomes a newspack-scripts release event, and every consumer downstream pays the blast radius. We hit this in PR #233 with React/cmdk/Radix/ui and it's a recurring pattern.
Goal
We want all @wordpress/* packages at latest, sustainably — meaning future major-version updates from WP-core don't trigger week-long PR investigations. PR #233 demonstrates the current architecture can't deliver that.
Audit topics for discussion
Each is a discussion prompt, not a settled answer. Looking for input from the team.
Inventory: declared vs imported. For each @wordpress/* we declare, is it (a) imported by our code, (b) needed for consumer build/test environment via DependencyExtractionPlugin, or (c) neither? The "neither" bucket is pure surface area we maintain for free. Open question: when did we last verify the (b) bucket against current webpack/jest behavior?
dependencies vs peerDependencies. Should runtime libraries like @wordpress/element, @wordpress/data, @wordpress/components be peerDependencies? Shifts version-choice responsibility to consumers and reduces blast radius from our releases.
Where does the testing-environment constraint actually come from? The eslintrc.js comment is from years ago. Verify the constraint is still real, then determine the minimum set of packages required to satisfy it, vs the maximum we currently ship.
What's the consumer-visible API of newspack-scripts? CLI subcommands (build, test, lint:js, lint:scss, format:js, commit, etc.) plus exported configs (getWebpackConfig, eslintrc, babel.config, postcss.config, prettier.config, stylelint.config, tsconfig). That's a small surface compared to what's listed in deps.
WP version coupling. Should newspack-scripts target a specific Gutenberg/WP-core release window and document it? Right now we track latest with no policy about which WP combination is "supported together."
Lockfile strategy. Should we ship a lockfile and recommend npm ci to consumers? Today's setup (broad caret ranges, no shipped lockfile) means consumer trees are unpredictable.
Compare to @wordpress/scripts. That package is a build-tool wrapper and doesn't bundle the editor. Why does newspack-scripts? Did the difference accumulate by accident, or was there a deliberate decision?
Migration paths. Likely outcomes:
Slim down: delete most @wordpress/* declarations; keep newspack-scripts as a thin tooling wrapper.
Formalize: split into two packages — newspack-scripts (CLI + configs) and newspack-deps-bundle (WP package set with explicit version coupling).
peerDeps shift: keep declarations but as peers; document expected consumer setup.
Why now
Two unresolved Copilot threads on PR #233 (thread on block-editor pin, thread on engines.node) are concrete examples of issues we cannot fix incrementally — they're consequences of the structural shape of newspack-scripts as a package, not bugs in any specific declaration.
Rather than continuing to whack moles on PR #233, closing it and starting from this issue.
Asks
Reactions / 🚀 if the broad direction (audit → architectural change) sounds right
Context
PR #233 attempted to bring
@wordpress/*packages up to latest withineslint@8compatibility. The goal was simple: keep@wordpress/componentsand@wordpress/iconsat latest, plus the obvious safe minor bumps.The PR turned into a multi-day investigation of cascading transitive-dependency issues:
@wordpress/block-editor15.6 → 15.18 brought@wordpress/commands→cmdk→@radix-ui/*requiring React 19, which conflicted with@wordpress/element's strict React 18 dependency, causing React duplication that broke 78 tests in newspack-plugin (hooks returnednullbecause components and react-dom loaded different React copies).@wordpress/dataviews(transitively pulled) ended up nested in some scenarios instead of hoisted, breaking consumer SCSS imports of@wordpress/dataviews/build-style/style.css.@wordpress/ui@0.12.0(transitively pulled by@wordpress/block-library@9.45.0) requiresengines.node: ">=20.10.0", but the codebase declares>=18.12.0— silent runtime mismatch.^15.6.0allowed npm to resolve 15.18.x. Even narrowing to~15.6.0for direct deps was bypassed by transitive resolution chains (block-library→core-data→block-editor@^15.18).overrides:only apply at the root install level — they do NOT propagate to packages that depend on us. So we cannot shape consumer trees from within newspack-scripts.PR #233 was closed because the surgical revert that "worked" was only a partial fix dependent on consumers' existing lockfile state.
The structural observation
newspack-scriptsdeclares ~25@wordpress/*packages as directdependencies, but only ~5 of them are imported bynewspack-scripts's own code (@wordpress/scripts,@wordpress/eslint-plugin,@wordpress/browserslist-config,@wordpress/prettier-config,@wordpress/stylelint-config).The rest (
@wordpress/components,icons,element,data,block-editor, etc.) are listed "for testing environment" per the comment inconfig/eslintrc.js— referencing webpack'sDependencyExtractionPluginbehavior where consumer builds extract these at runtime but tests need them locally.The result:
newspack-scriptsis an ambient distributor of the WordPress editor ecosystem. Every transitive shift in WP-core land becomes anewspack-scriptsrelease event, and every consumer downstream pays the blast radius. We hit this in PR #233 with React/cmdk/Radix/ui and it's a recurring pattern.Goal
We want all
@wordpress/*packages at latest, sustainably — meaning future major-version updates from WP-core don't trigger week-long PR investigations. PR #233 demonstrates the current architecture can't deliver that.Audit topics for discussion
Each is a discussion prompt, not a settled answer. Looking for input from the team.
Inventory: declared vs imported. For each
@wordpress/*we declare, is it (a) imported by our code, (b) needed for consumer build/test environment viaDependencyExtractionPlugin, or (c) neither? The "neither" bucket is pure surface area we maintain for free. Open question: when did we last verify the (b) bucket against current webpack/jest behavior?dependenciesvspeerDependencies. Should runtime libraries like@wordpress/element,@wordpress/data,@wordpress/componentsbepeerDependencies? Shifts version-choice responsibility to consumers and reduces blast radius from our releases.Where does the testing-environment constraint actually come from? The
eslintrc.jscomment is from years ago. Verify the constraint is still real, then determine the minimum set of packages required to satisfy it, vs the maximum we currently ship.What's the consumer-visible API of
newspack-scripts? CLI subcommands (build,test,lint:js,lint:scss,format:js,commit, etc.) plus exported configs (getWebpackConfig,eslintrc,babel.config,postcss.config,prettier.config,stylelint.config,tsconfig). That's a small surface compared to what's listed in deps.WP version coupling. Should
newspack-scriptstarget a specific Gutenberg/WP-core release window and document it? Right now we track latest with no policy about which WP combination is "supported together."Lockfile strategy. Should we ship a lockfile and recommend
npm cito consumers? Today's setup (broad caret ranges, no shipped lockfile) means consumer trees are unpredictable.Compare to
@wordpress/scripts. That package is a build-tool wrapper and doesn't bundle the editor. Why doesnewspack-scripts? Did the difference accumulate by accident, or was there a deliberate decision?Migration paths. Likely outcomes:
@wordpress/*declarations; keepnewspack-scriptsas a thin tooling wrapper.newspack-scripts(CLI + configs) andnewspack-deps-bundle(WP package set with explicit version coupling).Why now
Two unresolved Copilot threads on PR #233 (thread on
block-editorpin, thread onengines.node) are concrete examples of issues we cannot fix incrementally — they're consequences of the structural shape ofnewspack-scriptsas a package, not bugs in any specific declaration.Rather than continuing to whack moles on PR #233, closing it and starting from this issue.
Asks
prettierdependency #1 (inventory) and @wordpress/* packages handling #3 (testing-env constraint) which are factual questions someone may already have answerednewspack-scriptsthat this PR didn't surface but you've been waiting to raise