Skip to main content
Contact our team to know more about our services
select webform
Become a part of our team
select webform
One file only.
1.5 GB limit.
Allowed types: gif, jpg, jpeg, png, bmp, eps, tif, pict, psd, txt, rtf, html, odf, pdf, doc, docx, ppt, pptx, xls, xlsx, xml, avi, mov, mp3, mp4, ogg, wav, bz2, dmg, gz, jar, rar, sit, svg, tar, zip.
Building browser based terminal using Xterm.js and Node.js
24 Aug 2023

The need for remote access and management of servers and applications is ever-growing in today's world. Occasionally, a customized requirement emerges wherein we find the necessity for a terminal that facilitates remote access from within our own web-based applications. Let's understand a bit more about web-based terminals. 

Why do we need a terminal in the browser?

Instead of distributing server access via keys, there is an option to provide individuals entry to a web-based terminal located behind a secure login interface. This login interface remains under admin control. For example - Digital Ocean provides browser-based terminal access to droplets and Play with Dockers provides terminal access to containers right within the browser. When involved in developer tools, there's a high likelihood of eventually finding the need to create an embedded terminal.

How to build a terminal

One powerful way to achieve this is by creating a browser-based terminal using xterm.js, Web Socket & Node.js. This blog post will guide you through the steps to build your own browser-based terminal, enabling you to interact with remote systems and applications directly from your web browser.

How does this work? 

First, a server and client need to be created. Use Socket.IO to send and receive data.

 

The frontend implementation involves recreating a terminal emulator using the classic HTML, CSS, and JavaScript trio. When a user inputs a command in the emulator, it is transmitted to a NodeJS backend through a WebSocket, diverging from the standard HTTP protocol. This is because of the terminal's behavior. Upon receiving a command from the emulator, the backend executes it within an actual terminal. On inputting the command 'ls', a list of files and folders of that particular directory is returned to the emulator. It is a perfect one-way communication. Yet, specific commands like "netstat" trigger dynamic screen updates in the terminal, making back-and-forth HTTP communication cumbersome. With a WebSocket, the real terminal can send output whenever available, and the frontend emulator can do the same. This facilitates the emulation of features like progress bars without complications.

What is Xterm.Js? 

  • Xterm.js is a TypeScript-based frontend element enabling applications to provide comprehensive terminal experiences to their users through web browsers. It finds use in VS Code, Hyper, and Theia.
  • Xterm.js does not function as a standalone terminal application available for direct download and local use.
  • Xterm.js is not like "bash." Instead, it can establish connections to processes such as "bash," enabling interactive interactions where users can supply input and receive corresponding output.

Client-side setup:

Setting up the client side is straightforward. Generate a terminal using xterm and link it to a designated container within the Document Object Model (DOM). Next, transmit input from the terminal to the associated server of socket.io. Additionally, include an event listener for the socket.io-client, responsible for displaying responses received from the socket.io server on the xterm.js terminal.

On a html page, create a div where xtermjs will attach a terminal.


Before starting socket.io client, create a wrapper class containing xtermjs-related functions and the required event listeners for socket.io-client.

Users can customize it further by updating TerminalUI.js file and customize the this.terminal object.

 

Finally, initialize the socket.io client to send/receive events from the node-pty process from the server.

Backend Implementation:

The backend implementation functions as a bridge, facilitating communication between the emulator and the real terminal by forwarding both inputs and outputs seamlessly between the two.

First, set up the basics. Create a server from NodeJS HTTP module and pass it to socket.io server.

Index.js

SocketService.js 

Next, create a wrapper class to add event listeners for socket.io events. For this, create a SocketService Js file.