a modern node.js module for interacting with pseudo terminals.
JavaScript C++ Python


Build Status


child_pty is a module for creating and interacting with pseudo terminals. It tries to be as minimal as possible and borrows most of its functionality from child_process.


See child_process with the following changes:

  • Only child_pty.spawn() is supported


  • options fields:
    • new field: options.columns: columns of the instanciated PTY.
    • new field: options.rows: rows of the instanciated PTY.
    • new field: options.ptyInit should contain a function that will be called before after the pty is created. This allows to set terminal parameters using tools like node-termios.
    • options.detached is ignored.
    • options.stdio allows 'pty' as array element. The value 'pty' indicates, that this fd is bound to the pty.
    • options.stdio will default to [ 'pty', 'pty', 'pty' ]


ChildProcess of child_pty uses the same prototype as child_process. Its instances differentiate in the following:

  • new field: #pty points to a PtyRwStream that's associated with the child processes pty.
  • All file descriptors are bound to the pty in the #stdio array point to the the same object as #pty. This is also true for #stdin and #stdout.
  • If stderr is bound to the pty the field #stderr will be a dummy Event Emitter that will never emit any events.


PtyRwStream is a net.Socket with the following changes

  • #resize(size): resizes the underlying pty. The size attribute should have the following fields:
    • #size.columns: columns of the instanciated PTY.
    • #size.rows: rows of the instanciated PTY.
  • #ttyname: property with the name of the tty (eg: /dev/ttys016)
  • due to the nature of PTYs it's neither possible to get 'end' events from the underlying process when it closes its pty file descriptors nor will call #end() close the child processes file descriptor. To end the underlying process call ChildProcess#kill('SIGHUP') instead.
  • PtyRwStream will emit the 'end' Event when the child process exits. It will not emit the 'end' event if the child process closes its slave file descriptor. See above.


This example opens a PTY with /bin/sh, resizes the terminal, executes ls -l, and exits the shell.

var child_pty = require('child_pty');
var child = child_pty.spawn('/bin/sh', []);
child.stdout.on('resize', function() {
    console.log('New columns: ' + this.columns);
    console.log('New rows:    ' + this.rows);
child.stdout.resize({ columns: 80, rows: 48 });
child.stdin.write('ls -l\n');


  • v0.1 - initial release
  • v0.2 - fix job control for shells
  • v0.3 - API changes to fit child_process
  • v0.4 - remove deprecated APIs
  • v0.5 - MacOS support
  • v1.0 - Exposes TTY name to the API
  • v1.1 - Exposes tcgetattr/tcsetattr functions; node-4.0 support
  • v2.0 - child_pty now emits the error event when a child can't be spawned instead of printing an error to stdout.
  • v3.0 - child_pty IO handling has been rewritten. the end event is emitted on the pty when the child program exits. all fds opened on the pty point to the same Stream instance.