Skip to content

chore: formalize & guard ESM-only (no CJS, ESM-native) — closes #20 - #30

Merged
oekazuma merged 4 commits into
mainfrom
chore/esm-only-guard
Jun 22, 2026
Merged

oekazuma merged 4 commits into
mainfrom
chore/esm-only-guard

Conversation

@oekazuma

@oekazuma oekazuma commented Jun 22, 2026 •

Copy link
Copy Markdown
Owner

Summary

Locks in the project's ESM-only stance and guards it in CI so CJS can't creep back. Closes #20.

Changes

  • Guard type resolution in CI — add @arethetypeswrong/cli (attw) to the publish check. New check:types runs attw with --profile esm-only over all four packages; check:publish now runs publint + attw. The esm-only profile intentionally ignores the node10 / require-from-CJS cases (expected for ESM-only packages) and confirms node16 (ESM) + bundler resolve cleanly.
  • Consistent entry points — drop the legacy top-level main/types from @svelte-vitals/core and @svelte-vitals/vite; every package is now exports-only (matching the CLI and MCP packages).
  • Tree-shaking consistency — add sideEffects: false to svelte-vitals, @svelte-vitals/vite, and @svelte-vitals/mcp (core already had it).
  • Declare the requirement — each package README now states ESM-only (Node 18+); require() unsupported by design.
  • Policy guard — a one-line ESM-only by design (#20) — never add 'cjs'. comment in every tsup.config.ts.
  • .mjs consistency — rename scripts/verify-svelte-import.mjs → .js (a plain .js is already ESM under the repo's type: module).

Non-goals

No CJS or dual (ESM+CJS) build — the whole point is to stay ESM-only.

Validation

  • pnpm -r test — 198 passed (core 70, vite 31, cli 88, mcp 9)
  • pnpm -r typecheck, pnpm build, pnpm lint, pnpm check:publint — green
  • attw --pack . --profile esm-only — clean for all four packages (node16 ESM + bundler 🟢)

Note: locally pnpm check:publish can't run attw's npm pack step due to a pre-existing root-owned ~/.npm cache on this machine; verified instead via the direct attw invocation. CI uses a clean cache, so the gate runs normally there.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Chores

    • Updated all packages to require Node.js 18+ as the minimum runtime.
    • Enforced ESM-only module distribution; CommonJS is no longer supported.
    • Enhanced CI pipeline with improved type-checking validation.
  • Documentation

    • Updated README files to document ESM-only requirement and Node 18+ minimum.

- add @arethetypeswrong/cli (esm-only profile) to check:publish alongside publint
- drop legacy top-level main/types from core & vite (exports-only, uniform)
- add sideEffects:false across all packages
- document ESM-only (Node 18+, require unsupported) in each README
- one-line ESM-only policy comment in every tsup.config.ts
- rename scripts/verify-svelte-import.mjs -> .js (.js is ESM under type:module)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 22, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@oekazuma, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 51 minutes and 50 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0dac5060-1515-4405-a9d0-d34af2b5e91c

📥 Commits

Reviewing files that changed from the base of the PR and between f39fe15 and 3a27f79.

📒 Files selected for processing (1)
  • packages/cli/README.md
📝 Walkthrough

Walkthrough

This PR formalizes the ESM-only stance across all packages by removing legacy top-level main/types fields from @svelte-vitals/core and @svelte-vitals/vite, adding engines.node>=18 and sideEffects:false to every package manifest, annotating all tsup.config.ts files with an ESM-only comment, updating every README with an ESM-only disclaimer, and wiring @arethetypeswrong/cli into the CI publish check alongside existing publint.

Changes

ESM-only Guard

Layer / File(s) Summary
Package manifests: exports-only + engines + sideEffects
packages/core/package.json, packages/vite/package.json, packages/cli/package.json, packages/mcp/package.json
Removes top-level main/types from core and vite so exports is the sole entrypoint source; adds engines.node>=18 and sideEffects:false to all four package manifests.
CI publish check: attw alongside publint
pnpm-workspace.yaml, package.json
Adds @arethetypeswrong/cli@^0.18.0 to the catalog and devDependencies; splits check:publish into check:publint and check:types subtasks run sequentially.
tsup ESM-only intent comments
packages/cli/tsup.config.ts, packages/core/tsup.config.ts, packages/vite/tsup.config.ts
Inserts a one-line comment in each tsup config stating the build is ESM-only by design and must never include cjs format.
README notices and script comment updates
packages/cli/README.md, packages/core/README.md, packages/vite/README.md, packages/mcp/README.md, scripts/verify-svelte-import.js, .changeset/esm-only-guard.md
Adds "ESM-only (Node 18+)" disclaimers to cli/core/vite READMEs; reformats existing mcp note to bold wording; updates verify-svelte-import.js header comments from .mjs to .js; adds the changeset file.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • oekazuma/svelte-vitals#26: Also modifies packages/vite/package.json to shape the ESM exports map for @svelte-vitals/vite, adding a ./hooks subpath export alongside the same exports-only structure being enforced here.

Poem

🐇 Hoppity-hop through the module maze,
No require() here — just ESM always!
We dropped the old main, kept the exports map tight,
Node 18 or bust, the engines are right.
attw now guards what publint began —
pure ESM forever, that's the plan! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: formalizing and guarding the project's ESM-only architectural stance by closing issue #20.
Linked Issues check ✅ Passed All core objectives from issue #20 are met: ESM-only guard added to CI via attw integration, exports-only applied uniformly, Node 18+ requirement documented, policy comments added to tsup configs, .mjs renamed to .js, and sideEffects standardized.
Out of Scope Changes check ✅ Passed All changes directly support the ESM-only formalization objective; no out-of-scope modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/esm-only-guard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR formalizes the repo’s ESM-only posture by tightening package entrypoints and adding a CI guard that checks ESM/type resolution, while also documenting the ESM-only requirement across packages.

Changes:

  • Add @arethetypeswrong/cli (attw) and wire it into check:publish via a new check:types script to guard ESM-only type resolution in CI.
  • Standardize packages on exports-only by removing legacy top-level main/types from @svelte-vitals/core and @svelte-vitals/vite, and add sideEffects: false consistently.
  • Update READMEs and tsup configs to explicitly state “ESM-only (Node 18+)” and record the “never add cjs” policy.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
scripts/verify-svelte-import.js Updates runtime command docs and clarifies .js is ESM under the repo’s type: module.
pnpm-workspace.yaml Adds @arethetypeswrong/cli to the workspace catalog.
pnpm-lock.yaml Locks @arethetypeswrong/cli and its transitive deps.
packages/vite/tsup.config.ts Adds an explicit “ESM-only; never add cjs” policy comment.
packages/vite/README.md Documents ESM-only / Node 18+ / require() unsupported.
packages/vite/package.json Adds sideEffects: false and removes legacy main/types (exports-only).
packages/mcp/README.md Updates ESM-only wording to the new standardized phrasing.
packages/mcp/package.json Adds sideEffects: false.
packages/core/tsup.config.ts Adds an explicit “ESM-only; never add cjs” policy comment.
packages/core/README.md Documents ESM-only / Node 18+ / require() unsupported.
packages/core/package.json Removes legacy main/types (exports-only).
packages/cli/tsup.config.ts Adds an explicit “ESM-only; never add cjs” policy comment.
packages/cli/README.md Documents ESM-only / Node 18+ / require() unsupported.
packages/cli/package.json Adds sideEffects: false.
package.json Splits check:publish into publint + new attw-based check:types and adds attw devDependency.
.changeset/esm-only-guard.md Adds a changeset describing the ESM-only formalization and CI guard.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

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

Comment thread .changeset/esm-only-guard.md
oekazuma and others added 2 commits June 22, 2026 16:00
Dropping top-level main/types can affect consumers resolving entry points
without exports support, so a patch (which implies compatibility) is too weak
for those two packages; cli/mcp only gain additive sideEffects and stay patch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make the documented "Node 18+" runtime floor machine-enforceable so npm
install warnings, attw, and publint align with the README claim. Additive
declaration — core/vite stay minor (entry-point change), cli/mcp stay patch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cli/README.md`:
- Around line 13-14: The README.md file has a Markdown formatting violation
where line 14 is a blank line within a blockquote block that lacks the required
blockquote marker. To fix this, add the `> ` prefix to the blank line (line 14)
that sits between the blockquote starting at line 13 and the content continuing
at line 15 to properly maintain blockquote formatting according to Markdown
specifications.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 59cc95ff-3fe9-4a9b-9aaa-1f096f1692e6

📥 Commits

Reviewing files that changed from the base of the PR and between 0e367b1 and f39fe15.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • .changeset/esm-only-guard.md
  • package.json
  • packages/cli/README.md
  • packages/cli/package.json
  • packages/cli/tsup.config.ts
  • packages/core/README.md
  • packages/core/package.json
  • packages/core/tsup.config.ts
  • packages/mcp/README.md
  • packages/mcp/package.json
  • packages/vite/README.md
  • packages/vite/package.json
  • packages/vite/tsup.config.ts
  • pnpm-workspace.yaml
  • scripts/verify-svelte-import.js

Comment thread packages/cli/README.md Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

Two adjacent blockquotes (ESM-only note + [\!NOTE] alert) separated by a
blank line tripped markdownlint MD028. Merging them with `>` would have
broken the GitHub alert (its first line must be `[\!NOTE]`), so move the
ESM-only line into the top tagline blockquote instead — alert stays intact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@oekazuma
oekazuma merged commit cf2d2d8 into main Jun 22, 2026
4 checks passed
@oekazuma
oekazuma deleted the chore/esm-only-guard branch June 22, 2026 07:17
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.

chore: formalize & guard ESM-only (no CJS, ESM-native)

2 participants