Skip to content

feat: enable Twoslash on Cloudflare#8837

Open
dario-piotrowicz wants to merge 4 commits into
nodejs:mainfrom
dario-piotrowicz:dario/two-slash-on-cloudflare
Open

feat: enable Twoslash on Cloudflare#8837
dario-piotrowicz wants to merge 4 commits into
nodejs:mainfrom
dario-piotrowicz:dario/two-slash-on-cloudflare

Conversation

@dario-piotrowicz
Copy link
Copy Markdown
Member

@dario-piotrowicz dario-piotrowicz commented Apr 22, 2026

Description

Note

Disclaimer, This PR has been authored mostly by Claude Opus 4.6 with minor tweaks from me.
It does seem to work and the code makes sense to me.

Enables twoslash to work on Cloudflare (previously it would only work on the Vercel deployment):
Screenshot 2026-04-22 at 22 42 31

Validation

See: https://nodejs-website.dario-test.workers.dev/en

Related Issues

Check List

  • I have read the Contributing Guidelines and made commit messages that follow the guideline.
  • I have run pnpm format to ensure the code follows the style guide.
  • I have run pnpm test to check if all tests are passing.
  • I have run pnpm build to check if the website builds without errors.
  • I've covered new added functionality with unit tests if necessary.

Copilot AI review requested due to automatic review settings April 22, 2026 21:59
@dario-piotrowicz dario-piotrowicz requested review from a team as code owners April 22, 2026 21:59
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nodejs-org Ready Ready Preview May 25, 2026 11:10pm

Request Review

@cursor
Copy link
Copy Markdown

cursor Bot commented Apr 22, 2026

PR Summary

Medium Risk
Changes the MDX/Shiki build and Cloudflare worker path with a new generated artifact and larger runtime imports, but does not touch auth, payments, or user data.

Overview
Twoslash on Cloudflare Workers is turned on for MDX by no longer disabling it when 'Cloudflare' in global; on that runtime, Shiki gets a custom in-memory twoslasher built from a pre-generated VFS instead of the default Node filesystem twoslasher.

A new build:twoslash-fsmap step (wired into prebuild, Turbo build, and cloudflare:build:worker) writes apps/site/generated/twoslash-fsmap.json from TypeScript lib declarations plus @types/node via @typescript/vfs. createVfsTwoslasher loads that JSON and uses twoslash/core with bundler module resolution and types: ['node']. Generated output is gitignored.

@node-core/rehype-shiki now routes twoslashOptions.twoslasher through createTransformerFactory so Workers never pull in the default Node-dependent twoslasher; non-Cloudflare paths still use transformerTwoslash unchanged.

Reviewed by Cursor Bugbot for commit 23c7898. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions
Copy link
Copy Markdown
Contributor

👋 Codeowner Review Request

The following codeowners have been identified for the changed files:

Team reviewers: @nodejs/nodejs-website @nodejs/web-infra

Please review the changes when you have a chance. Thank you! 🙏

@dario-piotrowicz
Copy link
Copy Markdown
Member Author

@avivkeller 🙂

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.23%. Comparing base (b97f706) to head (23c7898).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8837   +/-   ##
=======================================
  Coverage   73.23%   73.23%           
=======================================
  Files         102      102           
  Lines        8628     8628           
  Branches      313      313           
=======================================
  Hits         6319     6319           
  Misses       2308     2308           
  Partials        1        1           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Enables Twoslash-powered code annotations in the Cloudflare Workers deployment by providing a virtual filesystem (VFS) twoslasher and wiring in a build-time generated TypeScript/@types map, while updating the rehype-shiki Twoslash transformer to accept a custom twoslasher.

Changes:

  • Add a VFS-backed Twoslash setup for Cloudflare that loads a pre-generated twoslash-fsmap.json.
  • Introduce a build script (and Turbo task dependency) to generate the VFS map before Cloudflare worker builds.
  • Update @node-core/rehype-shiki’s Twoslash transformer to support options.twoslasher via createTransformerFactory.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/rehype-shiki/src/transformers/twoslash/index.mjs Adds support for passing a custom twoslasher (Cloudflare-compatible path).
apps/site/mdx/plugins.mjs Enables Twoslash on Cloudflare by creating a VFS-based twoslasher and passing it through twoslashOptions.
apps/site/scripts/twoslash-fsmap/index.mjs New script to write the generated VFS map JSON to apps/site/generated/.
apps/site/scripts/twoslash-fsmap/generate.mjs New generator that builds a map of TS lib + @types/node declaration files.
apps/site/turbo.json Adds build:twoslash-fsmap task and makes Cloudflare worker build depend on it.
apps/site/package.json Adds build:twoslash-fsmap script entry.
.gitignore Ignores apps/site/generated/ build artifacts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/site/scripts/twoslash-fsmap/index.mjs Outdated
Comment thread apps/site/turbo.json Outdated
Comment thread apps/site/mdx/plugins.mjs Outdated
Comment thread packages/rehype-shiki/src/transformers/twoslash/index.mjs Outdated
Comment thread packages/rehype-shiki/src/transformers/twoslash/index.mjs
Comment thread apps/site/scripts/twoslash-fsmap/generate.mjs Outdated
@dario-piotrowicz dario-piotrowicz marked this pull request as draft April 22, 2026 22:06
Comment thread apps/site/scripts/twoslash-fsmap/index.mjs
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 841a898. Configure here.

Comment thread packages/rehype-shiki/src/transformers/twoslash/index.mjs
Copy link
Copy Markdown
Member

@ovflowd ovflowd left a comment

Choose a reason for hiding this comment

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

Not fan of this diff/approach. Let's keep Twoslash disabled for now in Cloudflare and discuss our options.

Comment thread apps/site/mdx/plugins.mjs Outdated
Comment thread apps/site/mdx/plugins.mjs Outdated
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.

I don't think we really need any of this? I'm fairly sue twoslash supports using vfs out of the box? Since they have this CDN thing https://twoslash.netlify.app/packages/cdn (for example)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

mh... that is interesting, however I am a bit worried on moving this to the runtime since it would add network calls for fetching from the CDN increasing cold starts 😕

Are we sure that we'd be happy with such tradeoff?

Copy link
Copy Markdown
Member

@ovflowd ovflowd left a comment

Choose a reason for hiding this comment

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

Feel free to eventually remove my block as I'm getting away of the project for a while... but I'd appreciate if you could look into my comments and find ways of improving the fs map...

I'm really not a fan of YET another prebuild step of generating files. We already have the blog-data one which also is only needed because of Cloudflare Workers. Having one more is starting to make me regret that Cloudflare Workers cannot index these things in a practical way. Like it'd be great if this could just be uploaded to the build as for example Next.js's out of the box "outputFileTracingIncludes" supports that.

@avivkeller
Copy link
Copy Markdown
Member

@dario-piotrowicz once you resolve the review, ping me, and I'll re-review + remove the block + merge

@dario-piotrowicz
Copy link
Copy Markdown
Member Author

I'm really not a fan of YET another prebuild step of generating files. We already have the blog-data one which also is only needed because of Cloudflare Workers. Having one more is starting to make me regret that Cloudflare Workers cannot index these things in a practical way. Like it'd be great if this could just be uploaded to the build as for example Next.js's out of the box "outputFileTracingIncludes" supports that.

Yeah I totally hear you! 😓

Indeed unfortunately this sort of stuff is a bit painful on Workers 😓, and I don't think we can do significantly better than this 😓

One thing worth considering, maybe as a followup is whether we could use the Workers fs system that has been introduced after we started this project. However that would still introduce (like the twoslash cdn thing) non-trivial runtime latencies which IMO might make the whole thing not worth it at all 😓

@dario-piotrowicz
Copy link
Copy Markdown
Member Author

@dario-piotrowicz once you resolve the review, ping me, and I'll re-review + remove the block + merge

Sorry that I didn't notice your comment for a while 😓, I addressed/replied to all of @ovflowd's comments and this PR should be ready for a re-review whenever you have time 🙂🙏

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