Building a Terminal Wordle Game with React Ink

Terminal user interfaces (UIs) are great: they’re fast, they sip system resources, and you can use them over SSH. The good ones even adapt nicely as you resize the window (like htop or vim).

The low-level way to build one is with ANSI escape codes, manipulating the position of the cursor while printing text. If you’ve ever tried to do this, you may have had a bad time full of flashing text, off-by-one errors, and errant text wrapping. Or maybe that’s just me.

So I know that I’d be better off with a higher-level library to handle the hard parts for me. I’ve been meaning to try one but only recently had an idea of something to build: Terminal Wordle.

Choosing a Library to Write Terminal Wordle

The Wordle craze may be mostly over by now, but I’m still playing. I love the story of it: it’s origin, all the spinoffs it inspired, and that it was wildly successful without ads or gems or desperation for user engagement.

I also appreciate how approachable it is mechanically. Puzzle games often lead me to idly ponder how I might design a solver or even reimplement the game. But this one is so simple that it’s a pretty low bar to do either! So I decided to write my own Terminal Wordle. But which library should I try?

There are a bunch of Terminal UI libraries out there, going way back to the venerable ncurses. But one that I’ve been curious about is Ink, which is a React backend! So you can build Terminal UI apps using the same patterns as web apps.

Highlights

With a goal in mind and a library in hand, I got to work. After the novelty of writing .tsx for a terminal app wore off, several parts of the Ink experience struck me as particularly valuable. What follows are a few of them.

Layout

Ink uses flexbox layout:

Hooks

Ink provides several React hooks. There’s one to receive keyboard input, and another to exit the app:


  const { exit } = useApp();
  useInput((input, key) => {
    if (key.escape) {
      exit();
    }
  }

When I wanted to get the terminal dimensions, there’s one for that too.

And React’s familiar useReducer was a perfect fit for managing the state in an input-driven game like Wordle.

Components

Just as in React Web or React Native, there are third-party components you can easily integrate into an Ink app.

React Dev Tools

You can use them!

Building a Terminal Wordle Game with React Ink

This was great for debugging what’s going on halfway through the game. It’s not quite the same as right-clicking on DOM elements, but it’s way better than Console.log (which isn’t available if you’ve taken over the whole terminal window).

Results

I’m impressed with this library. If you have any experience with React, then Ink offers a really short ramp to building slick terminal UIs. I managed to get the game working pretty quickly, and it feels much better with a terminal UI than it would with a conventional scrolling interactive prompt.

I wish Ink supported Deno, but it looks like that may happen eventually.

If you’re itching to play Wordle in a terminal, then I’d first point you to clidle, which is way better than mine. You can also play over anonymous SSH! But if you’d like to see how Terminal Wordle can be built in React with Ink, my app’s code is available on GitHub at jrr/inkle.