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
Thanks. This was very cute and informative.
Gooooood tutorial.
Thanks from Spain….