CLI tool
arp242/uni avatar
arp242/uni

uni: querying the Unicode database from a terminal

Query the Unicode database from the commandline, with good support for emojis

867 stars26 forksGoMIT

At a glance

What is it?
uni is a Go command line tool that queries the Unicode database, with four commands for identifying characters, searching by name, printing groups of codepoints and finding emojis. Its most useful feature is a format string that turns the output into whatever shape you need, including X11 keysym mappings for a Vim plugin.
Who is it for?
Adopt uni if you work with text encodings, need to look up a character you have seen, or want to build a launcher entry for an unusual symbol, because it answers the questions that a web search answers badly, and its format string means the output can be shaped for a script instead of a screen.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 36 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Four commands and a single Go binary

uni queries the Unicode database from the commandline, and it supports Unicode 15.1 from September 2023 with good support for emojis. The whole tool is four commands: identify codepoints in a string, search for codepoints, print codepoints by class, block or range, and emoji to find emojis.

That is a small surface, and it is small on purpose. There is no configuration file, no database to maintain and no daemon. The Go module is zgo.at/uni/v2 and it requires Go 1.24, with three direct dependencies from the same author's namespace, runewidth, termtext and zli, plus zstd, and one indirect dependency on the rivo/uniseg line segmentation library.

Those dependencies explain a design decision visible in the output. The tool aligns columns of wide characters correctly, and the README even warns that the alignment is slightly off in the GitHub rendering because of how wide characters are displayed there, and that in terminals it should be aligned correctly. Handling that needs width-aware measurement rather than counting runes, which is what runewidth and uniseg are for. A Unicode lookup tool that misaligned its output in a CJK locale would be annoying in a way that is hard to notice.

The releases are on the releases page, with packages for a number of platforms listed through repology, and the README notes you can also run it in your browser through a WebAssembly build. The current release is v2.10.0 from 2026-09-17, after v2.9.0 in December 2025 and v2.8.0 in September 2024, and the last push to the repository was on 2026-09-17. The licence is MIT.

identify is a unicode-aware hexdump

The identify command is the one people reach for first, and the README describes it as a kind of a unicode-aware hexdump. You give it a string and it tells you what is in it:

code
% uni identify €
             Dec    UTF8        HTML       Name
'€'  U+20AC  8364   e2 82 ac    €     EURO SIGN

The columns are the decimal codepoint, the UTF-8 bytes, the HTML entity and the Unicode name, and the character itself is quoted in the first column so that trailing spaces and other invisible characters are visible. The Unicode name is followed by aliases in brackets when the character has any, which is the detail that makes the output a proper reference rather than a label.

There is a shortcut, i is for identify, and it reads from stdin as well, so you can pipe a file through it:

code
% head -c5 README.md | uni i
      CPoint  Dec    UTF8        HTML       Name
'`'  U+0060  96     60          `    GRAVE ACCENT [backtick, backquote]

The first column is labelled CPoint when the input is read from stdin and shows the character rather than a CPoint value, and the Dec column carries the decimal number. The same command also accepts codepoints on input, so you can feed it U+1234 or U+1111 and get the characters back, which is the inverse operation and the one you want when you have a number and need to see the glyph.

Two flags shape the output. -compact, or -c, suppresses the header, and -format, or -f, controls the format string, which is covered in its own section.

search matches names, and quoting decides AND from phrase

The search command looks up codepoints by their description, and the results show why the name index is more useful than it sounds. A search for euro returns the euro sign, the euro currency sign, two Palmyrene fleurons, the Manichaean punctuation fleuron, the earth globe, the European post office, the European castle and the banknote with euro sign.

The two fleurons and the Manichaean punctuation mark are the interesting part. They match because their names contain the word FLEURON and the search is a substring match, not a word match, and if you were looking for the fleuron that means a flower-shaped ornament, you would not find it. That is the behaviour of a name search, and it is worth knowing before you conclude the database is wrong.

Multiple words are matched individually, so a search for globe earth returns the three earth globes. If you want the literal phrase, you quote it in the shell, and the README shows the difference: an unquoted rightwards black arrow returns the black rightwards arrow, the black rightwards arrowhead and others, while the quoted version returns only the one whose name is exactly rightwards black arrow.

And -or, or -o, switches the combination from AND to OR, which is what you want when you are browsing rather than narrowing. A search for globe milky with -o returns the milky way, the earth globes and the globe with meridians.

The s command is a shortcut for search, in the same spirit as i for identify.

print covers codepoints, ranges, categories and blocks

The print command covers the group-selection cases, and the flexibility here is in how you specify a group.

You can print a single codepoint, uni print U+2042, and you can print a range, uni print 2042..2044. The three ways of writing a codepoint are explicitly equivalent, with U+2042, U2042 and 2042 all identical, and you can also use hex, octal and binary numbers with the 0x, 0o and 0b prefixes.

Beyond that, two kinds of group. A general category, where uni p Po prints every character in the Other_Punctuation category and announces what it is showing. And blocks, where uni p arrows 'box drawing' prints the Arrows block and the Box Drawing block, announcing each. As with search, a phrase in quotes is the way to pass a multi-word block name.

The output can be rendered differently, with an -as table option and a shorter name variant, and the README's last visible example is truncated mid-sentence on that option, so the exact rendering is something to check in uni help rather than in the documentation.

The emoji command, the fourth one, exists to find emojis, and the tool's stated good support for emojis is what separates it from a generic lookup.

The format string is the real interface

The -f flag is where uni stops being a display command and becomes a tool you can build on, and the README spends more space on it than on any single command.

A format string selects fields and lays them out:

code
% uni i -f '%unicode %name' a€🧟
Unicode Name
1.1     LATIN SMALL LETTER A
2.1     EURO SIGN
10.0    ZOMBIE

The %unicode field is the Unicode version in which a character was assigned, so the same output tells you that the euro sign dates from Unicode 2.1 and the zombie emoji from 10.0. That is a quietly valuable piece of information, because it tells you how old a character is and therefore whether an old toolchain can handle it.

If the format string starts with a plus sign, the character, the codepoint and the name are prepended automatically, which saves writing the same three fields in every query:

code
% uni i -f +%unicode a€🧟
         Name                 Unicode
'a'  U+0061  LATIN SMALL LETTER A 1.1
'€'  U+20AC  EURO SIGN            2.1

The advanced part is %(name flags). A field can carry flags that control how it is rendered, and the README's example builds an aligned codepoint to X11 keysym mapping, which is the kind of output a launcher script or a keybinding tool needs:

code
% uni i -c -f '0x%(hex l:auto f:0): %(keysym l:auto q:":",) // %name' h€ý
0x6800: "h",        // LATIN SMALL LETTER H
0x20ac: "EuroSign", // EURO SIGN
0xfd00: "yacute",   // LATIN SMALL LETTER Y WITH ACUTE

Reading the flags: l:auto means the column is padded automatically for alignment, f:0 fixes the hex formatting to no leading zeros, and q:":", wraps the value in double quotes with a trailing comma. uni help documents the format flag in full, and the README notes that this flag can be added to the other commands, not just identify.

The fact that a keysym mapping can be produced at all is why the tool ships a Vim integration.

Integrations with dmenu, rofi, fzf and Vim

The README lists the integrations separately from the usage, and they show what the tool is for in practice.

There is a dmenu-uni script, described as a dmenu, rofi and fzf script, with a note to look at the top of the script for options you may want to change. That combination is the familiar one: dmenu and rofi are launchers, fzf is a fuzzy finder, and all three can present a list of characters and act on the one you pick. The tool's job there is to turn a name into the character, and the format string is what makes the list readable.

For Vim there is uni.vim, and the instruction is simply to copy and paste it into your vimrc. A Vim command that inserts a character by name is the kind of thing that gets used every day by anyone writing text with unusual symbols, and it is also the reason the keysym example above exists, since a keysym is what a keyboard layout and a windowing system both speak.

There is also the WebAssembly build, which the README links as running it in your browser, and the repository has a wasm/ directory for it. The wasm/ entry sits next to uni.go, format.go, gen.go, the unidata/ directory, uni_test.go, staticcheck.conf and the .readme.gotxt file, and that listing is itself informative. A generator and a data directory suggest the Unicode tables are produced from the upstream data files rather than typed in by hand, a formatter alongside a format-heavy command suggests the column layout is code rather than hardcoded strings, and the readme file with a .gotxt extension suggests the README is itself generated or at least maintained in a form that a Go program can process.

The CHANGELOG.md and CONTRIBUTING.md files are the other two entries that matter for a tool people install system-wide.

The limit that matters: which Unicode version you get

The README states that uni supports Unicode 15.1 from September 2023. That is the single most important fact for anyone planning to depend on it, and it is worth being explicit about the consequence.

A Unicode version fixes the set of assigned codepoints, the names, and the properties. The tool's own output shows the version in which each character was assigned, with the euro sign at 2.1 and the zombie emoji at 10.0, and characters added in versions after 15.1 will not be in the database at all. For most work, that is invisible, because the characters people actually need in menus, logs and identifiers are old ones. For a tool that is supposed to have good emoji support, it means the newest emoji of 2024, 2025 and 2026 are missing, and the newest of those are the ones people notice.

There is no statement in the README about the upgrade path for the Unicode data, but the repository's structure implies one. A unidata/ directory holds the upstream data, a generator produces the Go tables from it, and the CHANGELOG.md records what changed between releases. The v2.8.0 to v2.10.0 releases in the listing span September 2024 to September 2026, and the v2 major version line has been stable across them, so a data refresh is a release rather than an API change.

Two smaller practical points. The packages listed through repology mean you are likely to get the distribution's build, which may lag the tagged release, so checking the installed version against the tagged release is the thing to do. And the tool is a single Go binary with no runtime dependencies, so installing it is a matter of dropping a file in your PATH, which is either the easiest install in the article or the reason your distribution package is old.

Editorial conclusion

Adopt uni if you work with text encodings, need to look up a character you have seen, or want to build a launcher entry for an unusual symbol, because it answers the questions that a web search answers badly, and its format string means the output can be shaped for a script instead of a screen. Do not adopt it as a source of truth on current Unicode data, because the README states it supports Unicode 15.1 from September 2023, which is behind the versions since added, and check the version before you rely on a newly assigned character being present. Before you use it, run uni help on the format flag, because the %(name flags) syntax with its alignment and quoting options is where the real capability sits, and if you depend on emoji coverage, verify the specific emoji you need against the version you have installed.

Frequently asked questions

How do I install uni?

There are binaries on the releases page and packages for a number of platforms through repology, and you can also run it in your browser through the WebAssembly build. Compiling from source is a single command, go install zgo.at/uni/v2@latest, which puts a uni binary in ~/go/bin.

Which Unicode version does uni support?

The README states that uni supports Unicode 15.1, released in September 2023. Characters assigned in later Unicode versions are therefore not in its database, which matters most for recently added emoji.

How do I search for a character by name in uni?

Use the search command, or its shortcut s. Multiple words are matched individually, so uni s globe earth returns the earth globes, and quoting a phrase in the shell makes the match literal. The -or flag combines the terms with OR instead of AND.

What is the -format flag in uni used for?

It controls the output layout, with fields such as %unicode and %name, and a leading plus sign to prepend the character, codepoint and name automatically. Fields can carry flags in the form %(name flags), and the README shows an example that produces an aligned codepoint to X11 keysym mapping. uni help documents it in detail.

Official sources

  1. arp242/uni on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/arp242-uni.svg)](https://hysenlabs.com/projects/arp242-uni)

Was this useful?