Codetree ! Or why i create a new Codepen.
Tags: webassembly, webdev, react, typescript
Published: 2021-05-09 19:32:00



**Codepen and codesandbox are great, but honestly they are slow and even more if you have a weak internet connection, so i created Codetree, an ultra-fast, high-performance online playground with automatic npm module detection.**

### To be able to understand why [Codetree](https://codetree.vercel.app/) is a powerful online editor, we will:

* Understand how codepen works.

* Find a bundler that can be executable inside our browser.

* Build a simple react app transpiler.

## First, how Codepen/Codesandbox works ?

Thanks to the great instructor Stephen Grider, i found in one of these videos a rather detailed explanation on how [Codepen](https://codepen.io/) works. To simplify, they retrieves the raw user code and sends it to an Api Backend server, the server will run Babel or any other transpiler and send the result back to the application to be executed by the user’s web browser.

![](https://cdn-images-1.medium.com/max/3200/0*B1vUS8owwELpX9XS)

The problem with this method is that a request must be made each time the user writes code in the editor (even with a debouncer), which requires more time to receive, process and convert the code before displaying it in the application. So for [Codetree](https://codetree.vercel.app/), i needed to do all these compilation tasks directly in the browser.

## Next step: Find a transpiler and a bundler that work in a browser.
>  A transpiler, is a program that takes the source code of one programming language and compiles it into another programming language.

For [Codetree](https://github.com/philippetedajo/codetree), i chose Babel, it converts JavaScript (version ES2015 or higher), and typeScript into code that is compatible and directly executable by old or new browsers.

A **bundler** is used to group together multiples modules into a single one , more specifically, it : 
1- parses entry points, e.g. index.js , main.css
2- looks for import/export/require statements,
3- searches for theses modules on the hard drive 
4- links all these files into one file

The choice for the bundler was more complicated, as the Webpack bundling process does not work in the browser, being a big fan of [WebAssembly](https://webassembly.org/), i looked at [Esbuild](https://esbuild.github.io/).

[WebAssembly](https://webassembly.org/) is a low-level, assembler-like language that can achieve performance close to native applications (e.g. written in C/C++) while running on the web, and [Esbuild](https://esbuild.github.io/) as the docs says is An extremely fast JavaScript bundler build using Go and WebAssembly.

## Finally how Codetree works ?

To understand all this, we will create a simple application with react which allows us to compile typescript into a code that is directly executable by our browser.

To get started, let’s head to the terminal or command prompt and run the following command :

     yarn create react-app my-app --template typescript

I you are not familiar with typescript you can just omit the template, then clean up your app.ts file like this :

    import *React *from 'react';
{% gist https://gist.github.com/philippetedajo/978de6866a517a6cd893a4d6222bdd47.js %}
Now we need to add a **text area** where we will type our typescript code , a **button** to start **transpiling**, and a **“pre”** tag to show the **transpiled code **:
{% gist https://gist.github.com/philippetedajo/6599eac3808a8ab0caeefc6144ad7320.js %}
Let’s add state to store the user input code, and the output transpiled code :
{% gist https://gist.github.com/philippetedajo/4121f5a7bd83d34c86c2eb1f5ccaa596.js %}
**We can now integrate Esbuild to our project:**

Esbuild will allow us to transpile our code directly inside the browser. It comes with a javascript wrapper that define command to send to the GoLang bundler, and a webassembly binary (wasm) wrapper that allows us to run low level language(like C, Rust, Go..) directly inside the browser.

* First we need to install esbuild-wasm npm module :

    yarn add esbuild-wasm@0.8.57

Then we add this code :
{% gist https://gist.github.com/philippetedajo/b8e304236e7ade8060e0f44f246e3a78.js %}
Now let’s take a quick look on what we write above

* We add an asynchronous initializer function for esbuild in the body of our app.

* We add the url for the .wasm file : **"https://unpkg.com/esbuild-wasm@0.8.57/esbuild.wasm"** in the wasm argument.

* We start the services function when the component is mounted for the first time using a **useEffect Hooks and an empty array.**

* The services function of esbuild comes with some built-in functions (build: ƒ, serve: ƒ, transform: ƒ, stop: f)

**Now our Esbuild setup is ready in our app we can app try to compiled some typescript code:**
{% gist https://gist.github.com/philippetedajo/361ef84ef464eed0aad93090366d0524.js %}
**Once again let’s take a closer look at what’s going on :**

* First we set the scope of the services function available outside the initialize() function, to be able to use it in our onClick() function, we do this by using useRef hooks to references our Esbuild services.

* Then we prevent the user from executing a transpiling if Esbuild has not finished his initialization.

* We use the transform function to transpile our code by passing some arguments: 
 **The userInputCode** : the code we put in the text-area.
 **The loader** : to specify the type of code we are providing.
 **The target**: to nkow in wich js environement the code should be generated.

* Finaly we take the code result from the transform function and use it to update our transpiledCode state.

Voila ! You have build a typescript in-browser transpiler, you can now add any typescript code and show the result 🥳🥳🥳.

![](https://cdn-images-1.medium.com/max/2264/1*C1sQwxHpx6EWMPvw-mVtww.png)

If you find this project interesting, please support us by leaving a star on [Github](https://github.com/philippetedajo/Codetree), you can find the full open source project here [Codetree](https://github.com/philippetedajo/codetree). ✨