Skip to content

feat: split into scoped @marqdown/* packages - #897

Open
quantizor wants to merge 6 commits into
mainfrom
rename-to-marqdown
Open

feat: split into scoped @marqdown/* packages#897
quantizor wants to merge 6 commits into
mainfrom
rename-to-marqdown

Conversation

@quantizor

@quantizor quantizor commented Aug 13, 2026

Copy link
Copy Markdown
Owner

What changes

markdown-to-jsx is now published as a family of focused packages under the @marqdown scope, one per integration:

  • @marqdown/react, @marqdown/vue, @marqdown/solid, @marqdown/native: render markdown to that framework
  • @marqdown/html, @marqdown/markdown: render to an HTML or markdown string, no framework required
  • @marqdown/parser: the CommonMark + GFM parser and AST only

Each renderer includes the parser and pulls in only the framework it targets, so an install carries just the integration you use and a renderer can never fall out of step with the parser it was built against. Packages are versioned independently.

Compatibility

The markdown-to-jsx package stays as a compatibility alias that re-exports these packages, deep imports (markdown-to-jsx/react, markdown-to-jsx/html, and so on) included. Existing installs keep working unchanged, so migrating is optional. New code should install the specific @marqdown/<integration> package.

@cursor

cursor Bot commented Aug 13, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@changeset-bot

changeset-bot Bot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3c4ba96

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
@marqdown/parser Minor
@marqdown/react Minor
@marqdown/native Minor
@marqdown/solid Minor
@marqdown/vue Minor
@marqdown/html Minor
@marqdown/markdown Minor
markdown-to-jsx Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

A full re-read of all 51 changed files at this head. The rename is mechanical and consistent: every internal reference, self-import, workspace scope, entry point, error message, and JSDoc note now names marqdown, and the intentional old-name leftovers (GitHub URLs, the markdown-to-jsx.quantizor.dev domain, the benchmark baseline alias, the changelog history) line up exactly with what AGENTS.md and BACKLOG.md declare should stay. The bundled "quieter dev loop" changes (scripts/verify, .githooks/pre-commit, lib/src/__mocks__/console-leak.ts) are sound and internally consistent, and both bun run typecheck and bun run validate-i18n pass on this checkout.

  • Package renamelib/package.json name, workspace scopes (@marqdown/*), all workspace:* deps, self-referencing marqdown/entities imports wired through lib/tsconfig.json, lib/bunup.config.ts, native/metro.config.js, knip.jsonc, and .changeset/config.json.
  • Error messages and JSDoc — runtime messages (marqdown: the first argument must be a string) and deprecated-import pointers updated.
  • Docs and i18nlib/README.md, the en/hi/zh mirrors, both llms.txt files, scripts/llms-snippets.ts fences, the site (title, marqdown-lang key) and the rebuilt docs/ output.
  • Changeset and backlog — patch changeset in declarative release-note voice; BACKLOG.md tracked the remaining publish/repo/DNS steps.
  • Quieter dev loop — verify and the pre-commit hook capture per-step output and surface it only on failure; the console-leak wrappers no longer forward to the real console (documented, leak detection preserved).

ℹ️ Informational

One pre-existing reference to the old name falls outside the two keep-lists you enumerated in the PR body and AGENTS.md: bunfig.toml:3 still has minimumReleaseAgeExcludes = ["markdown-to-jsx"]. It is functionally inert today (every consumer resolves marqdown as a workspace:* dependency, never from the registry, so the 3-day release-age floor never applies to it), so nothing needs to change now. Worth a glance only if the upcoming shim/release flow ever installs marqdown from the registry within three days of its first publish, in which case you'd want marqdown in that list.

ℹ️ Nitpicks

  • You changed the site's localStorage language key from markdown-to-jsx-lang to marqdown-lang; any visitor with a stored non-English preference will reset to the default once after this ships. Purely cosmetic on a demo site, so fine as-is.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

…ompat alias

Publish one package per integration under the @marqdown org: @marqdown/parser,
react, native, solid, vue, html, markdown. Each renderer inlines the parser so
it is self-contained with zero cross-package @marqdown runtime deps and can never
skew from the parser it was tested against; @marqdown/parser is also standalone.

Every package is a slice of the single lib build. bunup drops the bodies of any
module outside its package root, so per-package bundling is infeasible: instead
lib builds once (in-root, the proven path) and scripts/pack-packages.ts copies
each package's slice from lib/dist, rewriting the externalized marqdown/entities
specifier to <scope>/entities so the entity browser-swap survives. Shared bunup
config moves to bunup.shared.ts.

The unscoped markdown-to-jsx name is kept as a deprecated compatibility alias
that re-exports the @marqdown/* packages (packages/compat, stubs generated by
scripts/gen-compat.ts) so existing imports and deep imports keep resolving.

Rename the private Expo harness to @marqdown/native-harness to free the published
@marqdown/native name. Root build produces every package and gen-compat; verify
covers all package declarations. Also codify bun as the sole package manager
(packageManager pin, gitignore stray lockfiles).
Add a release guard (scripts/check-inlined-parser-changesets.ts, wired into
verify) that fails when a shared parser file changed but not every published
package is covered by a changeset: the parser is inlined in each renderer, so a
parser change must republish all of them or a renderer ships a stale parser.

Add are-the-types-wrong packaging validation (scripts/attw-packages.ts, wired
into verify) across all eight published packages on the node16 and bundler
profiles. node10 is excluded (engines require Node 18+) and the deliberate
esModuleInterop-off default-export shape is ignored.

Mark lib private: the unscoped marqdown name is unpublishable, so lib is only the
internal source and build home. Rewrite the changeset to describe the scoped
split, and update the naming invariant and codebase map in AGENTS.md.
@socket-security

socket-security Bot commented Aug 14, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​arethetypeswrong/​cli@​0.18.59910010087100

View full report

@socket-security

socket-security Bot commented Aug 14, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm highlight.js is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ?npm/@arethetypeswrong/cli@0.18.5npm/highlight.js@10.7.3

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/highlight.js@10.7.3. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Important

The new compat shim breaks the legacy package's documented CommonJS root contract: require('markdown-to-jsx') no longer returns the Markdown component, and the shim's comment promises resolution tests that do not exist.

Reviewed changes

Incremental re-review against the prior pullfrog review (head e4c4e02). Commit 8758b45 changes the whole character of this PR: it is no longer a flat rename but a full monorepo split. The lib build's output is now sliced into seven published @marqdown/* packages plus a deprecated markdown-to-jsx compat alias.

  • Split lib/bunup.config.ts into a shared bunup.shared.ts and per-entry config; added a standalone lib/src/parser.ts entry for @marqdown/parser.
  • Added scripts/pack-packages.ts (copies each package's slice of lib/dist into packages/<dir>/dist, rewriting the marqdown/entities specifier to <scope>/entities and converting every package's package.json build to bun ../../scripts/pack-packages.ts <dir>).
  • Added scripts/gen-compat.ts (generates the markdown-to-jsx compat shim's ESM/CJS/dts re-export stubs) and packages/compat/ with dependency/peer mappings for native/solid/vue.
  • Renamed the native harness workspace @marqdown/native@marqdown/native-harness (@marqdown/native is now the published package).
  • Extended scripts/verify-declarations.ts to check every published package's declared types paths exist; heavy bun.lock regeneration.

The slice/entity plumbing is sound: specifiers, exports maps, and dependency/peer declarations are internally consistent, and @marqdown/parser/entities resolves for the compat ./entities subpath. The two findings below concern the compat shim's drop-in fidelity for its stated purpose ("so existing installs keep working").

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread scripts/gen-compat.ts
Comment thread scripts/gen-compat.ts Outdated
Retarget the README (and the en/hi/zh mirrors), llms.txt, and the rebuilt site
from the abandoned marqdown package name to the scoped @marqdown/* packages:
install the package for your integration, each includes the parser, and the
markdown-to-jsx alias re-exports them. Distribute README and LICENSE into every
package at build time so npm pages are populated.

Fix the markdown-to-jsx compat CommonJS root: require('markdown-to-jsx') must be
the renderable Markdown component with the named exports attached (the legacy
default-only contract), not the @marqdown/react module namespace. Add
scripts/check-package-resolution.ts (wired into verify) which loads the built
stubs and asserts each subpath's runtime shape, including that root contract.
Retarget the llms.txt snippet runner to the scoped packages.
@quantizor quantizor changed the title refactor: rename the package to marqdown feat: split into scoped @marqdown/* packages Aug 14, 2026

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ No new issues found. Both findings from the previous review are addressed, and the new regression test is meaningful coverage.

Reviewed changes

Incremental re-review of commit 3c4ba96 against the prior pullfrog review (head 8758b45), which had raised two IMPORTANT findings. Both are resolved in the code.

  • Fixed the compat CommonJS root contract — scripts/gen-compat.ts now emits var m = require('@marqdown/react'); module.exports = Object.assign(m.default, m) for the root, so require('markdown-to-jsx') returns the renderable Markdown component with the named exports attached (matching the legacy default-only Object.assign root in lib/src/index.cjs.tsx); the other subpaths keep their namespace shape. index.d.ts/index.d.cts are unchanged, which is fine since they describe the same exported surface.
  • Added scripts/check-package-resolution.ts, wired into verify wave 3, which loads the built compat stubs and asserts the CJS root renders as a component (# Hi<h1 id="hi">Hi</h1>), each subpath's runtime shape, the scoped @marqdown/react/@marqdown/html names, and the ESM root default. This directly pins down the CJS-shape contract the prior review asked for, and its exact HTML/typeof assertions would genuinely fail on a regression.
  • Retargeted the docs and snippets from the bare marqdown name to @marqdown/*lib/README.md, the en/hi/zh mirrors, both llms.txt files, the rebuilt docs/ output, and sitemap.xml. scripts/llms-snippets.ts runs its fences from packages/compat now that they import scoped packages (react resolves by walking up to the root).
  • scripts/pack-packages.ts and scripts/gen-compat.ts now copy the shared lib/README.md and lib/LICENSE into each published package root, matching the new packages/*/README.md / packages/*/LICENSE gitignore entries.

The resolution test's assumptions are internally consistent with the build flow (pack-packages/gen-compat run in the build step before verify wave 3 runs the resolution check), and the scoped packages resolve from packages/compat whether hoisted by the workspace or not.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

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