Skip to content

build: switch from Yarn 1 to npm - #1196

Merged
juliasilge merged 3 commits into
quarto-dev:mainfrom
nealrichardson:build/npm
Oct 14, 2026
Merged

juliasilge merged 3 commits into
quarto-dev:mainfrom
nealrichardson:build/npm

Conversation

@nealrichardson

@nealrichardson nealrichardson commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Replaces Yarn 1 with npm workspaces. Supersedes #970, which went stale.

Changes

  • Lockfile: yarn.lock → package-lock.json. The lockfile was generated by running npm install with yarn.lock still present, so npm resolved every package to the version Yarn had locked. A script comparing the two lockfiles finds no version differences. The only additions are the platform-specific optional binaries (esbuild, rolldown, turbo, lightningcss, …), which npm records for every platform. That avoids the [BUG] Platform-specific optional dependencies not being included in package-lock.json when reinstalling with node_modules present npm/cli#4828 problem of a lockfile that only works on the platform it was generated on. No overrides are needed (there were no resolutions left), and the workspace deps ("core": "*" etc.) all link to the local workspaces.
  • Root package.json:
    • packageManager is npm@11.19.0, the npm that ships with Node 24.21. Turbo needs this field to detect the package manager, and with Corepack enabled it makes yarn refuse to run in the repo.
    • allowScripts: npm 11.19 warns about dependency install scripts that aren't reviewed, and a later npm will block them by default. Approved: esbuild (puts the native binary in place) and @vscode/vsce-sign (copies its platform binary, needed for vsce). Denied: keytar (only for vsce login credential storage; CI uses tokens), @parcel/watcher and fsevents (both ship prebuilt binaries; the scripts only build from source), and core-js-pure (a funding banner). The entries are name-only rather than version-pinned, so Dependabot bumps don't drop the approvals.
    • Root scripts pass arguments through, e.g. npm run test-vscode -- --label main --grep pattern.
  • Deleted apps/vscode/.yarnrc (and its .vscodeignore line). vsce 4 runs vscode:prepublish with yarn when it finds that file. Its --ignore-engines isn't needed: npm doesn't enforce engines by default.
  • Scripts: yarn run build dev → npm run build -- dev etc. in apps/lsp and apps/vscode.
  • CI: yarn install --frozen-lockfile → npm ci, and yarn <script> → npm run <script>. yarn --silent vsce/ovsx … → npx --no vsce/ovsx …, which still uses the repo's pinned versions and fails rather than downloading if they're missing.
  • Editor tasks (apps/vscode/.vscode/tasks.json, launch.json): the yarn: dev-vscode and yarn: build-test tasks are now npm: ….
  • Docs: README, apps/vscode/CONTRIBUTING.md, claude.md, and the "update snapshots" comments in the tests.

Verification

On Node 24.21 / npm 11.19, from a clean node_modules:

  • npm ci: lockfile unchanged; npm ls --all exits 0.
  • npm run build -- --force: 9/9 tasks.
  • npm run test-packages: 13/13 tasks.
  • npm run lint -- --continue: 17/17 tasks, 0 errors, 17 warnings, the same as on main.
  • npx --no vsce package in apps/vscode: runs npm run vscode:prepublish, and packages 175 files.
  • npm run test-vscode -- --help: the arguments reach vscode-test.
  • test-vscode and test-positron weren't run locally (they open GUI windows); CI runs them.

Snyk

The two Snyk checks error on 3 of 30 tests. #1195 passed them, so it's this switch, most likely Snyk projects that were imported from yarn.lock. Someone with access to the Snyk org needs to re-import the repo, or point those projects at package-lock.json.

Rebasing

package-lock.json was regenerated after rebasing onto #1195 (React 19). Any other change to yarn.lock on main before this merges needs the same treatment: restore main's yarn.lock, delete package-lock.json and node_modules, run npm install, delete yarn.lock, and recheck the version comparison. Open PRs that touch yarn.lock will need to port their changes to package-lock.json after this merges.

Follow-ups

  • Turn on Dependabot (npm ecosystem, plus GitHub Actions).
  • npm audit reports 16 advisories (ajv, braces, diff, katex, serialize-javascript, source-map-js, …). They're the same package versions as on main, just reported by a different tool than Snyk. They should be handled separately.

🤖 Generated with Claude Code

@posit-snyk-bot

posit-snyk-bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Snyk checks are incomplete.

Status Scan Engine Critical High Medium Low Total (0)
⚠️ Open Source Security 0 0 0 0 See details
⚠️ Licenses 0 0 0 0 See details

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@nealrichardson

Copy link
Copy Markdown
Contributor Author

🤖 I built a VSIX from this branch locally (clean npm ci + npx --no vsce package) and compared it to one built with yarn install --frozen-lockfile from the parent commit (a658138). I also installed the npm build in Positron.

  • Both VSIXes have the same 175 files. The only non-bundle differences are the yarn→npm script text in package.json and scripts/run-positron-tests.mjs.
  • out/main.js (−10 KB) and out/lsp/lsp.js (−2 KB) shrink slightly. npm dropped some older duplicate packages that Yarn kept as separate copies (debug@4.3.4/4.4.1, tslib@2.4.1, braces@3.0.2, fill-range@7.0.1, ms@2.1.2, …) and uses the newer copy already in the tree. So the installed tree isn't quite identical to Yarn's, even though every version in package-lock.json matches yarn.lock.
  • One new package: assets/www/editor/index.js grows by 1.4 KB. @fluentui/react-context-selector lists scheduler: >=0.19.0 as a peer dependency. Yarn 1 doesn't install peer deps, so Fluent used the scheduler@0.23.2 that came with react-dom. npm installs peers itself, and because that copy sits under react-dom/node_modules where Fluent can't see it, npm added a separate scheduler@0.28.0 under @fluentui/react-context-selector/node_modules, which now gets bundled into the visual editor.

The extra scheduler is very likely harmless: Fluent only calls unstable_runWithPriority on it, and under React 18 a separate scheduler copy doesn't affect React's own scheduling. If we'd rather ship the same packages as before, we could pin scheduler to ^0.23.2, either with a root overrides entry or as a direct dependency of editor-ui. #1195 (React 19) will change which scheduler react-dom needs anyway, so it may be easier to recheck this after regenerating the lockfile for that.

@nealrichardson

Copy link
Copy Markdown
Contributor Author

🤖 About the red security/snyk and license/snyk checks: they come from Snyk's GitHub integration, not from a workflow in this repo. Each project Snyk monitors is tied to a target file, here yarn.lock plus a package.json. The PR check retests those same projects against this branch, so the ones built on yarn.lock error out once it's deleted. Both statuses say "3 tests have failed" out of 30, and their state is error rather than failure, which suggests Snyk couldn't test those projects, not that it found new vulnerabilities. (I haven't opened the Snyk report itself; it needs a login.)

A .snyk file can't fix this. It only holds policy (ignores, patches, path excludes) and can't change which lockfile a project reads. The fix is in the Snyk UI, after this merges:

  1. Merge despite the red Snyk checks. They aren't required, and the other checks pass.
  2. Re-import the repo in Snyk (Projects → Add projects → GitHub → quarto-dev/quarto). Snyk scans the default branch, so this only picks up package-lock.json once it's on main.
  3. Delete the old yarn.lock-based projects, or they'll keep erroring on later PRs.

The new projects start with no history, so the first scans may show existing issues as new (see the 16 npm audit advisories noted above). If we'd rather not merge with red checks, the alternative is to temporarily turn off "test new PRs" in Snyk's integration settings and turn it back on after the re-import.

nealrichardson and others added 3 commits October 14, 2026 07:50
Generate package-lock.json from yarn.lock (npm seeds its resolution from
it), so every package keeps the version Yarn had resolved. Delete yarn.lock
and apps/vscode/.yarnrc (vsce 4 runs prepublish with yarn when it finds it),
set packageManager to npm, and record which dependency install scripts may
run (allowScripts).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@nealrichardson
nealrichardson marked this pull request as ready for review October 14, 2026 11:59
@vezwork

vezwork commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

I checked out this branch and did a brief manual tests in Vscode and Positron: I did npm i and npm run dev-vscode, ran an extension host window to test; then, I went thru a bunch of the features I'm familiar with (including the visual editor). I didn't run into any unexpected problems.

@vezwork vezwork left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! This final step of migrating from yarn to npm should unblock our package management issues!!

@vezwork

vezwork commented Oct 14, 2026

Copy link
Copy Markdown
Member

Thanks very much @nealrichardson

@vezwork
vezwork requested a review from juliasilge October 14, 2026 17:09
@vezwork

vezwork commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

@juliasilge take a glance please, this migrates the monorepo from yarn to npm! Chill right?

@vezwork vezwork mentioned this pull request Oct 14, 2026

@juliasilge juliasilge left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I pulled this down and was able to clean out all the old build-y stuff, and then make a new dev build! Super exciting! 🎉

@juliasilge
juliasilge merged commit f2a2734 into quarto-dev:main Oct 14, 2026
6 of 8 checks passed
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.

4 participants