Hacking JSX: Building in Minecraft with React

Rate this content
Bookmark
SlidesGithub

When combined with a custom rendering function, JSX can be used to quickly build a custom domain-specific markup language. I will show you how to approach this using the example of creating builds in Minecraft.

7 min
12 Dec, 2023

Video Summary and Transcription

JSX can be used to create builds in Minecraft by writing pseudo-HTML code within JavaScript. It can be transpiled into a format that the browser can understand and is not limited to React. JSX allows for the creation of an intermediary representation that can be converted into commands for Minecraft. Existing tooling can be used with JSX, eliminating the need for custom parsers and enabling linting and IDE support. The source code for the project is available on GitHub.

Available in Español

1. Using JSX for Minecraft Builds

Short description:

Hello React Day, I will be talking about how we can use JSX to create builds in Minecraft. JSX is a way of writing pseudo-HTML code within JavaScript code. It can be transpiled into something that the browser can understand. JSX is not limited to React and can be used with other functions. It allows for the creation of an intermediary representation that can be converted into commands for Minecraft. Using JSX for building a custom DSL is beneficial because it is familiar to developers and has a low learning curve.

Hello React Day, my name is Felix and I will be talking about how we can use JSX to create builds in Minecraft. Furthermore, I will also be exploring the idea of using JSX as domain specific language in general.

So first of all, what even is a domain specific language? A domain specific language or DSL for short, it's a programming language that is designed to do one thing particularly well. And that is in contrast to a general purpose programming language such as for example JavaScript, which in theory is able to solve every problem.

So take for example SQL. SQL is very good at interacting with databases in a very concise manner, but it is overall limited in functionality and isn't able to solve every problem. Or in other words, SQL isn't Turing complete. Another very famous example for a domain specific language is HTML. HTML is designed to define the structure of a web page. But since we are talking about JavaScript and React here, we aren't able to use HTML directly. Instead, we use something called JSX.

JSX is a way of writing pseudo-HTML code within JavaScript code. But since browsers don't natively support JSX, this JSX syntax needs to be first transpiled into something that the browser can in fact understand. And this is, in the case of React, a call to a function called react.createElement() which then, in the end, represents the same content as our JSX does. But the great part about JSX is that we aren't limited to using it with React. Instead, we can use whatever function instead of React.createElement() to then use JSX and add custom behavior to it.

So in this case, I first of all create a custom block component which then gets fed into my custom JSX handler function, in this case a minecraft JSX function. And this works because my function has the exact same function signature as react.createElement() Therefore, I can take my function as target for transpolation from JSX. In this example here, I've expanded this example and also wrapped it in a fragment. And now the idea is that with my custom JSX handler, I'm able to convert this JSX syntax into an array consisting of plain objects. But now that's the important part. Depending on the use case or the problem that you're trying to solve, this intermediary representation may look completely different. You may want to use classes instead or possibly preserve the nesting that was created by JSX. This intermediary representation will greatly depend on the problem you're trying to solve.

I'm able to convert this array into a set of commands which are understood by the game and then turned into an actual build within Minecraft. In case you don't know, Minecraft is a 3D sandbox game where you can place blocks wherever as defined by three coordinates, x, y and z. And each block of course has a type, in this case it's defined by this ID value.

So therefore in general, the question why would you use JSX for building a custom DSL. The first reason is that you and your colleagues are already familiar with JSX. Therefore there isn't a great learning curve and it's easy to adopt.

2. Using JSX for Minecraft Builds - Part 2

Short description:

You can rely on existing tooling when using JSX, eliminating the need for custom parsers and enabling linting and IDE support. The apply build function converts JSX builds into game elements, similar to mounting a React tree to an HTML DOM element. Building with JSX is easy and familiar, as demonstrated by the readable house component. Running the app with bun allows for real-time rendering of the build. If you create something using JSX, please share it with me. The source code for this project is available on GitHub.

And probably, number two, way more important, you can rely on existing tooling. So for example you don't need to write a custom parser for transforming your JSX markup into the final result. Instead, you can just write that JSX handler and be done. You don't need to write a language parser. And also you can rely on existing tooling for linting or also for IDE support, because JSX is widely supported across tooling.

So, what does this look like in a greater picture? Here I've created an apply build function which in the end is what converts my build, as defined here in JSX, into something that's actually in the game. And you can think of this similarly to mounting your React tree to an HTML DOM element when using React regularly. And now with this village component, this is just plain JSX, as I told you. It is very easy to get into the idea of building something with JSX, because you already are familiar with it. Like here, this house component is just a collection of other components, that is, as I think, very readable overall.

So now if I run this app with bun, because bun has built-in JSX support, I can effectively watch as my build sort of gets rendered to the game. Ok, that's it. I hope I could give you a little insight of an idea of how you can use JSX for whatever purpose you want. If you end up building something, or building a custom language effectively on JSX, I'd love to see what you are creating. So please reach out to me, I'd love to see it. And the source code for this project that I just showed you is available on github.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

TechLead Conference 2023TechLead Conference 2023
35 min
A Framework for Managing Technical Debt
Top Content
Let’s face it: technical debt is inevitable and rewriting your code every 6 months is not an option. Refactoring is a complex topic that doesn't have a one-size-fits-all solution. Frontend applications are particularly sensitive because of frequent requirements and user flows changes. New abstractions, updated patterns and cleaning up those old functions - it all sounds great on paper, but it often fails in practice: todos accumulate, tickets end up rotting in the backlog and legacy code crops up in every corner of your codebase. So a process of continuous refactoring is the only weapon you have against tech debt.In the past three years, I’ve been exploring different strategies and processes for refactoring code. In this talk I will describe the key components of a framework for tackling refactoring and I will share some of the learnings accumulated along the way. Hopefully, this will help you in your quest of improving the code quality of your codebases.

React Day Berlin 2022React Day Berlin 2022
29 min
Fighting Technical Debt With Continuous Refactoring
Top Content
Let’s face it: technical debt is inevitable and rewriting your code every 6 months is not an option. Refactoring is a complex topic that doesn't have a one-size-fits-all solution. Frontend applications are particularly sensitive because of frequent requirements and user flows changes. New abstractions, updated patterns and cleaning up those old functions - it all sounds great on paper, but it often fails in practice: todos accumulate, tickets end up rotting in the backlog and legacy code crops up in every corner of your codebase. So a process of continuous refactoring is the only weapon you have against tech debt. In the past three years, I’ve been exploring different strategies and processes for refactoring code. In this talk I will describe the key components of a framework for tackling refactoring and I will share some of the learnings accumulated along the way. Hopefully, this will help you in your quest of improving the code quality of your codebases.
React Advanced Conference 2022React Advanced Conference 2022
22 min
Monolith to Micro-Frontends
Top Content
Many companies worldwide are considering adopting Micro-Frontends to improve business agility and scale, however, there are many unknowns when it comes to what the migration path looks like in practice. In this talk, I will discuss the steps required to successfully migrate a monolithic React Application into a more modular decoupled frontend architecture.
React Advanced Conference 2021React Advanced Conference 2021
20 min
Advanced Patterns for API Management in Large-Scale React Applications
Top Content
In this talk, you will discover how to manage async operations and request cancellation implementing a maintainable and scalable API layer and enhancing it with de-coupled cancellation logic. You will also learn how to handle different API states in a clean and flexible manner.
React Summit 2022React Summit 2022
7 min
How to Share Code between React Web App and React Native Mobile App in Monorepo
Usually creating web and mobile apps require different tech stacks, and it is pretty hard to share code. This talk will show how I added a React web app and a React Native mobile app in the same monorepo using Nx, and how I optimized codeshare between react web app and react native mobile app.
React Advanced Conference 2022React Advanced Conference 2022
22 min
Developing and Driving Adoption of Component Libraries
What makes a component library good? In order to create a component library that people want to use you need to navigate tradeoffs between extensibility, ease of use, and design consistency. This talk will cover how to traverse these factors when building a component library in React, how to measure its success, and how to improve adoption rates.