DEV Community

Cover image for Tech Talk: React in the Terminal? Hold my Beer 🍺
Manuel Artero Anguita 🟨
Manuel Artero Anguita 🟨

Posted on

24 3 3 1 3

Tech Talk: React in the Terminal? Hold my Beer 🍺

My company organizes a big event once per year. Around ~600 attendees. There are five simultaneous tracks for keynotes; Product, Project management, Design, Dev, Devops... It's the main event of the season for us.

You get the idea.


This year i decided to present a tech talk. 45 min long. The complete thing: slides & live coding.

I named it: «React in the Terminal? Hold my beer 🍺»


While the slides are in English, i'm afraid the talk itself was in my mother language (πŸ‡ͺπŸ‡Έ) and i won't share the recording.

However, here are the resources I used for the talk:

  1. The slides: up & running hosted at Vercel; I used SliDev, a framework that turns markdown into a web app which behaves like a Keynote. It's pretty cool.
    I genuinely think SliDev deserves its own post someday πŸ€”.

  2. my-react-dom: Repository with a custom implementation of react-dom used to live coding. Two branches: playground and main

  3. ink-world: Repository for a tiny-tiny-tiny game using Ink + React on the terminal again, used to live coding. Two branches: playground and main.


Talk Recap

I led a quick journey, starting with the simplest Β«Hello WorldΒ» in React...

...But unrolling the jsx syntax, making more obvious where we're invoking react and where we are calling react-dom

Slide no 7

This led us to the question: why are react and react-dom separated into two different packages?

We discussed the philosophy that React embraces; they mention "interfaces" and how React is designed to plug into any interface.

Slide no. 8

Next step: react-reconciler: the package the React team provides to create your custom renderer.

Slide no. 9

Time to live coding session (my-react-dom)

This is the goal: replace the ReactDOM object with one of our own and keeping the Counter APP running.

import React from 'react';
-import ReactDOM from 'react-dom';
+import ReactDOM from './my-custom-react-dom';
import './styles.css';
Enter fullscreen mode Exit fullscreen mode

✨ Ah! and that's also deployed at Vercel: https://my-react-hvpqtmgva-manu-artero.vercel.app/

Screenshot for https://my-react-hvpqtmgva-manu-artero.vercel.app/

If you open de dev tools, you may check the console:

Screenshot of the console


At this point, I took a small leap: while implementing a tiny react-dom is one thing, crafting the plugin for the terminal is a different tale.

So i introduced the solution by Vadim Demedes: Ink.

Ink is a React renderer for the terminal.

I did prepare a playground (check the playground branch) with just 2 dependencies: ink and react

You can check the final code at GitHub. Anyway, in a nutshell:

...

function useWorld({ onGameOver, onGameWin }) {
  const [world, setWorld] = useState([
    "tree",
    "character",
    "tree",
    "tree",
    "tree",
    "enemy",
  ]);

  useEffect(() => {
     ...
      if (random > 0.5) {
        return moveEnemyRight();
      }
      if (random < 0.5) {
        return moveEnemyLeft();
      }
    }
  });

  const moveEnemyRight = () => {
    setWorld((currentWorld) => {
      ... bla bla
    });
  };

  const moveEnemyLeft = () => {
    setWorld((currentWorld) => {
      ... bla bla
    });
  };

  const moveCharacterRight = () => ...

  const moveCharacterLeft = () => ...

  return { world, moveCharacterRight, moveCharacterLeft };
}


function App() {
  const { exit } = useApp();
  const { world, moveCharacterRight, moveCharacterLeft } = useWorld({...});

  useInput((input, key) => {
    if (input === "q") {
      exit();
    }
    if (key.leftArrow) {
      setDisplayText("<-");
      return moveCharacterLeft();
    }
    if (key.rightArrow) {
      setDisplayText("->");
      return moveCharacterRight();
    }
  });

  return (
    <>
      <Ground>
        {world.map((type, i) => (
          <WorldElement key={`${type}-${i}`} type={type} />
        ))}
      </Ground>
      <Text>{displayText}</Text>
    </>
  );
}

...

render(<App />);
Enter fullscreen mode Exit fullscreen mode

Resulting in this little fella:


Honestly, it was a tremendous success; many people congratulated me.


thanks for reading πŸ’›.

Image of Datadog

How to Diagram Your Cloud Architecture

Cloud architecture diagrams provide critical visibility into the resources in your environment and how they’re connected. In our latest eBook, AWS Solution Architects Jason Mimick and James Wenzel walk through best practices on how to build effective and professional diagrams.

Download the Free eBook

Top comments (2)

Collapse
 
proteusiq profile image
Prayson Wilfred Daniel β€’

That is awesome. I would not have completed a sentence React in... with word terminal. This is 🀯

Collapse
 
michthebrandofficial profile image
michTheBrandofficial β€’

How the hell can you render that? And what the hell is going on? πŸ˜‚

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up