• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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