Skip to content

bun init: add react + @types/react to the blank scaffold so .tsx works - #36607

Open
robobun wants to merge 4 commits into
mainfrom
farm/501ae8c8/init-blank-react-deps
Open

robobun wants to merge 4 commits into
mainfrom
farm/501ae8c8/init-blank-react-deps

Conversation

@robobun

@robobun robobun commented Aug 1, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

Fixes #5056.

The blank bun init -y scaffold writes a tsconfig.json with "jsx": "react-jsx", which makes both bun run file.tsx and tsc --noEmit try to resolve react/jsx-runtime. Because the scaffold did not install react or @types/react, dropping a .tsx file into a fresh project failed out of the box:

$ bun init -y && cat > react.tsx <<'TSX'
function Component(props: { message: string }): any {
  return <h1 style={{ color: "red" }}>{props.message}</h1>;
}
console.log(<Component message="Hello world!" />);
TSX

$ bun run react.tsx
error: Cannot find module 'react/jsx-dev-runtime' from '.../react.tsx'

$ bunx tsc --noEmit
react.tsx(2,10): error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.
react.tsx(2,10): error TS2875: This JSX tag requires the module path 'react/jsx-runtime' to exist, but none could be found.

This treats react the same way the scaffold already treats typescript: add react to peerDependencies and @types/react to devDependencies when neither is present, skip under --minimal, and leave any existing react setup alone.

After:

$ bun init -y
...
+ @types/bun@1.3.14
+ @types/react@19.2.18
+ react@19.2.8
+ typescript@6.0.3
8 packages installed

$ bun run react.tsx
<Component message="Hello world!" />

$ bunx tsc --noEmit
$ echo $?
0

How did you verify your code works?

New tests in test/cli/init/init.test.ts:

  • bun init -y: a .tsx file runs and typechecks out of the box runs bun init -y, writes a .tsx file, then asserts bun run succeeds and tsc --noEmit exits 0
  • bun init leaves an existing react dependency alone asserts a pre-existing dependencies.react is not moved or duplicated
  • --minimal test now asserts peerDependencies is absent and devDependencies is exactly { "@types/bun": "latest" }

Existing snapshot tests updated for the new package.json shape. All 17 tests in the file pass under bun bd test; the new .tsx test fails under USE_SYSTEM_BUN=1 at the first toHaveProperty("react") assertion.


no test proof · iteration 0 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/cli/init/init.test.ts

The blank template's tsconfig.json sets "jsx": "react-jsx", which makes
both `bun run file.tsx` and `tsc --noEmit` try to resolve
react/jsx-runtime. Without react and @types/react installed, creating a
.tsx file in a fresh `bun init -y` project fails with "Cannot find
module 'react/jsx-runtime'" at runtime and TS7026/TS2875 under tsc.

Treat react like the existing typescript peer dependency: add react to
peerDependencies and @types/react to devDependencies when neither is
present, skip under --minimal, and leave existing react setups alone.

Fixes #5056
@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@robobun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 16 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

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 reviews.

How do review limits work?

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

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, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4a5f04e1-3320-4826-8e2a-1ef4641e3257

📥 Commits

Reviewing files that changed from the base of the PR and between cf6d350 and 02f8e48.

📒 Files selected for processing (2)
  • src/runtime/cli/init_command.rs
  • test/cli/init/init.test.ts

Walkthrough

Changes

React dependencies for bun init

Layer / File(s) Summary
Detect and add React dependencies
src/runtime/cli/init_command.rs
Non-minimal scaffolds detect missing react and @types/react packages. The initializer adds React 19 peer and type dependencies when needed.
Validate generated manifests and scaffolds
test/cli/init/init.test.ts, docs/quickstart.mdx
Tests cover generated, reinitialized, blank, existing-dependency, and minimal scaffolds. The quickstart manifest includes the generated React dependencies.

Suggested reviewers: jarred-sumner

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states that the blank scaffold adds React and its type definitions so TSX works.
Description check ✅ Passed The description includes both required sections and provides clear implementation details and verification results.
Linked Issues check ✅ Passed The changes address issue #5056 by enabling TSX execution and type-checking while preserving existing dependencies and minimal scaffolds.
Out of Scope Changes check ✅ Passed The documentation, implementation, and tests directly support the scaffold React dependency objective.

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

@github-actions github-actions Bot added the claude label Aug 1, 2026
Comment thread src/runtime/cli/init_command.rs Outdated

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

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 `@test/cli/init/init.test.ts`:
- Around line 303-315: Update the initializer subprocess test around Bun.spawn
to concurrently drain stdout and stderr while awaiting proc.exited, then assert
the combined subprocess result after the package manifest expectations. Ensure
the test fails when bun init exits unsuccessfully, while preserving the existing
dependency assertions.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8926a5ee-0629-4250-ae9d-9e14122ffb6b

📥 Commits

Reviewing files that changed from the base of the PR and between df49a6e and cf6d350.

📒 Files selected for processing (3)
  • docs/quickstart.mdx
  • src/runtime/cli/init_command.rs
  • test/cli/init/init.test.ts

Comment thread test/cli/init/init.test.ts
@robobun

robobun commented Aug 1, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 11:20 PM PT - Jul 31st, 2026

✅ @robobun, your commit 02f8e48368385ccfdb46d5ccea5044ecd8784a71 passed in Build #86601! 🎉


🧪   To try this PR locally:

bunx bun-pr 36607

That installs a local version of the PR into your bun-36607 executable, so you can run:

bun-36607 --bun

Comment thread src/runtime/cli/init_command.rs Outdated
Comment thread src/runtime/cli/init_command.rs
Comment thread test/cli/init/init.test.ts Outdated
… react-free

The Library template is publishable (private=false); declaring react as a
peerDependency there would be a wrong consumer-facing contract.

@claude claude Bot 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.

Both earlier findings are addressed — needs_react_dependency is now gated on Template::Blank so the Library template stays react-free, and the existing-react test drains its pipes and asserts exit. The code looks correct to me. Deferring to a maintainer only because making react + @types/react part of the default bun init -y scaffold is a user-facing default change worth a human sign-off.

What was reviewed:

  • needs_react_dependency gating: --minimal, TypescriptLibrary, React templates (early-return), and existing-react-in-any-dep-bucket all skip; only Template::Blank adds it.
  • peerDependencies block still writes typescript independently when needs_react_dependency is false.
  • New tests drain stdout/stderr concurrently; --minimal test now pins devDependencies to exactly @types/bun.
Extended reasoning...

Overview

The PR adds react (peer) and @types/react (dev) to the bun init -y blank scaffold so a .tsx file resolves react/jsx-runtime out of the box, matching the tsconfig's existing "jsx": "react-jsx". Touches src/runtime/cli/init_command.rs (~40 lines), test/cli/init/init.test.ts (two new tests + snapshot updates + tightened --minimal assertions), and docs/quickstart.mdx.

Prior feedback

I previously flagged (1) the react gate leaking into Template::TypescriptLibrary (a publishable, non-private scaffold) and (2) an undrained-pipe subprocess test. Commit 02f8e48 gates on template == Template::Blank, and 768876c drains and asserts exit in the existing-react test. Both are resolved in the current diff.

Security risks

None. Scaffold-time dependency-list edits; no untrusted-input parsing, no auth/crypto/permissions.

Level of scrutiny

Code-wise this is low risk — it mirrors the existing needs_typescript_dependency pattern line-for-line, and the Template::Blank gate plus the three-bucket presence check keep it from clobbering existing setups or leaking into other templates. Tests cover blank, existing-react, and --minimal.

Why defer rather than approve

This changes what every bun init -y produces: react and @types/react are now installed by default in the blank template. That is a product/UX default (linked to #5056) rather than a pure bugfix, and per the approval guidelines a human should weigh in on user-facing default changes of this kind. No code concerns remain from my side.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tsx fails on fresh repo (JSX element implicitly has type 'any')

2 participants