Introducing hevi: a hex viewer
zig July 04, 2024Almost a year ago, I started writing hevi. Today, hevi 1.0.0 was released. Following the release, I decided I would write a blog post about it. I'll address the following:
Why do we need another tool like
xxd
orhexdump
?What makes a tool good?
Why is
hevi
the best tool available?
Why another tool
xxd
, hexdump
, hexyl
... There's a lot of tools like hevi
out there. However, I feel like none of them is good enough. Most of them either are really old pieces of software or don't offer many essential features.
For instance, xxd
(bundled with vim
) and hexdump
are really old and primitive tools. Sure, they get the job done most of the times, but they're not pleasant to use by any means (obscure flags, long manpages...). hexyl
on the other hand is a modern hex viewer... that offers little to no features.
I won't talk about GUI tools, as I think those are in a completely different context.
Bringing a new tool to the ecosystem is often viewed as a bad idea. But when all the other alternatives don't cut it, creating a new one does make sense.
What makes a tool good?
We've just decided that we need a new hex viewer. What do we do now? Start writing a tool that will be as bad as the ones that are already out there? No. We think frist.
Semantic flags
For a CLI program, the main way the user will interact with it is, well, the CLI. If a program has obscure flags that the user has to remember, it can be very harmful to the entire experiece. hevi
does not have single-character flags. The only exceptions are -h
and -v
, which are well-known and widespread (but even those have semantic alternatives, --help
and --version
).
Sure, we could add shorthards for certain flags (e.g. -c
for --color
), but that would only encourage bad habits. By not having those, we push users towards a more semantic usage.
If your program needs to have single-character flags in order to provide a concise and short CLI usage, maybe you've got another problem...
Defaults
I like the ASCII interpretation of the bytes. But some people don't. Do all those people have to type --no-ascii
every single time they want to use the tool? Of course not. We want to create a versatile tool, that can suit the needs of as much users as possible. Having a way to override the defaults is the way to go.
hevi
archives this by allowing the user to create a config file. In it, the user can decide if they want to have ASCII or not by default. They can still use --ascii
and --no-ascii
, but it will default to what the user likes, not to what the developer wants.
Having config files doesn't seem like a big deal, but many programs do it in a very bad way, having little to no connection to the flags.
Diagnostics
If the user has an invalid config or passes an invalid flag, we need to report it properly. We shouldn't say "error: invalid config" and exit. Having good diagnostics, specially for the config file, is an essential piece that makes for a good tool.
Features the user wants
Ideally, the tool should support every single feature the user wants, but not many unwanted ones. We don't want the user to feel like the tool is bloated.
For example, if you're dumping the contents of an ELF file, you're probably interested in its structure. hevi
can parse ELF files and give the user a syntax-highlighted dump. It is an optional feature, and does not affect the executable size significantly.
Modularity
A tool as generic as a hex viewer should be modular, and maybe even export some kind of module or library. hevi
does this in an elegant way, exporting a zig module that makes it extremely easy to integrate with your zig application.
Here comes hevi
hevi
meets all the criteria we described.
Now, what is hevi?
hevi is a modern, modular and minimalistic hex viewer.
That's exactly what it is. Just look at it, and its simple usage:
One of the most remarkable features are the parsers. I've mentioned them briefly before, but here's an example. Just picture this. You're inspecting a Windows executable. Let's use xxd
first. You write xxd foo.exe | less
. You get this:
What a mess! Oh, wait, let's add the -R always
flag (which obviously stands for colorize).
Still, not great. Now let's use hevi
instead of xxd
:
You can easily see the headers, the sections it contains... You can even pretend like the executable doesn't contain a DOS stub for back-compatibility by just ignoring the brown blob!
Nice.
Well, that's pretty much everything I wanted to say. If you want to check it out, you can do so on github.