For a developer, most of his/her time is spent on the code editor or the terminal. As web developers, we mostly target browsers and nowadays even native mobile platforms (thanks React Native). But I recently figured out you could also target terminals for your web-based UIs.
What do I mean by this ?
curl wttr.in in your terminal. This console app from Igor Chubin written in python is what inspired me to write this blog.
Amazing! right. So, I decided to dig a bit deeper and find out how it is done.
ANSI Escape Codes
ANSI escape sequences are a standard for in-band signaling to control the cursor location, color, and other options on video text terminals. Certain sequences of bytes, most starting with Esc and ‘[‘, are embedded into the text, which the terminal looks for and interprets as commands, not as character codes.
In essence, ANSI Escape codes are characters that are interpreted by the terminal in a special way. These codes can be used to add colors to the text, control cursor location, etc. All major terminals support these codes including Windows 😉.
In 2016 with Windows 10 “Threshold 2” Microsoft unexpectedly started supporting ANSI escape sequences
The exact details of how ANSI escape codes work will not be covered here. There is an excellent Wikipedia article on that here: https://en.wikipedia.org/wiki/ANSI_escape_code
More examples for inspiration before we code
Before we go ahead and hack this out, I wanted to share more awesome examples:
Another one from Igor Chubin . This one even has charts 😲. That’s just crazy!!
This one is from Hugo. This has an animated party parrot !!
How cool is that !!!
This one I built for last day at my previous job. Wanted to say goodbye in style 😉
There are more examples listed at: https://github.com/chubin/awesome-console-services
Why will anyone build these ?
- So one interesting thing you will notice is that when you hit
wttr.inusing a browser, you get a simple HTML & CSS based web page. But when you hit it using
wgetyou will get an ANSI coded text as the response. So, now you can target terminal users (devs) directly. For example, devs can now view an online documentation that is color-coded and syntax highlighted directly on their terminals without opening a web page on a separate browser.
- Curiosity 😬; Don’t know about you, but these demos were convincing enough for me to try building this using NodeJS.
The complete source code can be found here: https://github.com/master-atul/console-web-ui
First step: Simple hello world
Since this is a web API, I would be using express.js to build a simple API server using nodejs. Follow the guide here: https://expressjs.com/en/starter/hello-world.html to make a simple express js API server.
node app.js to launch the server.
In another terminal type:
curl localhost:3000. You should see :
There, hello world is ready 😆
Next step: Add colors to the text
As mentioned before, we need ANSI codes for the colored output to the screen. Fortunately, there is a really nice
npm module for that. https://github.com/chalk/ansi-styles
Let’s see what hello world in color looks like.
You should get the following output on
What about animations ?
Animations are a continuous sequence of frames that give an impression that something is moving. To achieve that we need to send multiple frames to the client side and clear out the old frame before showing the next.
- To send multiple frames of data to the client side we will use
- To clear out screen before displaying next frame we can use a special ANSI code
Let’s say we want to show the current server time on the console that changes with every second. So our output would look like this:
The code looks like this:
What if same route can be used for both browser and terminal ?
Ideally, if we hit a URL on a browser we should get the HTML and CSS response, while if we hit it from curl or terminal we should get the response in the text format that terminal understands.
What do I mean ?
Okay try opening
wttr.in on the browser — You should see HTML, CSS based website loading up. Now try
curl wttr.in , the same URL now returns text-based output that the terminal can understand.
To do this in expressjs. We will use the concept of
Now when you run
⬅ You get this
If you open up the link in your browser, you ‘ll get the HTML page you made.
This example is hosted on heroku at https://console-web-ui.herokuapp.com/
All the code for this blog is at :
I hope this was fun 😬🎉