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:
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 ๐ค.my-react-dom: Repository with a custom implementation of
react-domused to live coding. Two branches:playgroundandmainink-world: Repository for a tiny-tiny-tiny game using Ink + React on the terminal again, used to live coding. Two branches:
playgroundandmain.
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
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.
Next step: react-reconciler: the package the React team provides to create your custom renderer.
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'; โจ Ah! and that's also deployed at Vercel: https://my-react-hvpqtmgva-manu-artero.vercel.app/
If you open de dev tools, you may check 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 />); Resulting in this little fella:
Honestly, it was a tremendous success; many people congratulated me.
thanks for reading ๐.





Top comments (2)
How the hell can you render that? And what the hell is going on? ๐
That is awesome. I would not have completed a sentence
React in...with wordterminal. This is ๐คฏ