Build a Custom REPL Environment in Node.js

This article explains how to create and customize a Read-Eval-Print Loop (REPL) environment inside a Node.js application. You will learn how to use Node’s built-in repl module to launch an interactive shell, expose custom variables and functions to the execution context, and define custom evaluation logic for handling user input.

Using the Built-In REPL Module

Node.js provides a native repl module that allows you to spin up an interactive terminal within your application. The simplest way to start a REPL is by importing the module and calling the start method.

const repl = require('repl');

// Start a basic REPL session
repl.start({
  prompt: 'my-app > ',
});

When you run this script, your terminal will display the my-app > prompt and allow you to execute standard JavaScript code just like the default Node.js shell.

Injecting Custom Context and Variables

To make a REPL useful for debugging or managing your application, you can expose local variables, helper functions, or database connections directly to the REPL context. This allows users to interact with your application’s state in real-time.

const repl = require('repl');

// Mock application state/services
const db = {
  users: ['Alice', 'Bob'],
  getUsers: () => db.users
};

const replServer = repl.start({
  prompt: 'admin-panel > ',
});

// Assign custom objects to the REPL context
replServer.context.db = db;
replServer.context.greet = (name) => `Hello, ${name}!`;

In this session, typing db.getUsers() or greet('Alice') will execute the injected functions and print their return values to the terminal.

Creating a Custom Evaluation Function

By default, the REPL evaluates input as standard JavaScript. If you want to build a custom command-line interface (CLI) with its own syntax, you can override the default evaluation logic by providing a custom eval function.

const repl = require('repl');

// Custom evaluation handler
function customEval(cmd, context, filename, callback) {
  // Remove trailing newlines and whitespace
  const input = cmd.trim();

  if (input === 'hello') {
    return callback(null, 'World!');
  }

  if (input === 'time') {
    return callback(null, new Date().toLocaleTimeString());
  }

  // Handle errors or unrecognized commands
  callback(null, `Unknown command: "${input}"`);
}

repl.start({
  prompt: 'custom-cli > ',
  eval: customEval
});

The callback function accepts two arguments: an error (or null) and the result to print to the screen.

Handling REPL Events

The REPL server emits events that allow you to clean up resources or run code when certain actions occur, such as when a user exits the environment.

const replServer = repl.start({ prompt: 'app > ' });

// Handle REPL exit event (e.g., via Ctrl+C or .exit command)
replServer.on('exit', () => {
  console.log('Exiting REPL. Cleaning up connections...');
  process.exit();
});