Skip to content

docs: make the REPL page match what bun repl prints - #46308

Open
robobun wants to merge 1 commit into
mainfrom
robobun/a80e2d55/repl-docs-match-output
Open

robobun wants to merge 1 commit into
mainfrom
robobun/a80e2d55/repl-docs-match-output

Conversation

@robobun

@robobun robobun commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

  • Seven output lines on docs/runtime/repl.mdx are never what bun repl prints. Four show undefined after a declaration or an import. The others show single-quoted strings and a one-line { a: 1, b: 2 }.
  • The examples omit the stack frames of an error and show > where a terminal shows ❯. The banner (v1.3.3) is older than the native REPL (v1.3.10).
  • Other statements do not hold on main. Examples: __dirname is "", Ctrl+T swaps around the cursor, and a signal loses the history.

Fix

  • Each example is now the exact screen of a pty session on a build of main (1.4.4-canary.1+0c864a07c).
  • Three examples printed a long or changing result: a star count, a Response, the zod exports. Lines with a short, fixed result replace them.
  • Twelve statements are corrected or scoped. Notes lists each with the run that decides it.
  • Verified: a script types every example into a pty and compares the screen. All 9 match.

Background

Notes

How the page was checked

  • Binary: the canary build of main, 1.4.4-canary.1+0c864a07c. src/runtime/cli/repl.rs, repl_command.rs and src/js_parser/repl_transforms.rs are the same at the head of this branch. A build of 367d939d9 (1.4.3) prints the same text, except the version in the banner.
  • Interactive examples: typed key by key into bun repl in a pty (TERM=xterm-256color, NO_COLOR not set), one fresh session and one empty HOME for each block. The rendered screen must equal the block, line for line.
  • -e and -p examples: run through sh, with stdout compared to the # lines.
  • Statements: each sentence and each table row was run in the plain case and in the corner cases listed below.
  • The page compiles as MDX and passes prettier --check.

Example lines that changed, and what the binary prints

Page on main bun repl
Welcome to Bun v1.3.3 Welcome to Bun v1.4.4
> const greeting = "Hello, Bun!" gives undefined "Hello, Bun!"
> greeting gives 'Hello, Bun!' "Hello, Bun!"
JSON.parse("oops") gives one line the message, two at lines, and an empty line
the star count 81234 96328 on the day of the check
const response = await fetch(...) gives undefined the whole Response, 31 lines with dates and request ids
import { z } from "zod" gives undefined the module namespace, 1096 lines with zod 4.6.7
const path = require("path") gives undefined the path module, 37 lines
'/tmp/file.txt' "/tmp/file.txt"
.save ./my-session.txt gives no output Session saved to ./my-session.txt
-p "{ a: 1, b: 2 }" gives { a: 1, b: 2 } four lines, one property on each line

Statements that changed, and the run behind each one

Statement on main On the binary
__dirname and __filename are "resolved relative to your current working directory", as require and module are __dirname prints "" and __filename prints "[repl]". After process.chdir(), require("./x.js") still loads the file of the directory that the REPL started in.
The two special variables "update after each evaluation" _ does not change after a result of undefined. _error does not change after an input that does not throw.
_ is "the result of the last expression" 5, then undefined, then _ prints 5.
_error is "the last error that was thrown" A throw in a setTimeout callback and a rejection that nothing awaits print an error and leave _error.
Unclosed brackets, braces, or parentheses continue on the next line Also an unclosed ', " or backtick.
.editor "buffers all input" until Ctrl+D A line that you typed and did not end with Enter is not evaluated. It stays on the next prompt.
.history prints "the command history" With 1000 entries it prints entries 981 to 1000.
.copy copies to the clipboard It writes ESC ] 52 ; c ; <base64> BEL. The terminal does the rest.
Ctrl+D exits "if line is empty" On an empty ... line it does nothing. In editor mode it evaluates.
Ctrl+T swaps "the two characters before the cursor" he█llo becomes hle█lo. At the end of the line it swaps the last two.
The REPL "automatically saves history" Saved after .exit, Ctrl+D, and Ctrl+C twice. Not saved after SIGTERM, SIGHUP, SIGINT, SIGKILL, or process.exit(0). The limit holds: a file of 1500 lines plus one new entry leaves 1000 lines.
"On error, the process exits with code 1" Exit 1 for a throw, a syntax error, and a rejected top-level await. Exit 0 for Promise.reject(new Error("x")) that nothing awaits, and for an async function that rejects and that nothing awaits.

Sentences that are new

  • "The REPL prints the result of each input. A variable declaration prints the value of its last initializer." let a = 1, b = 2 prints 2. const { p } = { p: 1 } prints the object.
  • "With NO_COLOR=1, or when standard input or standard output is not a terminal, the prompt is >." Each of the three conditions was run on its own.
  • The OSC 52 sentence below the commands table.

Corner cases that the page does not describe

They are defects or limits of the REPL. None makes a sentence of the new page false in the plain case.

Other open PRs that edit this page

Hosts

The fetch examples use https://bun.com, as 7 other examples in docs/ do. https://example.com does not resolve in the environment where the examples were run, so a line with that host could not be run as written.


no test proof · iteration 0 · docs-only change; test-proof not applicable

Each example on docs/runtime/repl.mdx is now the screen of a pty session
on a build of main (0c864a0). The examples show the `❯` prompt, the
value that a declaration prints, strings in double quotes, the stack
frames of an error, and the four lines that `-p "{ a: 1, b: 2 }"` prints.
Three examples printed a long or changing result: the star count of the
repository, a Response object, and the exports of zod. Lines with a
short, fixed result replace them.

These statements did not hold on main and are corrected or scoped:

- `__dirname` and `__filename` are "" and "[repl]". They do not resolve
  from the working directory. `require` resolves from the directory that
  the REPL starts in.
- `_` keeps its value after a result of `undefined`. `_error` changes
  when an input throws.
- An unclosed quote also continues the input. `.editor` buffers the lines
  that end with Enter.
- `.history` prints the last 20 entries. `.copy` writes an OSC 52 escape
  sequence.
- Ctrl+T swaps the character before the cursor with the character at the
  cursor. Ctrl+D does not exit at a `...` prompt.
- The REPL saves the history on `.exit`, Ctrl+D and Ctrl+C. A signal or
  `process.exit()` loses the history of the session.
- `bun repl -e` exits with code 1 when the script throws or when a
  promise that it awaits at the top level rejects.
@coderabbitai

coderabbitai Bot commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: oven-sh/bun/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 909375bd-b375-4a04-8c79-b7c639663575
📥 Commits

Reviewing files that changed from the base of the PR and between 59c1ac4 and 5ad8958.

📒 Files selected for processing: 1
  • docs/runtime/repl.mdx
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@robobun

robobun commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 1:15 AM PT - Oct 21st, 2026

✅ @robobun, your commit 5ad8958d2eeff13f93a10d6ba3cbd085280ad086 passed in Build #129990! 🎉


🧪   To try this PR locally:

bunx bun-pr 46308

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

bun-46308 --bun

@robobun

robobun commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator Author

Status

Reproduced on main (1.4.4-canary.1+0c864a07c) and on 1.4.3:

printf 'const greeting = "Hello, Bun!"\ngreeting\n.exit\n' | NO_COLOR=1 bun repl
# the page on main: undefined, then 'Hello, Bun!'
# bun repl:         "Hello, Bun!", then "Hello, Bun!"

bun repl -p "{ a: 1, b: 2 }"
# the page on main: { a: 1, b: 2 }
# bun repl:         four lines, one property on each line

printf '__dirname\n__filename\n.exit\n' | NO_COLOR=1 bun repl
# the page on main: both resolve from the working directory
# bun repl:         "" and "[repl]"

With this PR, each of the 9 examples on the page equals the screen of a pty session on that build, line for line.

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

Code review found no issues

No high-confidence issues detected in this change.

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.

1 participant