Terminal in React JS
Tags: react, javascript, css, design
Published: 2017-07-25 15:51:48

---
title: Terminal in React JS
published: true
description: A component that renders a terminal
tags: React, JavaScript, CSS, Design  
---

![screenshot](https://camo.githubusercontent.com/0cbe60854a20d1c9d17b863dc53c6ae84498af7a/68747470733a2f2f692e6779617a6f2e636f6d2f61376533356633343662393039333439613032343338656531373637383935362e676966)

Already more than two weeks ago, I created [terminal-in-react](https://github.com/nitin42/terminal-in-react), a component that renders a terminal in React JS. I wanted to create something interesting with React and then I’d this crazy idea.

### How it worksÂ ?

The component renders a terminal interface which allows you to add your own commands. For example – let’s add a command that will type the given text automatically.

```js
<Terminal
  commands={{
    "type-text": (args, print, runCommand) => {
      const text = args.slice(1).join(' ');
      print('');
      for (let i = 0; i < text.length; i += 1) {
        setTimeout(() => {
          runCommand(`edit-line ${text.slice(0, i + 1)}`);
        }, 100 * i);
      }
    }
  }}
/>
```

Don’t worry, we will look into the API later. Let’s see how this command works.

![type](https://camo.githubusercontent.com/811a5b86064acd395a6155f0bea1dffa0337262e/68747470733a2f2f692e6779617a6f2e636f6d2f65663234323734363439383962316365313462633434626234666339343638392e676966)

Interesting! RightÂ ? But there is more…

### Basic example

```jsx

import React, { Component } from 'react';
import Terminal from 'terminal-in-react';
import 'terminal-in-react/lib/css/index.css';

class App extends Component {
  showMsg = () => 'Hello World'

  render() {
    return (
      <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }}>
        <Terminal
          color='green'
          backgroundColor='black'
          barColor='black'
          style={{ fontWeight: "bold", fontSize: "1em" }}
          commands={{
            'open-google': () => window.open('google.com', '_blank'),
            showmsg: this.showMsg,
            popup: () => alert('Terminal in React')
          }}
          descriptions={{
            'open-google': 'opens google.com',
            showmsg: 'shows a message',
            alert: 'alert', popup: 'alert'
          }}
          msg='You can write anything here. Example - Hello! My name is Foo and I like Bar.'
        />
      </div>
    );
  }
}
```

In the above example I’ve added three commands, open-googleÂ , showmsg and popupÂ . Also I’ve described all the three commands with a description prop.

### Display message
Display a message with `msg` prop when the component mounts.

```html
<Terminal msg="Hello World" />
```

### Customisation

To customise the terminal look, you can pass prop `color` to change the text color, `backgroundColor` to change the background color and `barColor` to change the color of bar.

![](https://cdn-images-1.medium.com/max/800/1*2zVFoGsY6PVHT07Kj7UisA.gif)

### Minimise, Maximise andÂ Close
Yup! Those three buttons actually work ðŸ˜…

![](https://cdn-images-1.medium.com/max/1000/1*M4SVqbvnrmpndnfGk7ip7A.gif)

### Creating advanceÂ commands
You can also add a command that performs some async stuff rather that basic I/O using the advance command api. It has three parameters -
* `arguments` - input array
* `print` - method to write new line
* `runCommand` - to call the command

```js

<Terminal
  commands={{
    color: {
      method: (args, print, runCommand) => {
        print(`The color is ${args._[0] || args.color}`);
      },
      options: [
        {
          name: 'color',
          description: 'The color the output should be',
          defaultValue: 'white',
        },
      ],
    },
  }}
/>
```

![](https://cdn-images-1.medium.com/max/800/1*0KIMGya2LgZSFWVaLa8-Yg.gif)

### Using pluginsÂ ðŸ”¥
We have also developed a plugin system for the <Terminal /> component which helps you develop custom plugins.

One example of the plugin is [terminal-in-react-pseudo-file-system-plugin](https://github.com/jcgertig/terminal-in-react-pseudo-file-system-plugin) which creates a fake file system.

```js
<Terminal
  plugins={[
    new PseudoFileSystem(),
  ]}
/>
```

Let’s see it in action,

![](https://cdn-images-1.medium.com/max/800/1*IyyiXeHf95GCuajcq3KLUQ.gif)

Woaah! Awesome!! Let us know if you make something interesting ðŸ˜ƒ

### More features
* Tab autocomplete

![](https://cdn-images-1.medium.com/max/800/1*xoLnt73ETCMseEvlgFKZDw.gif)

* Multi-line input

![](https://cdn-images-1.medium.com/max/800/1*mIIyNiXpsIO8BYRAjEA-gQ.gif)

* Check history of your commands

![](https://cdn-images-1.medium.com/max/800/1*XavuSylXlxkidSTJ8m-RtA.gif)

### Keyboard shortcuts

You can also define keyboard shortcuts. They have to be grouped by os. The three available are win, darwin, and linux. You can group multiple os by a `,` for example if the shortcut was for all platforms `win,darwin,linux` would be fine as a key. The value of the shortcut should be a command to run.

```js
<Terminal
  shortcuts={{
    'darwin,win,linux': {
      'ctrl + a': 'echo whoo',
    },
  }}
/>
```


OS specific shortcuts

```js

<Terminal
  shortcuts={{
    'win': {
      'ctrl + a': 'echo hi windows',
    },
    'darwin': {
      'cmd + a': 'echo hi mac'
    },
    'linux': {
      'ctrl + a': 'echo hi linux'
    }
  }}
/>
```


or mix and match

```js

<Terminal
  shortcuts={{
    'win,linux': {
      'ctrl + b': 'echo we are special',
    },
    'win': {
      'ctrl + a': 'echo hi windows',
    },
    'darwin': {
      'cmd + a': 'echo hi mac'
    },
    'linux': {
      'ctrl + a': 'echo hi linux'
    }
  }}
/>
```


### Built-in commands

* `clear` - clears the screen
* `help` - list all the commands
* `show` - shows a msg if any
* `echo` - display the input message
* `edit-line` - edits the last line or a given line using the -l argument

### Current status
We are working on -

* adding workspaces and tabs
* parser (to write basic programs)
* expanding the plugin system

So expect much more features in the next release ðŸ˜Ž

Shoutout to [Jonathan Gertig](https://github.com/jcgertig) and [Christian Varisco](https://github.com/CVarisco) for their amazing contributions to the project ðŸŽ‰Â . Thank you so much!!

If you want to contribute to the project, [here](https://github.com/nitin42/terminal-in-react/blob/master/CONTRIBUTING.md) is the contributing guide. I’m excited to see your pull request.

GitHub - https://github.com/nitin42/terminal-in-react

Website - http://terminal-in-react.surge.sh/

Docs - https://github.com/nitin42/terminal-in-react/wiki