1# REPL 2 3<!--introduced_in=v0.10.0--> 4 5> Stability: 2 - Stable 6 7<!-- source_link=lib/repl.js --> 8 9The `repl` module provides a Read-Eval-Print-Loop (REPL) implementation that 10is available both as a standalone program or includible in other applications. 11It can be accessed using: 12 13```js 14const repl = require('repl'); 15``` 16 17## Design and features 18 19The `repl` module exports the [`repl.REPLServer`][] class. While running, 20instances of [`repl.REPLServer`][] will accept individual lines of user input, 21evaluate those according to a user-defined evaluation function, then output the 22result. Input and output may be from `stdin` and `stdout`, respectively, or may 23be connected to any Node.js [stream][]. 24 25Instances of [`repl.REPLServer`][] support automatic completion of inputs, 26completion preview, simplistic Emacs-style line editing, multi-line inputs, 27[ZSH][]-like reverse-i-search, [ZSH][]-like substring-based history search, 28ANSI-styled output, saving and restoring current REPL session state, error 29recovery, and customizable evaluation functions. Terminals that do not support 30ANSI styles and Emacs-style line editing automatically fall back to a limited 31feature set. 32 33### Commands and special keys 34 35The following special commands are supported by all REPL instances: 36 37* `.break`: When in the process of inputting a multi-line expression, entering 38 the `.break` command (or pressing the `<ctrl>-C` key combination) will abort 39 further input or processing of that expression. 40* `.clear`: Resets the REPL `context` to an empty object and clears any 41 multi-line expression being input. 42* `.exit`: Close the I/O stream, causing the REPL to exit. 43* `.help`: Show this list of special commands. 44* `.save`: Save the current REPL session to a file: 45 `> .save ./file/to/save.js` 46* `.load`: Load a file into the current REPL session. 47 `> .load ./file/to/load.js` 48* `.editor`: Enter editor mode (`<ctrl>-D` to finish, `<ctrl>-C` to cancel). 49 50```console 51> .editor 52// Entering editor mode (^D to finish, ^C to cancel) 53function welcome(name) { 54 return `Hello ${name}!`; 55} 56 57welcome('Node.js User'); 58 59// ^D 60'Hello Node.js User!' 61> 62``` 63 64The following key combinations in the REPL have these special effects: 65 66* `<ctrl>-C`: When pressed once, has the same effect as the `.break` command. 67 When pressed twice on a blank line, has the same effect as the `.exit` 68 command. 69* `<ctrl>-D`: Has the same effect as the `.exit` command. 70* `<tab>`: When pressed on a blank line, displays global and local (scope) 71 variables. When pressed while entering other input, displays relevant 72 autocompletion options. 73 74For key bindings related to the reverse-i-search, see [`reverse-i-search`][]. 75For all other key bindings, see [TTY keybindings][]. 76 77### Default evaluation 78 79By default, all instances of [`repl.REPLServer`][] use an evaluation function 80that evaluates JavaScript expressions and provides access to Node.js built-in 81modules. This default behavior can be overridden by passing in an alternative 82evaluation function when the [`repl.REPLServer`][] instance is created. 83 84#### JavaScript expressions 85 86The default evaluator supports direct evaluation of JavaScript expressions: 87 88```console 89> 1 + 1 902 91> const m = 2 92undefined 93> m + 1 943 95``` 96 97Unless otherwise scoped within blocks or functions, variables declared 98either implicitly or using the `const`, `let`, or `var` keywords 99are declared at the global scope. 100 101#### Global and local scope 102 103The default evaluator provides access to any variables that exist in the global 104scope. It is possible to expose a variable to the REPL explicitly by assigning 105it to the `context` object associated with each `REPLServer`: 106 107```js 108const repl = require('repl'); 109const msg = 'message'; 110 111repl.start('> ').context.m = msg; 112``` 113 114Properties in the `context` object appear as local within the REPL: 115 116```console 117$ node repl_test.js 118> m 119'message' 120``` 121 122Context properties are not read-only by default. To specify read-only globals, 123context properties must be defined using `Object.defineProperty()`: 124 125```js 126const repl = require('repl'); 127const msg = 'message'; 128 129const r = repl.start('> '); 130Object.defineProperty(r.context, 'm', { 131 configurable: false, 132 enumerable: true, 133 value: msg 134}); 135``` 136 137#### Accessing core Node.js modules 138 139The default evaluator will automatically load Node.js core modules into the 140REPL environment when used. For instance, unless otherwise declared as a 141global or scoped variable, the input `fs` will be evaluated on-demand as 142`global.fs = require('fs')`. 143 144```console 145> fs.createReadStream('./some/file'); 146``` 147 148#### Global uncaught exceptions 149<!-- YAML 150changes: 151 - version: v12.3.0 152 pr-url: https://github.com/nodejs/node/pull/27151 153 description: The `'uncaughtException'` event is from now on triggered if the 154 repl is used as standalone program. 155--> 156 157The REPL uses the [`domain`][] module to catch all uncaught exceptions for that 158REPL session. 159 160This use of the [`domain`][] module in the REPL has these side effects: 161 162* Uncaught exceptions only emit the [`'uncaughtException'`][] event in the 163 standalone REPL. Adding a listener for this event in a REPL within 164 another Node.js program throws [`ERR_INVALID_REPL_INPUT`][]. 165* Trying to use [`process.setUncaughtExceptionCaptureCallback()`][] throws 166 an [`ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE`][] error. 167 168As standalone program: 169 170```js 171process.on('uncaughtException', () => console.log('Uncaught')); 172 173throw new Error('foobar'); 174// Uncaught 175``` 176 177When used in another application: 178 179```js 180process.on('uncaughtException', () => console.log('Uncaught')); 181// TypeError [ERR_INVALID_REPL_INPUT]: Listeners for `uncaughtException` 182// cannot be used in the REPL 183 184throw new Error('foobar'); 185// Thrown: 186// Error: foobar 187``` 188 189#### Assignment of the `_` (underscore) variable 190<!-- YAML 191changes: 192 - version: v9.8.0 193 pr-url: https://github.com/nodejs/node/pull/18919 194 description: Added `_error` support. 195--> 196 197The default evaluator will, by default, assign the result of the most recently 198evaluated expression to the special variable `_` (underscore). 199Explicitly setting `_` to a value will disable this behavior. 200 201```console 202> [ 'a', 'b', 'c' ] 203[ 'a', 'b', 'c' ] 204> _.length 2053 206> _ += 1 207Expression assignment to _ now disabled. 2084 209> 1 + 1 2102 211> _ 2124 213``` 214 215Similarly, `_error` will refer to the last seen error, if there was any. 216Explicitly setting `_error` to a value will disable this behavior. 217 218```console 219> throw new Error('foo'); 220Error: foo 221> _error.message 222'foo' 223``` 224 225#### `await` keyword 226 227With the [`--experimental-repl-await`][] command line option specified, 228experimental support for the `await` keyword is enabled. 229 230```console 231> await Promise.resolve(123) 232123 233> await Promise.reject(new Error('REPL await')) 234Error: REPL await 235 at repl:1:45 236> const timeout = util.promisify(setTimeout); 237undefined 238> const old = Date.now(); await timeout(1000); console.log(Date.now() - old); 2391002 240undefined 241``` 242 243### Reverse-i-search 244<!-- YAML 245added: v12.17.0 246--> 247 248The REPL supports bi-directional reverse-i-search similar to [ZSH][]. It is 249triggered with `<ctrl> + R` to search backward and `<ctrl> + S` to search 250forward. 251 252Duplicated history entires will be skipped. 253 254Entries are accepted as soon as any button is pressed that doesn't correspond 255with the reverse search. Cancelling is possible by pressing `escape` or 256`<ctrl> + C`. 257 258Changing the direction immediately searches for the next entry in the expected 259direction from the current position on. 260 261### Custom evaluation functions 262 263When a new [`repl.REPLServer`][] is created, a custom evaluation function may be 264provided. This can be used, for instance, to implement fully customized REPL 265applications. 266 267The following illustrates a hypothetical example of a REPL that performs 268translation of text from one language to another: 269 270```js 271const repl = require('repl'); 272const { Translator } = require('translator'); 273 274const myTranslator = new Translator('en', 'fr'); 275 276function myEval(cmd, context, filename, callback) { 277 callback(null, myTranslator.translate(cmd)); 278} 279 280repl.start({ prompt: '> ', eval: myEval }); 281``` 282 283#### Recoverable errors 284 285As a user is typing input into the REPL prompt, pressing the `<enter>` key will 286send the current line of input to the `eval` function. In order to support 287multi-line input, the eval function can return an instance of `repl.Recoverable` 288to the provided callback function: 289 290```js 291function myEval(cmd, context, filename, callback) { 292 let result; 293 try { 294 result = vm.runInThisContext(cmd); 295 } catch (e) { 296 if (isRecoverableError(e)) { 297 return callback(new repl.Recoverable(e)); 298 } 299 } 300 callback(null, result); 301} 302 303function isRecoverableError(error) { 304 if (error.name === 'SyntaxError') { 305 return /^(Unexpected end of input|Unexpected token)/.test(error.message); 306 } 307 return false; 308} 309``` 310 311### Customizing REPL output 312 313By default, [`repl.REPLServer`][] instances format output using the 314[`util.inspect()`][] method before writing the output to the provided `Writable` 315stream (`process.stdout` by default). The `showProxy` inspection option is set 316to true by default and the `colors` option is set to true depending on the 317REPL's `useColors` option. 318 319The `useColors` boolean option can be specified at construction to instruct the 320default writer to use ANSI style codes to colorize the output from the 321`util.inspect()` method. 322 323If the REPL is run as standalone program, it is also possible to change the 324REPL's [inspection defaults][`util.inspect()`] from inside the REPL by using the 325`inspect.replDefaults` property which mirrors the `defaultOptions` from 326[`util.inspect()`][]. 327 328```console 329> util.inspect.replDefaults.compact = false; 330false 331> [1] 332[ 333 1 334] 335> 336``` 337 338To fully customize the output of a [`repl.REPLServer`][] instance pass in a new 339function for the `writer` option on construction. The following example, for 340instance, simply converts any input text to upper case: 341 342```js 343const repl = require('repl'); 344 345const r = repl.start({ prompt: '> ', eval: myEval, writer: myWriter }); 346 347function myEval(cmd, context, filename, callback) { 348 callback(null, cmd); 349} 350 351function myWriter(output) { 352 return output.toUpperCase(); 353} 354``` 355 356## Class: `REPLServer` 357<!-- YAML 358added: v0.1.91 359--> 360 361* `options` {Object|string} See [`repl.start()`][] 362* Extends: {readline.Interface} 363 364Instances of `repl.REPLServer` are created using the [`repl.start()`][] method 365or directly using the JavaScript `new` keyword. 366 367```js 368const repl = require('repl'); 369 370const options = { useColors: true }; 371 372const firstInstance = repl.start(options); 373const secondInstance = new repl.REPLServer(options); 374``` 375 376### Event: `'exit'` 377<!-- YAML 378added: v0.7.7 379--> 380 381The `'exit'` event is emitted when the REPL is exited either by receiving the 382`.exit` command as input, the user pressing `<ctrl>-C` twice to signal `SIGINT`, 383or by pressing `<ctrl>-D` to signal `'end'` on the input stream. The listener 384callback is invoked without any arguments. 385 386```js 387replServer.on('exit', () => { 388 console.log('Received "exit" event from repl!'); 389 process.exit(); 390}); 391``` 392 393### Event: `'reset'` 394<!-- YAML 395added: v0.11.0 396--> 397 398The `'reset'` event is emitted when the REPL's context is reset. This occurs 399whenever the `.clear` command is received as input *unless* the REPL is using 400the default evaluator and the `repl.REPLServer` instance was created with the 401`useGlobal` option set to `true`. The listener callback will be called with a 402reference to the `context` object as the only argument. 403 404This can be used primarily to re-initialize REPL context to some pre-defined 405state: 406 407```js 408const repl = require('repl'); 409 410function initializeContext(context) { 411 context.m = 'test'; 412} 413 414const r = repl.start({ prompt: '> ' }); 415initializeContext(r.context); 416 417r.on('reset', initializeContext); 418``` 419 420When this code is executed, the global `'m'` variable can be modified but then 421reset to its initial value using the `.clear` command: 422 423```console 424$ ./node example.js 425> m 426'test' 427> m = 1 4281 429> m 4301 431> .clear 432Clearing context... 433> m 434'test' 435> 436``` 437 438### `replServer.defineCommand(keyword, cmd)` 439<!-- YAML 440added: v0.3.0 441--> 442 443* `keyword` {string} The command keyword (*without* a leading `.` character). 444* `cmd` {Object|Function} The function to invoke when the command is processed. 445 446The `replServer.defineCommand()` method is used to add new `.`-prefixed commands 447to the REPL instance. Such commands are invoked by typing a `.` followed by the 448`keyword`. The `cmd` is either a `Function` or an `Object` with the following 449properties: 450 451* `help` {string} Help text to be displayed when `.help` is entered (Optional). 452* `action` {Function} The function to execute, optionally accepting a single 453 string argument. 454 455The following example shows two new commands added to the REPL instance: 456 457```js 458const repl = require('repl'); 459 460const replServer = repl.start({ prompt: '> ' }); 461replServer.defineCommand('sayhello', { 462 help: 'Say hello', 463 action(name) { 464 this.clearBufferedCommand(); 465 console.log(`Hello, ${name}!`); 466 this.displayPrompt(); 467 } 468}); 469replServer.defineCommand('saybye', function saybye() { 470 console.log('Goodbye!'); 471 this.close(); 472}); 473``` 474 475The new commands can then be used from within the REPL instance: 476 477```console 478> .sayhello Node.js User 479Hello, Node.js User! 480> .saybye 481Goodbye! 482``` 483 484### `replServer.displayPrompt([preserveCursor])` 485<!-- YAML 486added: v0.1.91 487--> 488 489* `preserveCursor` {boolean} 490 491The `replServer.displayPrompt()` method readies the REPL instance for input 492from the user, printing the configured `prompt` to a new line in the `output` 493and resuming the `input` to accept new input. 494 495When multi-line input is being entered, an ellipsis is printed rather than the 496'prompt'. 497 498When `preserveCursor` is `true`, the cursor placement will not be reset to `0`. 499 500The `replServer.displayPrompt` method is primarily intended to be called from 501within the action function for commands registered using the 502`replServer.defineCommand()` method. 503 504### `replServer.clearBufferedCommand()` 505<!-- YAML 506added: v9.0.0 507--> 508 509The `replServer.clearBufferedCommand()` method clears any command that has been 510buffered but not yet executed. This method is primarily intended to be 511called from within the action function for commands registered using the 512`replServer.defineCommand()` method. 513 514### `replServer.parseREPLKeyword(keyword[, rest])` 515<!-- YAML 516added: v0.8.9 517deprecated: v9.0.0 518--> 519 520> Stability: 0 - Deprecated. 521 522* `keyword` {string} the potential keyword to parse and execute 523* `rest` {any} any parameters to the keyword command 524* Returns: {boolean} 525 526An internal method used to parse and execute `REPLServer` keywords. 527Returns `true` if `keyword` is a valid keyword, otherwise `false`. 528 529### `replServer.setupHistory(historyPath, callback)` 530<!-- YAML 531added: v11.10.0 532--> 533 534* `historyPath` {string} the path to the history file 535* `callback` {Function} called when history writes are ready or upon error 536 * `err` {Error} 537 * `repl` {repl.REPLServer} 538 539Initializes a history log file for the REPL instance. When executing the 540Node.js binary and using the command line REPL, a history file is initialized 541by default. However, this is not the case when creating a REPL 542programmatically. Use this method to initialize a history log file when working 543with REPL instances programmatically. 544 545## `repl.start([options])` 546<!-- YAML 547added: v0.1.91 548changes: 549 - version: v12.17.0 550 pr-url: https://github.com/nodejs/node/pull/30811 551 description: The `preview` option is now available. 552 - version: v12.0.0 553 pr-url: https://github.com/nodejs/node/pull/26518 554 description: The `terminal` option now follows the default description in 555 all cases and `useColors` checks `hasColors()` if available. 556 - version: v10.0.0 557 pr-url: https://github.com/nodejs/node/pull/19187 558 description: The `REPL_MAGIC_MODE` `replMode` was removed. 559 - version: v6.3.0 560 pr-url: https://github.com/nodejs/node/pull/6635 561 description: The `breakEvalOnSigint` option is supported now. 562 - version: v5.8.0 563 pr-url: https://github.com/nodejs/node/pull/5388 564 description: The `options` parameter is optional now. 565--> 566 567* `options` {Object|string} 568 * `prompt` {string} The input prompt to display. **Default:** `'> '` 569 (with a trailing space). 570 * `input` {stream.Readable} The `Readable` stream from which REPL input will 571 be read. **Default:** `process.stdin`. 572 * `output` {stream.Writable} The `Writable` stream to which REPL output will 573 be written. **Default:** `process.stdout`. 574 * `terminal` {boolean} If `true`, specifies that the `output` should be 575 treated as a TTY terminal. 576 **Default:** checking the value of the `isTTY` property on the `output` 577 stream upon instantiation. 578 * `eval` {Function} The function to be used when evaluating each given line 579 of input. **Default:** an async wrapper for the JavaScript `eval()` 580 function. An `eval` function can error with `repl.Recoverable` to indicate 581 the input was incomplete and prompt for additional lines. 582 * `useColors` {boolean} If `true`, specifies that the default `writer` 583 function should include ANSI color styling to REPL output. If a custom 584 `writer` function is provided then this has no effect. **Default:** checking 585 color support on the `output` stream if the REPL instance's `terminal` value 586 is `true`. 587 * `useGlobal` {boolean} If `true`, specifies that the default evaluation 588 function will use the JavaScript `global` as the context as opposed to 589 creating a new separate context for the REPL instance. The node CLI REPL 590 sets this value to `true`. **Default:** `false`. 591 * `ignoreUndefined` {boolean} If `true`, specifies that the default writer 592 will not output the return value of a command if it evaluates to 593 `undefined`. **Default:** `false`. 594 * `writer` {Function} The function to invoke to format the output of each 595 command before writing to `output`. **Default:** [`util.inspect()`][]. 596 * `completer` {Function} An optional function used for custom Tab auto 597 completion. See [`readline.InterfaceCompleter`][] for an example. 598 * `replMode` {symbol} A flag that specifies whether the default evaluator 599 executes all JavaScript commands in strict mode or default (sloppy) mode. 600 Acceptable values are: 601 * `repl.REPL_MODE_SLOPPY` to evaluate expressions in sloppy mode. 602 * `repl.REPL_MODE_STRICT` to evaluate expressions in strict mode. This is 603 equivalent to prefacing every repl statement with `'use strict'`. 604 * `breakEvalOnSigint` {boolean} Stop evaluating the current piece of code when 605 `SIGINT` is received, such as when `Ctrl+C` is pressed. This cannot be used 606 together with a custom `eval` function. **Default:** `false`. 607 * `preview` {boolean} Defines if the repl prints autocomplete and output 608 previews or not. **Default:** `true` with the default eval function and 609 `false` in case a custom eval function is used. If `terminal` is falsy, then 610 there are no previews and the value of `preview` has no effect. 611* Returns: {repl.REPLServer} 612 613The `repl.start()` method creates and starts a [`repl.REPLServer`][] instance. 614 615If `options` is a string, then it specifies the input prompt: 616 617```js 618const repl = require('repl'); 619 620// a Unix style prompt 621repl.start('$ '); 622``` 623 624## The Node.js REPL 625 626Node.js itself uses the `repl` module to provide its own interactive interface 627for executing JavaScript. This can be used by executing the Node.js binary 628without passing any arguments (or by passing the `-i` argument): 629 630```console 631$ node 632> const a = [1, 2, 3]; 633undefined 634> a 635[ 1, 2, 3 ] 636> a.forEach((v) => { 637... console.log(v); 638... }); 6391 6402 6413 642``` 643 644### Environment variable options 645 646Various behaviors of the Node.js REPL can be customized using the following 647environment variables: 648 649* `NODE_REPL_HISTORY`: When a valid path is given, persistent REPL history 650 will be saved to the specified file rather than `.node_repl_history` in the 651 user's home directory. Setting this value to `''` (an empty string) will 652 disable persistent REPL history. Whitespace will be trimmed from the value. 653 On Windows platforms environment variables with empty values are invalid so 654 set this variable to one or more spaces to disable persistent REPL history. 655* `NODE_REPL_HISTORY_SIZE`: Controls how many lines of history will be 656 persisted if history is available. Must be a positive number. 657 **Default:** `1000`. 658* `NODE_REPL_MODE`: May be either `'sloppy'` or `'strict'`. **Default:** 659 `'sloppy'`, which will allow non-strict mode code to be run. 660 661### Persistent history 662 663By default, the Node.js REPL will persist history between `node` REPL sessions 664by saving inputs to a `.node_repl_history` file located in the user's home 665directory. This can be disabled by setting the environment variable 666`NODE_REPL_HISTORY=''`. 667 668### Using the Node.js REPL with advanced line-editors 669 670For advanced line-editors, start Node.js with the environment variable 671`NODE_NO_READLINE=1`. This will start the main and debugger REPL in canonical 672terminal settings, which will allow use with `rlwrap`. 673 674For example, the following can be added to a `.bashrc` file: 675 676```text 677alias node="env NODE_NO_READLINE=1 rlwrap node" 678``` 679 680### Starting multiple REPL instances against a single running instance 681 682It is possible to create and run multiple REPL instances against a single 683running instance of Node.js that share a single `global` object but have 684separate I/O interfaces. 685 686The following example, for instance, provides separate REPLs on `stdin`, a Unix 687socket, and a TCP socket: 688 689```js 690const net = require('net'); 691const repl = require('repl'); 692let connections = 0; 693 694repl.start({ 695 prompt: 'Node.js via stdin> ', 696 input: process.stdin, 697 output: process.stdout 698}); 699 700net.createServer((socket) => { 701 connections += 1; 702 repl.start({ 703 prompt: 'Node.js via Unix socket> ', 704 input: socket, 705 output: socket 706 }).on('exit', () => { 707 socket.end(); 708 }); 709}).listen('/tmp/node-repl-sock'); 710 711net.createServer((socket) => { 712 connections += 1; 713 repl.start({ 714 prompt: 'Node.js via TCP socket> ', 715 input: socket, 716 output: socket 717 }).on('exit', () => { 718 socket.end(); 719 }); 720}).listen(5001); 721``` 722 723Running this application from the command line will start a REPL on stdin. 724Other REPL clients may connect through the Unix socket or TCP socket. `telnet`, 725for instance, is useful for connecting to TCP sockets, while `socat` can be used 726to connect to both Unix and TCP sockets. 727 728By starting a REPL from a Unix socket-based server instead of stdin, it is 729possible to connect to a long-running Node.js process without restarting it. 730 731For an example of running a "full-featured" (`terminal`) REPL over 732a `net.Server` and `net.Socket` instance, see: 733<https://gist.github.com/TooTallNate/2209310>. 734 735For an example of running a REPL instance over [`curl(1)`][], see: 736<https://gist.github.com/TooTallNate/2053342>. 737 738[TTY keybindings]: readline.html#readline_tty_keybindings 739[ZSH]: https://en.wikipedia.org/wiki/Z_shell 740[`'uncaughtException'`]: process.html#process_event_uncaughtexception 741[`--experimental-repl-await`]: cli.html#cli_experimental_repl_await 742[`ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE`]: errors.html#errors_err_domain_cannot_set_uncaught_exception_capture 743[`ERR_INVALID_REPL_INPUT`]: errors.html#errors_err_invalid_repl_input 744[`curl(1)`]: https://curl.haxx.se/docs/manpage.html 745[`domain`]: domain.html 746[`process.setUncaughtExceptionCaptureCallback()`]: process.html#process_process_setuncaughtexceptioncapturecallback_fn 747[`readline.InterfaceCompleter`]: readline.html#readline_use_of_the_completer_function 748[`repl.ReplServer`]: #repl_class_replserver 749[`repl.start()`]: #repl_repl_start_options 750[`reverse-i-search`]: #repl_reverse_i_search 751[`util.inspect()`]: util.html#util_util_inspect_object_options 752[stream]: stream.html 753