• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Readline
2
3<!--introduced_in=v0.10.0-->
4
5> Stability: 2 - Stable
6
7<!-- source_link=lib/readline.js -->
8
9The `readline` module provides an interface for reading data from a [Readable][]
10stream (such as [`process.stdin`][]) one line at a time. It can be accessed
11using:
12
13```js
14const readline = require('readline');
15```
16
17The following simple example illustrates the basic use of the `readline` module.
18
19```js
20const readline = require('readline');
21
22const rl = readline.createInterface({
23  input: process.stdin,
24  output: process.stdout
25});
26
27rl.question('What do you think of Node.js? ', (answer) => {
28  // TODO: Log the answer in a database
29  console.log(`Thank you for your valuable feedback: ${answer}`);
30
31  rl.close();
32});
33```
34
35Once this code is invoked, the Node.js application will not terminate until the
36`readline.Interface` is closed because the interface waits for data to be
37received on the `input` stream.
38
39## Class: `Interface`
40<!-- YAML
41added: v0.1.104
42-->
43
44* Extends: {EventEmitter}
45
46Instances of the `readline.Interface` class are constructed using the
47`readline.createInterface()` method. Every instance is associated with a
48single `input` [Readable][] stream and a single `output` [Writable][] stream.
49The `output` stream is used to print prompts for user input that arrives on,
50and is read from, the `input` stream.
51
52### Event: `'close'`
53<!-- YAML
54added: v0.1.98
55-->
56
57The `'close'` event is emitted when one of the following occur:
58
59* The `rl.close()` method is called and the `readline.Interface` instance has
60  relinquished control over the `input` and `output` streams;
61* The `input` stream receives its `'end'` event;
62* The `input` stream receives <kbd>Ctrl</kbd>+<kbd>D</kbd> to signal
63  end-of-transmission (EOT);
64* The `input` stream receives <kbd>Ctrl</kbd>+<kbd>C</kbd> to signal `SIGINT`
65  and there is no `'SIGINT'` event listener registered on the
66  `readline.Interface` instance.
67
68The listener function is called without passing any arguments.
69
70The `readline.Interface` instance is finished once the `'close'` event is
71emitted.
72
73### Event: `'line'`
74<!-- YAML
75added: v0.1.98
76-->
77
78The `'line'` event is emitted whenever the `input` stream receives an
79end-of-line input (`\n`, `\r`, or `\r\n`). This usually occurs when the user
80presses <kbd>Enter</kbd> or <kbd>Return</kbd>.
81
82The listener function is called with a string containing the single line of
83received input.
84
85```js
86rl.on('line', (input) => {
87  console.log(`Received: ${input}`);
88});
89```
90
91### Event: `'history'`
92<!-- YAML
93added: v14.18.0
94-->
95
96The `'history'` event is emitted whenever the history array has changed.
97
98The listener function is called with an array containing the history array.
99It will reflect all changes, added lines and removed lines due to
100`historySize` and `removeHistoryDuplicates`.
101
102The primary purpose is to allow a listener to persist the history.
103It is also possible for the listener to change the history object. This
104could be useful to prevent certain lines to be added to the history, like
105a password.
106
107```js
108rl.on('history', (history) => {
109  console.log(`Received: ${history}`);
110});
111```
112
113### Event: `'pause'`
114<!-- YAML
115added: v0.7.5
116-->
117
118The `'pause'` event is emitted when one of the following occur:
119
120* The `input` stream is paused.
121* The `input` stream is not paused and receives the `'SIGCONT'` event. (See
122  events [`'SIGTSTP'`][] and [`'SIGCONT'`][].)
123
124The listener function is called without passing any arguments.
125
126```js
127rl.on('pause', () => {
128  console.log('Readline paused.');
129});
130```
131
132### Event: `'resume'`
133<!-- YAML
134added: v0.7.5
135-->
136
137The `'resume'` event is emitted whenever the `input` stream is resumed.
138
139The listener function is called without passing any arguments.
140
141```js
142rl.on('resume', () => {
143  console.log('Readline resumed.');
144});
145```
146
147### Event: `'SIGCONT'`
148<!-- YAML
149added: v0.7.5
150-->
151
152The `'SIGCONT'` event is emitted when a Node.js process previously moved into
153the background using <kbd>Ctrl</kbd>+<kbd>Z</kbd> (i.e. `SIGTSTP`) is then
154brought back to the foreground using fg(1p).
155
156If the `input` stream was paused *before* the `SIGTSTP` request, this event will
157not be emitted.
158
159The listener function is invoked without passing any arguments.
160
161```js
162rl.on('SIGCONT', () => {
163  // `prompt` will automatically resume the stream
164  rl.prompt();
165});
166```
167
168The `'SIGCONT'` event is _not_ supported on Windows.
169
170### Event: `'SIGINT'`
171<!-- YAML
172added: v0.3.0
173-->
174
175The `'SIGINT'` event is emitted whenever the `input` stream receives a
176<kbd>Ctrl+C</kbd> input, known typically as `SIGINT`. If there are no `'SIGINT'`
177event listeners registered when the `input` stream receives a `SIGINT`, the
178`'pause'` event will be emitted.
179
180The listener function is invoked without passing any arguments.
181
182```js
183rl.on('SIGINT', () => {
184  rl.question('Are you sure you want to exit? ', (answer) => {
185    if (answer.match(/^y(es)?$/i)) rl.pause();
186  });
187});
188```
189
190### Event: `'SIGTSTP'`
191<!-- YAML
192added: v0.7.5
193-->
194
195The `'SIGTSTP'` event is emitted when the `input` stream receives a
196<kbd>Ctrl</kbd>+<kbd>Z</kbd> input, typically known as `SIGTSTP`. If there are
197no `'SIGTSTP'` event listeners registered when the `input` stream receives a
198`SIGTSTP`, the Node.js process will be sent to the background.
199
200When the program is resumed using fg(1p), the `'pause'` and `'SIGCONT'` events
201will be emitted. These can be used to resume the `input` stream.
202
203The `'pause'` and `'SIGCONT'` events will not be emitted if the `input` was
204paused before the process was sent to the background.
205
206The listener function is invoked without passing any arguments.
207
208```js
209rl.on('SIGTSTP', () => {
210  // This will override SIGTSTP and prevent the program from going to the
211  // background.
212  console.log('Caught SIGTSTP.');
213});
214```
215
216The `'SIGTSTP'` event is _not_ supported on Windows.
217
218### `rl.close()`
219<!-- YAML
220added: v0.1.98
221-->
222
223The `rl.close()` method closes the `readline.Interface` instance and
224relinquishes control over the `input` and `output` streams. When called,
225the `'close'` event will be emitted.
226
227Calling `rl.close()` does not immediately stop other events (including `'line'`)
228from being emitted by the `readline.Interface` instance.
229
230### `rl.pause()`
231<!-- YAML
232added: v0.3.4
233-->
234
235The `rl.pause()` method pauses the `input` stream, allowing it to be resumed
236later if necessary.
237
238Calling `rl.pause()` does not immediately pause other events (including
239`'line'`) from being emitted by the `readline.Interface` instance.
240
241### `rl.prompt([preserveCursor])`
242<!-- YAML
243added: v0.1.98
244-->
245
246* `preserveCursor` {boolean} If `true`, prevents the cursor placement from
247  being reset to `0`.
248
249The `rl.prompt()` method writes the `readline.Interface` instances configured
250`prompt` to a new line in `output` in order to provide a user with a new
251location at which to provide input.
252
253When called, `rl.prompt()` will resume the `input` stream if it has been
254paused.
255
256If the `readline.Interface` was created with `output` set to `null` or
257`undefined` the prompt is not written.
258
259### `rl.question(query[, options], callback)`
260<!-- YAML
261added: v0.3.3
262-->
263
264* `query` {string} A statement or query to write to `output`, prepended to the
265  prompt.
266* `options` {Object}
267  * `signal` {AbortSignal} Optionally allows the `question()` to be canceled
268    using an `AbortController`.
269* `callback` {Function} A callback function that is invoked with the user's
270  input in response to the `query`.
271
272The `rl.question()` method displays the `query` by writing it to the `output`,
273waits for user input to be provided on `input`, then invokes the `callback`
274function passing the provided input as the first argument.
275
276When called, `rl.question()` will resume the `input` stream if it has been
277paused.
278
279If the `readline.Interface` was created with `output` set to `null` or
280`undefined` the `query` is not written.
281
282The `callback` function passed to `rl.question()` does not follow the typical
283pattern of accepting an `Error` object or `null` as the first argument.
284The `callback` is called with the provided answer as the only argument.
285
286Example usage:
287
288```js
289rl.question('What is your favorite food? ', (answer) => {
290  console.log(`Oh, so your favorite food is ${answer}`);
291});
292```
293
294Using an `AbortController` to cancel a question.
295
296```js
297const ac = new AbortController();
298const signal = ac.signal;
299
300rl.question('What is your favorite food? ', { signal }, (answer) => {
301  console.log(`Oh, so your favorite food is ${answer}`);
302});
303
304signal.addEventListener('abort', () => {
305  console.log('The food question timed out');
306}, { once: true });
307
308setTimeout(() => ac.abort(), 10000);
309```
310
311If this method is invoked as it's util.promisify()ed version, it returns a
312Promise that fulfills with the answer. If the question is canceled using
313an `AbortController` it will reject with an `AbortError`.
314
315```js
316const util = require('util');
317const question = util.promisify(rl.question).bind(rl);
318
319async function questionExample() {
320  try {
321    const answer = await question('What is you favorite food? ');
322    console.log(`Oh, so your favorite food is ${answer}`);
323  } catch (err) {
324    console.error('Question rejected', err);
325  }
326}
327questionExample();
328```
329
330### `rl.resume()`
331<!-- YAML
332added: v0.3.4
333-->
334
335The `rl.resume()` method resumes the `input` stream if it has been paused.
336
337### `rl.setPrompt(prompt)`
338<!-- YAML
339added: v0.1.98
340-->
341
342* `prompt` {string}
343
344The `rl.setPrompt()` method sets the prompt that will be written to `output`
345whenever `rl.prompt()` is called.
346
347### `rl.getPrompt()`
348<!-- YAML
349added: v14.17.0
350-->
351
352* Returns: {string} the current prompt string
353
354The `rl.getPrompt()` method returns the current prompt used by `rl.prompt()`.
355
356### `rl.write(data[, key])`
357<!-- YAML
358added: v0.1.98
359-->
360
361* `data` {string}
362* `key` {Object}
363  * `ctrl` {boolean} `true` to indicate the <kbd>Ctrl</kbd> key.
364  * `meta` {boolean} `true` to indicate the <kbd>Meta</kbd> key.
365  * `shift` {boolean} `true` to indicate the <kbd>Shift</kbd> key.
366  * `name` {string} The name of the a key.
367
368The `rl.write()` method will write either `data` or a key sequence identified
369by `key` to the `output`. The `key` argument is supported only if `output` is
370a [TTY][] text terminal. See [TTY keybindings][] for a list of key
371combinations.
372
373If `key` is specified, `data` is ignored.
374
375When called, `rl.write()` will resume the `input` stream if it has been
376paused.
377
378If the `readline.Interface` was created with `output` set to `null` or
379`undefined` the `data` and `key` are not written.
380
381```js
382rl.write('Delete this!');
383// Simulate Ctrl+U to delete the line written previously
384rl.write(null, { ctrl: true, name: 'u' });
385```
386
387The `rl.write()` method will write the data to the `readline` `Interface`'s
388`input` *as if it were provided by the user*.
389
390### `rl[Symbol.asyncIterator]()`
391<!-- YAML
392added:
393 - v11.4.0
394 - v10.16.0
395changes:
396  - version:
397     - v11.14.0
398     - v10.17.0
399    pr-url: https://github.com/nodejs/node/pull/26989
400    description: Symbol.asyncIterator support is no longer experimental.
401-->
402
403* Returns: {AsyncIterator}
404
405Create an `AsyncIterator` object that iterates through each line in the input
406stream as a string. This method allows asynchronous iteration of
407`readline.Interface` objects through `for await...of` loops.
408
409Errors in the input stream are not forwarded.
410
411If the loop is terminated with `break`, `throw`, or `return`,
412[`rl.close()`][] will be called. In other words, iterating over a
413`readline.Interface` will always consume the input stream fully.
414
415Performance is not on par with the traditional `'line'` event API. Use `'line'`
416instead for performance-sensitive applications.
417
418```js
419async function processLineByLine() {
420  const rl = readline.createInterface({
421    // ...
422  });
423
424  for await (const line of rl) {
425    // Each line in the readline input will be successively available here as
426    // `line`.
427  }
428}
429```
430
431`readline.createInterface()` will start to consume the input stream once
432invoked. Having asynchronous operations between interface creation and
433asynchronous iteration may result in missed lines.
434
435### `rl.line`
436<!-- YAML
437added: v0.1.98
438changes:
439  - version: v14.18.0
440    pr-url: https://github.com/nodejs/node/pull/33676
441    description: Value will always be a string, never undefined.
442-->
443
444* {string}
445
446The current input data being processed by node.
447
448This can be used when collecting input from a TTY stream to retrieve the
449current value that has been processed thus far, prior to the `line` event
450being emitted. Once the `line` event has been emitted, this property will
451be an empty string.
452
453Be aware that modifying the value during the instance runtime may have
454unintended consequences if `rl.cursor` is not also controlled.
455
456**If not using a TTY stream for input, use the [`'line'`][] event.**
457
458One possible use case would be as follows:
459
460```js
461const values = ['lorem ipsum', 'dolor sit amet'];
462const rl = readline.createInterface(process.stdin);
463const showResults = debounce(() => {
464  console.log(
465    '\n',
466    values.filter((val) => val.startsWith(rl.line)).join(' ')
467  );
468}, 300);
469process.stdin.on('keypress', (c, k) => {
470  showResults();
471});
472```
473
474### `rl.cursor`
475<!-- YAML
476added: v0.1.98
477-->
478
479* {number|undefined}
480
481The cursor position relative to `rl.line`.
482
483This will track where the current cursor lands in the input string, when
484reading input from a TTY stream. The position of cursor determines the
485portion of the input string that will be modified as input is processed,
486as well as the column where the terminal caret will be rendered.
487
488### `rl.getCursorPos()`
489<!-- YAML
490added:
491 - v13.5.0
492 - v12.16.0
493-->
494
495* Returns: {Object}
496  * `rows` {number} the row of the prompt the cursor currently lands on
497  * `cols` {number} the screen column the cursor currently lands on
498
499Returns the real position of the cursor in relation to the input
500prompt + string. Long input (wrapping) strings, as well as multiple
501line prompts are included in the calculations.
502
503## `readline.clearLine(stream, dir[, callback])`
504<!-- YAML
505added: v0.7.7
506changes:
507  - version: v12.7.0
508    pr-url: https://github.com/nodejs/node/pull/28674
509    description: The stream's write() callback and return value are exposed.
510-->
511
512* `stream` {stream.Writable}
513* `dir` {number}
514  * `-1`: to the left from cursor
515  * `1`: to the right from cursor
516  * `0`: the entire line
517* `callback` {Function} Invoked once the operation completes.
518* Returns: {boolean} `false` if `stream` wishes for the calling code to wait for
519  the `'drain'` event to be emitted before continuing to write additional data;
520  otherwise `true`.
521
522The `readline.clearLine()` method clears current line of given [TTY][] stream
523in a specified direction identified by `dir`.
524
525## `readline.clearScreenDown(stream[, callback])`
526<!-- YAML
527added: v0.7.7
528changes:
529  - version: v12.7.0
530    pr-url: https://github.com/nodejs/node/pull/28641
531    description: The stream's write() callback and return value are exposed.
532-->
533
534* `stream` {stream.Writable}
535* `callback` {Function} Invoked once the operation completes.
536* Returns: {boolean} `false` if `stream` wishes for the calling code to wait for
537  the `'drain'` event to be emitted before continuing to write additional data;
538  otherwise `true`.
539
540The `readline.clearScreenDown()` method clears the given [TTY][] stream from
541the current position of the cursor down.
542
543## `readline.createInterface(options)`
544<!-- YAML
545added: v0.1.98
546changes:
547  - version: v14.18.0
548    pr-url: https://github.com/nodejs/node/pull/37932
549    description: The `signal` option is supported now.
550  - version: v14.18.0
551    pr-url: https://github.com/nodejs/node/pull/33662
552    description: The `history` option is supported now.
553  - version: v13.9.0
554    pr-url: https://github.com/nodejs/node/pull/31318
555    description: The `tabSize` option is supported now.
556  - version:
557    - v8.3.0
558    - v6.11.4
559    pr-url: https://github.com/nodejs/node/pull/13497
560    description: Remove max limit of `crlfDelay` option.
561  - version: v6.6.0
562    pr-url: https://github.com/nodejs/node/pull/8109
563    description: The `crlfDelay` option is supported now.
564  - version: v6.3.0
565    pr-url: https://github.com/nodejs/node/pull/7125
566    description: The `prompt` option is supported now.
567  - version: v6.0.0
568    pr-url: https://github.com/nodejs/node/pull/6352
569    description: The `historySize` option can be `0` now.
570-->
571
572* `options` {Object}
573  * `input` {stream.Readable} The [Readable][] stream to listen to. This option
574    is *required*.
575  * `output` {stream.Writable} The [Writable][] stream to write readline data
576    to.
577  * `completer` {Function} An optional function used for Tab autocompletion.
578  * `terminal` {boolean} `true` if the `input` and `output` streams should be
579    treated like a TTY, and have ANSI/VT100 escape codes written to it.
580    **Default:** checking `isTTY` on the `output` stream upon instantiation.
581  * `history` {string[]} Initial list of history lines. This option makes sense
582    only if `terminal` is set to `true` by the user or by an internal `output`
583    check, otherwise the history caching mechanism is not initialized at all.
584    **Default:** `[]`.
585  * `historySize` {number} Maximum number of history lines retained. To disable
586    the history set this value to `0`. This option makes sense only if
587    `terminal` is set to `true` by the user or by an internal `output` check,
588    otherwise the history caching mechanism is not initialized at all.
589    **Default:** `30`.
590  * `removeHistoryDuplicates` {boolean} If `true`, when a new input line added
591    to the history list duplicates an older one, this removes the older line
592    from the list. **Default:** `false`.
593  * `prompt` {string} The prompt string to use. **Default:** `'> '`.
594  * `crlfDelay` {number} If the delay between `\r` and `\n` exceeds
595    `crlfDelay` milliseconds, both `\r` and `\n` will be treated as separate
596    end-of-line input. `crlfDelay` will be coerced to a number no less than
597    `100`. It can be set to `Infinity`, in which case `\r` followed by `\n`
598    will always be considered a single newline (which may be reasonable for
599    [reading files][] with `\r\n` line delimiter). **Default:** `100`.
600  * `escapeCodeTimeout` {number} The duration `readline` will wait for a
601    character (when reading an ambiguous key sequence in milliseconds one that
602    can both form a complete key sequence using the input read so far and can
603    take additional input to complete a longer key sequence).
604    **Default:** `500`.
605  * `tabSize` {integer} The number of spaces a tab is equal to (minimum 1).
606    **Default:** `8`.
607  * `signal` {AbortSignal} Allows closing the interface using an AbortSignal.
608    Aborting the signal will internally call `close` on the interface.
609* Returns: {readline.Interface}
610
611The `readline.createInterface()` method creates a new `readline.Interface`
612instance.
613
614```js
615const readline = require('readline');
616const rl = readline.createInterface({
617  input: process.stdin,
618  output: process.stdout
619});
620```
621
622Once the `readline.Interface` instance is created, the most common case is to
623listen for the `'line'` event:
624
625```js
626rl.on('line', (line) => {
627  console.log(`Received: ${line}`);
628});
629```
630
631If `terminal` is `true` for this instance then the `output` stream will get
632the best compatibility if it defines an `output.columns` property and emits
633a `'resize'` event on the `output` if or when the columns ever change
634([`process.stdout`][] does this automatically when it is a TTY).
635
636When creating a `readline.Interface` using `stdin` as input, the program
637will not terminate until it receives `EOF` (<kbd>Ctrl</kbd>+<kbd>D</kbd> on
638Linux/macOS, <kbd>Ctrl</kbd>+<kbd>Z</kbd> followed by <kbd>Return</kbd> on
639Windows).
640If you want your application to exit without waiting for user input, you can
641[`unref()`][] the standard input stream:
642
643```js
644process.stdin.unref();
645```
646
647### Use of the `completer` function
648
649The `completer` function takes the current line entered by the user
650as an argument, and returns an `Array` with 2 entries:
651
652* An `Array` with matching entries for the completion.
653* The substring that was used for the matching.
654
655For instance: `[[substr1, substr2, ...], originalsubstring]`.
656
657```js
658function completer(line) {
659  const completions = '.help .error .exit .quit .q'.split(' ');
660  const hits = completions.filter((c) => c.startsWith(line));
661  // Show all completions if none found
662  return [hits.length ? hits : completions, line];
663}
664```
665
666The `completer` function can be called asynchronously if it accepts two
667arguments:
668
669```js
670function completer(linePartial, callback) {
671  callback(null, [['123'], linePartial]);
672}
673```
674
675## `readline.cursorTo(stream, x[, y][, callback])`
676<!-- YAML
677added: v0.7.7
678changes:
679  - version: v12.7.0
680    pr-url: https://github.com/nodejs/node/pull/28674
681    description: The stream's write() callback and return value are exposed.
682-->
683
684* `stream` {stream.Writable}
685* `x` {number}
686* `y` {number}
687* `callback` {Function} Invoked once the operation completes.
688* Returns: {boolean} `false` if `stream` wishes for the calling code to wait for
689  the `'drain'` event to be emitted before continuing to write additional data;
690  otherwise `true`.
691
692The `readline.cursorTo()` method moves cursor to the specified position in a
693given [TTY][] `stream`.
694
695## `readline.emitKeypressEvents(stream[, interface])`
696<!-- YAML
697added: v0.7.7
698-->
699
700* `stream` {stream.Readable}
701* `interface` {readline.Interface}
702
703The `readline.emitKeypressEvents()` method causes the given [Readable][]
704stream to begin emitting `'keypress'` events corresponding to received input.
705
706Optionally, `interface` specifies a `readline.Interface` instance for which
707autocompletion is disabled when copy-pasted input is detected.
708
709If the `stream` is a [TTY][], then it must be in raw mode.
710
711This is automatically called by any readline instance on its `input` if the
712`input` is a terminal. Closing the `readline` instance does not stop
713the `input` from emitting `'keypress'` events.
714
715```js
716readline.emitKeypressEvents(process.stdin);
717if (process.stdin.isTTY)
718  process.stdin.setRawMode(true);
719```
720
721## `readline.moveCursor(stream, dx, dy[, callback])`
722<!-- YAML
723added: v0.7.7
724changes:
725  - version: v12.7.0
726    pr-url: https://github.com/nodejs/node/pull/28674
727    description: The stream's write() callback and return value are exposed.
728-->
729
730* `stream` {stream.Writable}
731* `dx` {number}
732* `dy` {number}
733* `callback` {Function} Invoked once the operation completes.
734* Returns: {boolean} `false` if `stream` wishes for the calling code to wait for
735  the `'drain'` event to be emitted before continuing to write additional data;
736  otherwise `true`.
737
738The `readline.moveCursor()` method moves the cursor *relative* to its current
739position in a given [TTY][] `stream`.
740
741## Example: Tiny CLI
742
743The following example illustrates the use of `readline.Interface` class to
744implement a small command-line interface:
745
746```js
747const readline = require('readline');
748const rl = readline.createInterface({
749  input: process.stdin,
750  output: process.stdout,
751  prompt: 'OHAI> '
752});
753
754rl.prompt();
755
756rl.on('line', (line) => {
757  switch (line.trim()) {
758    case 'hello':
759      console.log('world!');
760      break;
761    default:
762      console.log(`Say what? I might have heard '${line.trim()}'`);
763      break;
764  }
765  rl.prompt();
766}).on('close', () => {
767  console.log('Have a great day!');
768  process.exit(0);
769});
770```
771
772## Example: Read file stream line-by-Line
773
774A common use case for `readline` is to consume an input file one line at a
775time. The easiest way to do so is leveraging the [`fs.ReadStream`][] API as
776well as a `for await...of` loop:
777
778```js
779const fs = require('fs');
780const readline = require('readline');
781
782async function processLineByLine() {
783  const fileStream = fs.createReadStream('input.txt');
784
785  const rl = readline.createInterface({
786    input: fileStream,
787    crlfDelay: Infinity
788  });
789  // Note: we use the crlfDelay option to recognize all instances of CR LF
790  // ('\r\n') in input.txt as a single line break.
791
792  for await (const line of rl) {
793    // Each line in input.txt will be successively available here as `line`.
794    console.log(`Line from file: ${line}`);
795  }
796}
797
798processLineByLine();
799```
800
801Alternatively, one could use the [`'line'`][] event:
802
803```js
804const fs = require('fs');
805const readline = require('readline');
806
807const rl = readline.createInterface({
808  input: fs.createReadStream('sample.txt'),
809  crlfDelay: Infinity
810});
811
812rl.on('line', (line) => {
813  console.log(`Line from file: ${line}`);
814});
815```
816
817Currently, `for await...of` loop can be a bit slower. If `async` / `await`
818flow and speed are both essential, a mixed approach can be applied:
819
820```js
821const { once } = require('events');
822const { createReadStream } = require('fs');
823const { createInterface } = require('readline');
824
825(async function processLineByLine() {
826  try {
827    const rl = createInterface({
828      input: createReadStream('big-file.txt'),
829      crlfDelay: Infinity
830    });
831
832    rl.on('line', (line) => {
833      // Process the line.
834    });
835
836    await once(rl, 'close');
837
838    console.log('File processed.');
839  } catch (err) {
840    console.error(err);
841  }
842})();
843```
844
845## TTY keybindings
846
847<table>
848  <tr>
849    <th>Keybindings</th>
850    <th>Description</th>
851    <th>Notes</th>
852  </tr>
853  <tr>
854    <td><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Backspace</kbd></td>
855    <td>Delete line left</td>
856    <td>Doesn't work on Linux, Mac and Windows</td>
857  </tr>
858  <tr>
859    <td><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Delete</kbd></td>
860    <td>Delete line right</td>
861    <td>Doesn't work on Mac</td>
862  </tr>
863  <tr>
864    <td><kbd>Ctrl</kbd>+<kbd>C</kbd></td>
865    <td>Emit <code>SIGINT</code> or close the readline instance</td>
866    <td></td>
867  </tr>
868  <tr>
869    <td><kbd>Ctrl</kbd>+<kbd>H</kbd></td>
870    <td>Delete left</td>
871    <td></td>
872  </tr>
873  <tr>
874    <td><kbd>Ctrl</kbd>+<kbd>D</kbd></td>
875    <td>Delete right or close the readline instance in case the current line is empty / EOF</td>
876    <td>Doesn't work on Windows</td>
877  </tr>
878  <tr>
879    <td><kbd>Ctrl</kbd>+<kbd>U</kbd></td>
880    <td>Delete from the current position to the line start</td>
881    <td></td>
882  </tr>
883  <tr>
884    <td><kbd>Ctrl</kbd>+<kbd>K</kbd></td>
885    <td>Delete from the current position to the end of line</td>
886    <td></td>
887  </tr>
888  <tr>
889    <td><kbd>Ctrl</kbd>+<kbd>A</kbd></td>
890    <td>Go to start of line</td>
891    <td></td>
892  </tr>
893  <tr>
894    <td><kbd>Ctrl</kbd>+<kbd>E</kbd></td>
895    <td>Go to to end of line</td>
896    <td></td>
897  </tr>
898  <tr>
899    <td><kbd>Ctrl</kbd>+<kbd>B</kbd></td>
900    <td>Back one character</td>
901    <td></td>
902  </tr>
903  <tr>
904    <td><kbd>Ctrl</kbd>+<kbd>F</kbd></td>
905    <td>Forward one character</td>
906    <td></td>
907  </tr>
908  <tr>
909    <td><kbd>Ctrl</kbd>+<kbd>L</kbd></td>
910    <td>Clear screen</td>
911    <td></td>
912  </tr>
913  <tr>
914    <td><kbd>Ctrl</kbd>+<kbd>N</kbd></td>
915    <td>Next history item</td>
916    <td></td>
917  </tr>
918  <tr>
919    <td><kbd>Ctrl</kbd>+<kbd>P</kbd></td>
920    <td>Previous history item</td>
921    <td></td>
922  </tr>
923  <tr>
924    <td><kbd>Ctrl</kbd>+<kbd>Z</kbd></td>
925    <td>Moves running process into background. Type
926    <code>fg</code> and press <kbd>Enter</kbd>
927    to return.</td>
928    <td>Doesn't work on Windows</td>
929  </tr>
930  <tr>
931    <td><kbd>Ctrl</kbd>+<kbd>W</kbd> or <kbd>Ctrl</kbd>
932   +<kbd>Backspace</kbd></td>
933    <td>Delete backward to a word boundary</td>
934    <td><kbd>Ctrl</kbd>+<kbd>Backspace</kbd> Doesn't
935    work on Linux, Mac and Windows</td>
936  </tr>
937  <tr>
938    <td><kbd>Ctrl</kbd>+<kbd>Delete</kbd></td>
939    <td>Delete forward to a word boundary</td>
940    <td>Doesn't work on Mac</td>
941  </tr>
942  <tr>
943    <td><kbd>Ctrl</kbd>+<kbd>Left arrow</kbd> or
944    <kbd>Meta</kbd>+<kbd>B</kbd></td>
945    <td>Word left</td>
946    <td><kbd>Ctrl</kbd>+<kbd>Left arrow</kbd> Doesn't work
947    on Mac</td>
948  </tr>
949  <tr>
950    <td><kbd>Ctrl</kbd>+<kbd>Right arrow</kbd> or
951    <kbd>Meta</kbd>+<kbd>F</kbd></td>
952    <td>Word right</td>
953    <td><kbd>Ctrl</kbd>+<kbd>Right arrow</kbd> Doesn't work
954    on Mac</td>
955  </tr>
956  <tr>
957    <td><kbd>Meta</kbd>+<kbd>D</kbd> or <kbd>Meta</kbd>
958   +<kbd>Delete</kbd></td>
959    <td>Delete word right</td>
960    <td><kbd>Meta</kbd>+<kbd>Delete</kbd> Doesn't work
961    on windows</td>
962  </tr>
963  <tr>
964    <td><kbd>Meta</kbd>+<kbd>Backspace</kbd></td>
965    <td>Delete word left</td>
966    <td>Doesn't work on Mac</td>
967  </tr>
968</table>
969
970[Readable]: stream.md#stream_readable_streams
971[TTY]: tty.md
972[TTY keybindings]: #readline_tty_keybindings
973[Writable]: stream.md#stream_writable_streams
974[`'SIGCONT'`]: #readline_event_sigcont
975[`'SIGTSTP'`]: #readline_event_sigtstp
976[`'line'`]: #readline_event_line
977[`fs.ReadStream`]: fs.md#fs_class_fs_readstream
978[`process.stdin`]: process.md#process_process_stdin
979[`process.stdout`]: process.md#process_process_stdout
980[`rl.close()`]: #readline_rl_close
981[`unref()`]: net.md#net_socket_unref
982[reading files]: #readline_example_read_file_stream_line_by_line
983