JSCity visualizing JavaScript code
Tags: react, reactthreefiber, threejs, visualization
Published: 2020-05-31 12:53:37

---
title: JSCity visualizing JavaScript code
published: true
description: This is the first very first article talks about the **motivation** behind JSCity. The idea is to publish a series of posts about building.
tags: react, reactthreefiber, threejs, visualization
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/rwelvqqeqxjuf2pqtmqn.png
series: JSCity visualizing JavaScript code
---

This is the very first article that talks about the **idea**,  **motivation** and the **mvp** of [JSCity](https://github.com/peaonunes/jscity). 

I learned a lot while doing it and hopefully you will also find something interesting to take out of it as well.

## react-three-fiber

So, late last year I started creating [JSCity](https://github.com/peaonunes/jscity). The ultimate goal was to visualize JavaScript projects as cities. But why?

It all started when I saw the following [tweet](https://twitter.com/0xca0a/status/1184586883520761856) by [Paul Henschel](https://twitter.com/0xca0a).

{% twitter 1184586883520761856 %}

My reaction was: "_Wow! That's really cool and it's built with `React`, how?!_"

The answer was [react-three-fiber](https://github.com/react-spring/react-three-fiber). I was amazed by the project 🤯. It is a `React` [reconciler](https://reactjs.org/docs/reconciliation.html) for [Threejs](https://threejs.org/), and I got really curious to see what it does.

On one side there is `React`, a very popular and robust library to build UIs.  Because of its declarative nature `React` is really good for a lot of things and the community is always pushing the ecosystem forward.

On the other side, there is `Threejs`, the most popular 3D library for `JavaScript` with a very powerful and rich API.

Although it is very possible to combine them together the `Threejs` imperative nature makes that a non-trivial work. For example, synchronizing `React` state with the 3D canvas can be painful.

Now let's take checkout this [sandbox](https://codesandbox.io/s/rrppl0y8l4?file=/src/index.js). Feel free to play around with it.

{% codesandbox rrppl0y8l4 view=split %}

`react-three-fiber` builds the bridge between the composable and declarative `React` nature and the powerful API from `Threejs`.

A lot of initial setup and complexity is abstracted. However, the main part is that it exposes a very good [API](https://github.com/react-spring/react-three-fiber/blob/master/api.md), handy hooks and maps objects from `Threejs` to `React` components. 

Now we can leverage of the best of these two different universes.

## Matching an intention with an idea
I immediately wanted to try it. But what should I do?

I made a few examples using `react-three-fiber` on [CodeSandbox](https://codesandbox.io), but I wanted to continually explore and build something bigger.

![idea conception](https://media.giphy.com/media/LlLPJYt7pgolgHLcmq/giphy.gif)

I've used `Threejs` in the past to build a project called [SwiftCity](https://swiftcity.github.io/) (no longer maintained) - a visualizer of Swift code. Then it clicked 💡! I can bring that same idea of visualizing code as cities, but this time applying to JavaScript universe.

I would also be able to explore some other interesting topics like `react-three-fiber`, [ASTs](https://en.wikipedia.org/wiki/Abstract_syntax_tree), `babel`, etc.

Besides, 3D things are so cool, right?

## JSCity

So JSCity idea came to visualize JavaScript code as cities. My intention was to build a **demo** to get a sense of how that would look like.

### Explaining "The City Metaphor"

To summarize, the idea behind [City Metaphor](https://www.inf.usi.ch/faculty/lanza/Downloads/Wett07b.pdf) is to analyze and view software systems as cities. The key point is to explore and understand the complexity of a system by mapping the source code to a city.

### The concepts

Before rushing to implement the MVP we have to define how to translate JavaScript code into a city. For example, cities have buildings, right? And also blocks. So here are the building blocks that I've chosen for our city:

- What piece of code does a **building** represent?
- How do we define the dimensions of a building (width, height and length) ?
- How do we show the code hierarchy as areas of a city?

![Azures City Topology from Visualizing Software Systems as Cities](https://dev-to-uploads.s3.amazonaws.com/i/l799qkw4ksnexcgmz6pe.png)
<figcaption>Azures City Topology from Visualizing Software Systems as Cities</figcaption>

#### The buildings in the city

In the original metaphor, a building was mapped to represent a Java class. However, various elements can own a lot of responsibilities in JavaScript.

For instance, the buildings could be Functions, Classes, Objects, etc. Beyond that, functions might appear as [IFFEs](https://developer.mozilla.org/en-US/docs/Glossary/IIFE), [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), [closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures), [function expressions](https://developer.mozilla.org/en-US/docs/web/JavaScript/Reference/Operators/function) and more.

I decided then to **only consider** [simple function definitions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions) and its clojures for the purpose of the demo.

#### Dimensions

![block dimensions](https://dev-to-uploads.s3.amazonaws.com/i/2ecf222imcsb2trsiulq.png)

Several metrics can be taken to define the measurements of a building. I decided that the building **height** would be given by the **number of lines of code** of the analyzed function. The **width and length** then would be defined by the amount of **calls to other functions** inside the examined function.

#### Topology

The city topology is mapped to elements of the system hierarchy.

Since there are no packages, namespaces or anything equivalent in JavaScript, the mapping will limit to the following levels: the **project**, **directories** and the **files**.

```js
function sum(a, b) {
  return a + b
}

function calculate(a,b) {
  function log(text) {
    console.log(text)
  }
  log(sum(a, b));
  log(minus(a, b));
  log(times(a, b));
}

function minus(a, b) {
  return a - b
}

function times(a, b) {
  return a * b
}

```

The code above would look something like this:

![topology of a city](https://dev-to-uploads.s3.amazonaws.com/i/y5tqnpghhleu6hjkhem8.png)

Function definitions that belong to a file will appear inside the file limits. In the image above, the light grey area represents a file and its functions are the buildings.

Function declarations that are declared inside another function ([clojures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)) will have their own block stacked on top of the building that represents their parent function. We can see that the largest building represents a function that has a clojure inside of it.

### Building the MVP

Even having previous experience with the concept and knowing more or less what I would need to build, I still wanted to keep it minimal at first.

I **will not go** into implementations details here. But do not worry! The next posts will be really focused on exploring every part.

In summary, the steps that I took were:
1. Created functions where I could read the content of a JavaScript file and parse it to get its `AST`. For that I've used [babel-parser](https://babeljs.io/docs/en/babel-parser).
2. Coded something to navigate the `AST` and collect the necessary data from the functions. Instead of using tools like [babel-traverse](https://babeljs.io/docs/en/babel-traverse) for this, I actually implemented it myself (and I regret it 😅)!
3. Implemented an algorithm to create the city grid and place the buildings in the right place from scratch. Although I still have the code from SwiftCity, I can barely understand it anymore 😬.
4. Used `react-three-fiber` to read the city definition and to render the city.
5. Used `React`to build the app and handle the input file that would be imported.

### The first version

I made it in the end 🎉! The live version is available at [JSCity](https://peaonunes.github.io/jscity/) and the code is on [GitHub](https://github.com/peaonunes/jscity) as well.

{% twitter 1202165153866715136 %}

There is a lot that this first version does not cope with. For example, as I opt in to just consider function definitions a lot of modern JavaScript code will not be represented. One example is functions defined using the the arrow notation.

### Some conclusions

I got inspired and could not rest until trying out `react-three-fiber`. All because of a tweet. And that is a lesson to me:
> Share your work whatever that is. It may inspire someone.

My initial intention was to focus on experimenting with 3D through `react-three-fiber`, but what ended up happening was me spending most of the time trying to get a good enough city creation algorithm... That was hard! Another lesson here was:
> Choose a project that will let you focus on what you want to learn.

Nonetheless, it was really fun to build it: I got to play around with other nice tools like `babel-parser`.

![giving magic stick](https://media.giphy.com/media/ifYxDMBr1XP8hQvPeY/giphy.gif)

## What is next?

I got it working. Now I want to make it better.

The code is very limited and fragile at the moment. I want to extend JSCity and be able to load a directory and build the entire city from that. 

From now on I will be diving deep into each part of the implementation one at the time. I'll be sharing it through posts and I hope some of these things are interesting to someone else too!

Let me know what do you think about the idea. Thoughts, suggestions and comments are always welcome. See you in the next chapter.