Add Emoji to your Node Projects with node-emoji ✨

Node emoji

Attention ๐Ÿ“ฃ Node developers. We're building highly functional applications, but it's time to add some pizzazz and breathe new life into our software creations. In this article, we'll learn how to sprinkle in some emoji to add sparkleโœจ to our Node projects with the help of the node-emoji package. We'll culminate our efforts with the creation of a command-line emoji picker that we can use in a variety of contexts.

Article contents

Prepare computing environment

For this article, we'll be building Node.js console applications to display emoji in the terminal so we want to make sure we're ready to handle that.

Linux

For Linux, I tested with Ubuntu 18.10 and emoji can be displayed in the terminal right out of the box using the default GNOME terminal.

I also tested with Lubuntu and the default terminal (LXTerminal) does not currently support emoji. For Lubuntu, I installed gnome-terminal and added the emojione font to make it work:

$ sudo apt install gnome-terminal
$ sudo apt install fonts-emojione

macOS

The macOS terminal supports emoji out of the box.๐Ÿ‘

Windows

The Windows console does not currently support Unicode and thus we cannot render emoji characters in the console โ˜น๏ธ. This is also true for WSL (Windows Subsystem for Linux) which is also hampered by this limitation. Microsoft is in the process of providing Unicode support in the Windows console, but it did not work at the time of this writing for mainstream Windows builds.

Nonetheless, Windows users - have no fear! The emoji picker console application we'll be building later in this tutorial will write the results directly to the clipboard so you can paste and view your emoji in Windows GUI applicationsโ€”even though the emoji characters will be unintelligible in the console.

Display our first emojis on the console

Let's start displaying some emoji! We'll be using the popular node-emoji npm package to help us achieve our goals. Here we go!

First, we'll create a project directory and navigate into it:

$ mkdir emoji && cd emoji

Next, we'll create a blank package.json file and automatically acceptย all the defaults without being prompted:

$ npm init -y

Let's install the node-emoji package and save it as a dependency in the package.json file:

$ npm install --save node-emoji

Create a file called index.js and add the following contents:

const emoji = require('node-emoji');

const { log } = console;

const pizza = emoji.get('pizza');
log(pizza);

In the code above, we use the emoji.get function to supply an emoji code and return the corresponding Unicode emoji symbol. Here is a list of available emoji codes we'll be using as a reference during this tutorial. There is also this Emoji cheat sheet with the codes that enables you to copy emojis right into your clipboard. This is very handy, but we're building our own more powerful tool using Node in this tutorial. We're developers and we'd like to make it ourselves to learn something and have fun.๐Ÿ˜Ž

Finally, run the command and verify it works:

$ node index.js
๐Ÿ•

You should see a pizza in your console! Seeing the pepperoni on the pizza is making me hungryโ€”or are those tomato slices?

Emojify all the texts

Let's expand our humble emoji program and intermingle our emoji with other text. Here's our first iteration:

const emoji = require('node-emoji');

const { log } = console;

const pizza = emoji.get('pizza');
const message = `It's time for ${pizza}!`;
log(message);

Let's run it again:

$ node index.js
It's time for ๐Ÿ•!

Looking good!

As shown next, we can use the emojify function to embed the emoji codes in our text. Notice that we are now using colons on each side of the emoji code. The colons are considered to be part of the emoji code and the emoji.get function we used previously allowed the colons to be omitted.

const emoji = require('node-emoji');

const { log } = console;

const message = 'I like :tomato: sauce on my :pizza:.';
const emojiMessage = emoji.emojify(message);

log(emojiMessage);

Let's see it in action:

$ node index.js
I like ๐Ÿ… sauce on my ๐Ÿ•.

We're making progress...

Next, let's build a simple Node CLI (command-line interface) application to make our code even more useful.

First, create a file called emoji.js:

#!/usr/bin/env node

const emoji = require('node-emoji');

const { log } = console;

if (process.argv.length <= 2) {
  log(`Usage: ${__filename} emoji_text`);
  process.exit(-1);
}

const result = emoji.emojify(process.argv[2]);

log(result);

The first line of our program is the shebang (also known as the "bang line") which enables our operating system to know what interpreter to use for executing our script.

We provide the user with usage help if an argument is not supplied containing the text to emojify.

Since we included the shebang syntax, we can new execute the file directly without specifying "node" in the front of the script file.

$ ./emoji.js "The :pizza: is here :tada:!"
The ๐Ÿ• is here ๐ŸŽ‰!

It works! Please note that we must wrap the text to emojify in double quotes. Try it without quotes and you will see that only the first word "The" is passed as a parameter to our script.

Let's modify our code so we don't need to wrap the text to emojify in double quotes:

#!/usr/bin/env node

const emoji = require('node-emoji');

const { log } = console;

if (process.argv.length <= 2) {
  log(`Usage: ${__filename} emoji_text`);
  process.exit(-1);
}

const [, , ...args] = process.argv;
const message = args.join(' ');
const result = emoji.emojify(message);

log(result);

The command-line interpreter considers all values separated by spaces to be individual arguments. We use the rest parameter syntax ...args (in conjunction with array destructuring) to enable all arguments we supply to be stored in an array called args.

const [, , ...args] = process.argv;

The first two commas enables us to ignore and throw away the first two elements of the process.argv to array. We could have also done this:

const [bin, sourcePath, ...args] = process.argv;

Since we have no need for the bin and sourcePath variables retrieved in the array destructuring, we can simply omit the variable names to make our code cleaner.

We then join the elements in the args array back together to create a single string that can be emojified.

const message = args.join(' ');

Now, let's invoke the command again without wrapping our text to emojify in double quotes:

$ ./emoji.js The :pizza: is here :tada:!
The ๐Ÿ• is here ๐ŸŽ‰!

Excellent - we no longer need to be burdened with the psychic weight of remembering those double quotes.

Save emoji text to the clipboard

If we're running macOS or Linux, we can save our text to the clipboard.

macOS

In macOS, it is very simple, and we can use the built-in pbcopy command:

$ ./emoji.js The :pizza: is here :tada:! | pbcopy

Paste the results from the clipboard into another application to verify it works.

Linux

In Linux (Ubuntu and derivatives), we can accomplish the goal by building our own pbcopy command. We'll follow the steps from Gary Woodfine's helpful Use pbcopy on Ubuntu article.

First, we'll check and see if xclip is installed:

$ which xclip

If xclip is not there, install it:

$ sudo apt install xclip

Create or open the ~/.bash_aliases file using nano or text editor of choice:

$ nano ~/.bash_aliases

...and add the following lines:

alias pbcopy='xclip -selection clipboard'
alias pbpaste='xclip -selection clipboard -o'

We include the pbpaste command which you might find useful too, even though we don't need it for this tutorial.

Use the source command to read the updated contents of your .bashrc file, eliminating the need to have to log out and log back in to activate your changes:

$ source ~/.bash_aliases

Use your newly created pbcopy alias to copy from STDOUT in the script to the clipboard.

$ ./emoji.js The :pizza: is here :tada:! | pbcopy
The ๐Ÿ• is here ๐ŸŽ‰!

Paste the results from the clipboard into another application to verify it works. For example, the Ubuntu "Text Editor" application. As a side note, it does not appear that LibreOffice Writer supports emoji at the time of the writing of this article since the paste from the clipboard did not yield any emoji.

Windows

Unfortunately, we're out of luck here until Microsoft provides support for Unicode in the Windows console. When they do, this command will work since the Windows clip command works in a similar fashion to pbcopy to save STDOUT streams to the clipboard:

$ ./emoji.js The :pizza: is here :tada:! | clip

As I mentioned previously, we have a way to copy to the Windows clipboard which will be described later in this article so stay tuned ๐Ÿ“บ.

Expand our console app to read from STDIN

Let's expand our console application (emoji.js) to read from STDIN to provide more flexibility so we don't have to supply a giant parameter containing all the text to emojify. This will also enable us to easily handle vertical spacing.

We use the built-in Node readline module to listen for lines streaming in through STDIN:

#!/usr/bin/env node

const readline = require('readline');
const emoji = require('node-emoji');

const { log } = console;

if (process.stdin.isTTY || process.env.STDIN === '0') {
  if (process.argv.length <= 2) {
    log(`Usage: ${__filename} emoji_text`);
    process.exit(-1);
  }
  const [, , ...args] = process.argv;

  const message = args.join(' ');

  const result = emoji.emojify(message);
  log(result);
} else {
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    terminal: false
  });

  rl.on('line', line => {
    const result = emoji.emojify(line);
    log(result);
  });
}

Next, let's create a file called message.txt containing our text to emojify:

Weather Forecast
   Today: :partly_sunny:
Tomorrow: :sunny: (good day for :running:)

Finally, let's feed message.txt through and see how it works:

$ cat message.txt | ./emoji.js
Weather Forecast
   Today: โ›…๏ธ
Tomorrow: โ˜€๏ธ (good day for ๐Ÿƒ)

It works, and we have a lot more flexibility in terms of formatting!

Create command-line emoji picker

As a final exercise, let's create a general-purpose emoji picker that we can use to select that perfect emoji for any occasion.

We'll use the node-emoji search function to enable us to supply the first letters of a given emoji code and find all the matches.

Create a new file called emoji-picker.js and add the following code:

#!/usr/bin/env node

const emoji = require('node-emoji');

const { log } = console;

if (process.argv.length <= 2) {
  log(`Usage: ${__filename} emoji_text`);
  process.exit(-1);
}

const result = emoji.search(process.argv[2]);

result.forEach(item => {
  log(`${item.emoji}  ${item.key}`);
});

We supply a substring of characters on the command line and the search function will return all the matching characters. Let's see it in action by showing all emojis that start with "smile":

$ ./emoji-picker.js smile
๐Ÿ˜ƒ  smiley
๐Ÿ˜„  smile
๐Ÿ˜ธ  smile_cat
๐Ÿ˜บ  smiley_cat

How about that? We even see smiling cats! This command is going to be very useful.

This is a good start, but we want to select an emoji from the list retrieved and save it to the clipboard. To accomplish these goals, we'll install a couple of additional npm modules.

First, we'll install the incredibly useful inquirer module to make our command-line interface more interactive and select the emoji of choice:

$ npm install --save inquirer

Next, we'll install the excellent clipboardy module which will enable us to write to the clipboard in a cross-platform fashion. This will also empower us to overcome the lack of emoji support in the Windows console to save our emojis to the clipboard and paste elsewhere.

$ npm install --save clipboardy

Modify the emoji-picker.js file you created above with the following contents:

#!/usr/bin/env node

const inquirer = require('inquirer');
const clipboardy = require('clipboardy');
const emoji = require('node-emoji');

const { log } = console;

function addToClipboard(emojiText) {
  const [emojiChar, emojiName] = emojiText.split(' ');
  clipboardy.writeSync(emojiChar);
  const emojiNameText = emojiName ? ` (${emojiName})` : '';
  log(`${emojiChar}${emojiNameText} copied to clipboard`);
}

if (process.argv.length <= 2) {
  log(`Usage: ${__filename} emoji_text`);
  process.exit(-1);
}

const result = emoji.search(process.argv[2]);

if (result.length > 0) {
  if (result.length === 1) {
    addToClipboard(result[0].emoji);
  } else {
    const choices = [];
    result.forEach(item => {
      choices.push(`${item.emoji} ${item.key}`);
    });

    const questions = [
      {
        message: 'Select an emoji',
        type: 'rawlist',
        name: 'emoji',
        choices
      }
    ];

    inquirer.prompt(questions).then(answers => {
      addToClipboard(answers.emoji);
    });
  }
}

We use inquirer's powerful capabilities to prompt the user to select their emoji of choice based on the list of emojis returned from the emoji.search function.

Let's give it a try and find all emoji codes that start with "wat":

$ ./emoji-picker.js wat
? Select an emoji 
  1) โŒš๏ธ watch
  2) ๐Ÿ‰ watermelon
  3) ๐Ÿƒ water_buffalo
  Answer: 

We select a number, hit return, and the emoji is stored in our clipboard, ready to be pasted. How awesome is that? (We can also use our up/down arrow keys to select an option and hit the Enter key.)

If all the results can't fit on the screen, inquirer elegantly enables us to arrow down beyond the list currently displayed and select the emoji of choice. Let's push this to the limit and retrieve all emojis that start with "a"

$ ./emoji-picker.js a
? Select an emoji 
  1) โ†•๏ธ arrow_up_down
  2) โ†–๏ธ arrow_upper_left
  3) โ†—๏ธ arrow_upper_right
  4) โ†˜๏ธ arrow_lower_right
  5) โ†™๏ธ arrow_lower_left
  6) โ™ˆ๏ธ aries
(Move up and down to reveal more choices)
  Answer: 

We use our down arrow key to scroll down through the choices and hit the Enter key when we find our emoji of choice. Inquirer is amazing for creating interactive command-line interfaces!

Make emoji picker universally available on our system

We can make our emoji-picker.js available to be invoked from any directory on our system in a couple of ways.

Option 1 - place a script in our system path

We first need to find where our operating system looks for scripts and executable programs, so we know where our programs need to reside:

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

We see several directories including /usr/local/bin which we'll use in this context. (We could also add another directory to our path, but /usr/local/bin will suffice here.)

Create a bash script in the /usr/local/bin directory to launch the emoji-picker.js script. We use sudo to elevate our privileges to create file in that location.

$ nano /usr/local/bin/emoji-picker

Add these contents and update the cd ~/scripts command to reflect the directory containing your emoji-picker.js script:

#!/bin/bash

cd ~/scripts

./emoji-picker.js $@

Change the directory to a random location to confirm you can run the emoji-picker from anywhere on your system. Let's look for emojis that start with "cat"

$ emoji-picker cat
? Select an emoji 
  1) ๐Ÿˆ cat2
  2) ๐Ÿฑ cat
  Answer: 

It's working and ready for us to choose a cat emoji!

Option 2 - build CLI application using npm

As a second option, we can create a Node command-line application using npm. Let's add a bin property in our package.json file. Please note that my file may look slightly different since the version numbers for my dependencies may be different. You're better off grafting in the bin property rather than copying/pasting all the contents below into your package.json file.

{
  "name": "emoji",
  "version": "0.1.0",
  "description": "Emoji picker",
  "bin": {
    "emoji-picker": "emoji-picker.js"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "clipboardy": "^1.2.3",
    "inquirer": "^6.2.2",
    "node-emoji": "^1.8.1"
  }
}

You may also notice that I removed the default main property since it is not needed for building npm CLI programs.

Let's take a closer look at the bin property:

  "bin": {
    "emoji-picker": "emoji-picker.js"
  },

This line will ultimately create a file called emoji-picker that invokes the emoji-picker.js script.

Finally, we can create an executable that is available anywhere on our system using the npm link command:

$ sudo npm link

Let's give our command a try:

$ emoji-picker dog
? Select an emoji 
  1) ๐Ÿ• dog2
  2) ๐Ÿถ dog
  Answer: dave@ubuntu2:~$ 

Bingo! (was his name-O ๐Ÿ˜‰) Our script is working and ready for us to select a dog emoji to copy to our clipboard.

What magic happened behind the scenes with the npm link command? Let's see where it resides:

$ which emoji-picker
/usr/bin/emoji-picker

Ah, it resides in the /usr/bin directory. Let's dig deeper and see more details:

$ ls -la /usr/bin/emoji-picker
lrwxrwxrwx 1 root root 34 Feb 15 07:49 /usr/bin/emoji-picker -> ../lib/node_modules/emoji/emoji-picker.js

Our Emoji Picker is symbolically linked to our script which was coped into the /usr/lib/modules/emoji folder when the npm link command was invoked.

Very good - our emoji-picker is fully complete and ready for use!

Miscellaneous tips

Our emoji picker works with Windows, but we are not able to see the emoji Unicode characters through the Windows console. Fortunately, the emoji will copy into the Windows clipboard and be available to paste into other Windows programs beyond the console. To see the emoji from Windows, you could create an Ubuntu virtual machine, for example, using VirtualBox and use the shared clipboard feature to pick the emojis from Ubuntu and paste into Windows. That would probably be more work than it's worth, but where there's a will, there's a way.

Recent versions of Windows 10 include an Emoji Picker that can be invoked from the WIN+; or WIN+. keyboard combination as described here. This is not as fun as creating our own, but it is highly functional and includes the ability to search for emoji.

If you are writing Markdown using VS Code, I highly recommend the :emojisense: extension. See my Build an Amazing Markdown Editor Using Visual Studio Code and Pandoc article for additional Markdown extensions and helps.

Conclusion

We learned how to sprinkle in some emoji and add sparkleโœจ to our Node projects with the help of the node-emoji package. We also created a command-line emoji picker that we can use in a variety of contexts. Hopefully you had fun and learned something new along the way!

Follow @thisDaveJ (Dave Johnson) on Twitter to stay up to date with the latest tutorials and tech articles.

Additional articles

Guide to Installing Node.js on a Raspberry Pi
Making Interactive Node.js Console Apps That Listen for Keypress Events
How to Watch for Files Changes in Node.js
How to Count Unique Items in JavaScript Arrays

Last updated Feb 19 2019

Share

6 thoughts on “Add Emoji to your Node Projects with node-emoji ✨

Leave a Reply

Your email address will not be published. Required fields are marked *