DEV Community

Sanjar Afaq
Sanjar Afaq

Posted on

6

Keyboard input in Node.js

This article talks about working with keyboard input in Node.js. This code will run in the terminal.

We'll be discussing the default way in Node to do this. Practically, people prefer using a library like inquirer to create interactive CLIs.


The readline module can be used for reading input into programs.
A promise version readline/promises is it's marked experimental. Works by default in v20.

The APIs of the module allow for very granular control if needed - like position of cursor, row/column position, reading a line vs per character reads.

I'll demonstrate two commonly needed interfaces:

  1. Read a sentence (until user presses enter). Like C++'s cin.
  2. Read single character

1. Read sentence (until 'Enter' is pressed)

Since we get back something once, I'm using async-await.

Logic (snippet)

const readline = require("readline/promises");

/**
 * Take sentence input, until you press 'Enter'
 * Like C++ cin
 *
 * @param {String} message
 * @returns {String}
 */
const prompt = async (message) => {
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  const answer = await rl.question(message);

  rl.close(); // stop listening
  return answer;
};
Enter fullscreen mode Exit fullscreen mode

A simple program

// copy code from above here
async function simpleSum() {
  const a = await prompt("Enter first number: ");
  const b = await prompt("Enter second number: ");
  console.log("Sum is", Number(a) + Number(b));
}
simpleSum();
Enter fullscreen mode Exit fullscreen mode

A more interesting program

async function getGitHubName() {
  const username = await prompt("GitHub username: ");
  const resp = await fetch(`https://api.github.com/users/${username}`);
// yes, `fetch` is available by default in Node v20
  if (!resp.ok) {
    console.log(
      "Error occurred",
      ",",
      "Code:",
      resp.status,
      ",",
      "Message:" + (await resp.text())
    );
  } else {
    const data = await resp.json();
    const name = data.name;
    console.log("User found. Name:", name);
  }
}

getGitHubName();
Enter fullscreen mode Exit fullscreen mode

2. Run code for single character

More like run some code on keypress. This continuously listens for keypresses.
Since each keypress runs some code, I'm using callback.

Example: this is what Metro (React native dev process) runs like - when 'r' is pressed it reloads.

Logic (snippet)

const readline = require("readline/promises");
/**
 * Continues listening for keypresses, and run code for each keypress
 */
const listenKeyPresses = (callback = (key, data) => console.log({ key, data })) => {

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  rl.input.on("keypress", callback);
  return rl;
};

listenKeyPresses.example = () => {
  listenKeyPresses((key, data) => {
    const isLetter =
      key.toLowerCase().charCodeAt() >= "a".charCodeAt() &&
      key.toLowerCase().charCodeAt() <= "z".charCodeAt();

    console.log(`\b${key} is a ${isLetter ? "letter" : "Non-letter"}`);
    console.log(data);
  });
};
listenKeyPresses.example() // run the example
Enter fullscreen mode Exit fullscreen mode

This is very handy when testing, trying something new. Instead of creating a small frontend using HTML, CSS or JS, or setting up Postman. Just use this, setup key press and corresponding code run, and test quickly. Both input + output in the same terminal!

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (1)

Collapse
 
monfernape profile image
Usman Khalil

Noice 👌

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs