Alan Jo Portfolio

Alan Jo Portfolio

Side Projects

3 Threes

2020.6 ~ 2022.3
This is a 7500-page web application made with Next.js using both SSG and SSR. While Googling is helpful for finding various information in real-time, it can be difficult to determine which information is true. To solve this problem, I needed a knowledge base where I could accumulate information that I judged to be true based on my experiences, thoughts, and research. I found the Notion platform to be ideal for this purpose; I organize my knowledge into three categories and use it to eliminate the repetition of finding the same knowledge.
Since this storage has helped me increase my productivity, I wanted to make it accessible to everyone else. I initially used a Cloudflare worker proxy to run Notion with my domain, but this method required modifying the Cloudflare worker code whenever the Notion API policy or structure changed. Instead, I began using the react-notion-x library to fully re-render the notions based on the data, set the UI customization, and apply SEO through code.
By selecting Next.js, I was able to execute static server rendering of a large number of pages at build time and maintain the rendered page even if the official Notion API structure changed. Newly created or unbuilt pages are developed in a way that is visualized using the Notion API in real-time. Some pages were rendered at build time, and hole sitemaps and other pages is rendered with Server Server Rendering per request. Pages with dynamic routing also used and rendered by getStaticPaths of Next.js, and performance optimization was applied to fetch page data only once in various build process.
notion image


2020.3 ~ 2020.10
I created a dedicated page for users to explore, similar to a game. The page was developed using Nuxt, a framework based on Vue. It is a web page that uses Three.js and Potree. I developed a mobile-friendly 3D move controller that allows you to use a joystick anywhere on the screen by touching it. I also added game elements that can be controlled using the WASD or arrow keys, and you can move up and down using Q and E.
After analyzing the Seongland connection, I realized that mobile support was necessary due to the high number of mobile connections. However, I also wanted to provide 3D space exploration without a keyboard. Inspired by a mobile game, I developed a web page that allows movement through a joystick as if playing a mobile game. By dividing the functions by the position of the joystick on the left, right, and top, the movement of forward, backward, left, right, up, and down is intuitively arranged for each function.
notion image


2019.10 ~ 2022.3
I have always wanted to provide a 3D experience to the public through a web browser. However, it was difficult for users to easily obtain information in an unfamiliar three-dimensional space if all the components in the web page were made in 3D. So, I decided to add a 3D element, which is a planet, to the scrolling method like a normal web. A 3D planet is shown on the first screen, and as you scroll down, readable information is provided with cards showing my information below.
To give the card a 3D feel, I added an element called a deck where cards are stacked. Unlike static 2D cards, the cards stacked up with a slight twist from side to side were able to provide both informational elements, a spatial feel, and fun elements through the user's swipe gesture.
However, I encountered some problems. Since I chose a scrollable web page, I used a fake 2D star image for the stars in the background. So, I refactored it with nice code quality. My new object was floating stars in 3D space. To differentiate them from 2D stars, I added interaction. If the user touches or moves the mouse, the stars follow the user interaction. I optimized it not by moving all the stars but only by moving the camera to implement this feature.
In addition, I added sound effects when toggling between dark mode. Sound effects are uncommon in browser experiences, as there is typically only background music. However, I wanted users to have a more immersive experience, so I added sound effects to enhance their interaction with the page.


2019.10 ~ 2021.11
By using keyboard shortcuts effectively, you can significantly improve your work efficiency. However, it is strange that people tend to use shortcuts more frequently in certain programs than for typing, which is the most common computer activity. For example, when writing and you find a mistake at the beginning of a line, you may have experienced moving the cursor one space by pressing the left arrow repeatedly to reach that point. This can be easily solved by using the ctrl + left shortcut, but people do not use it very often due to the arrangement of the shortcut keys. As the positions of ctrl and left keys on the keyboard end at the end, they cannot be pressed with one hand. Moreover, the layout of many shortcuts is difficult to use compared to their functions. Relocating these shortcuts could greatly improve typing productivity.
While searching for a solution to this problem, the author came across Autohotkey (AHK). To design the relocation of necessary shortcut keys, the author referenced many functions of vim. However, vim had three major problems. First, it was not intuitive as the text cursor movements were listed as hjkl in a row. Second, productivity was low as it required changing the mode. Third, it only works inside vim, so it was not a shortcut that could be used anywhere, leading to shortcut conflicts. The author solved these problems by making the keyboard shortcut layout identical to the arrow shape, which is more intuitive. By using the alt key, a shortcut structure was designed that does not overlap with most applications without changing the mode. A core source was made using AHK by adding various functions for productivity, such as typing supported by vim and moving the mouse using shortcut keys. All of these functions have intuitive shortcut keys, so the author named it Intutier, which means anyone can use it easily.
The author has been using Intutier successfully, and it has significantly increased productivity. Typing, which takes a lot of time on a computer, can become more efficient and faster with Intutier. The author decided to develop it into a program so that anyone can install it and save time. A desktop application platform was used to install and run the project, which previously only had AHK core. The author created a desktop application using Vue and Electron, built an exe, and distributed it on Github. Additionally, it has been distributed on Winget, a windows package manager, for installation in various ways, and is currently maintained. To address reviews that Intutier is difficult to learn due to its collection of shortcut keys, the author created a usage page in Korean and English to make it easy for anyone to learn. Intutier is also the project that currently has the highest number of Github stars for the author.
notion image

To Spotify

2021.6 ~ 2021.7
I believe that the apps that dominate the domestic music streaming industry offer poor user experiences. Both Melon and Genie were error-prone and lacked functionality. When I tried Spotify, however, it provided a good user experience. I wanted to switch to Spotify, but I was stuck with my current platform because it was difficult to transfer my favorite artists, albums, and playlists from Genie to Spotify. Moving them one by one was too time-consuming, so I looked for a way to automate the process. Fortunately, Spotify provides a web API, which allowed us to develop a tool to transfer user data such as songs and followed artists. We also created a document page to make it easier for users to use the tool.

Github Setter

2021.11 ~ 2021.12
As you develop, the number of projects you manage, or Github repositories, increases. Although Github provides various APIs and management UI for repository management, there is no function for the simultaneous setting of multiple repositories. It can be physically difficult to set up features such as branch protection, issue label setting, or uploading commonly used lint config files or .github folder to multiple repositories individually.
To solve this issue, I developed a code that can upload files to all selected repositories or configure various repositories. This code is also distributed on NPM and is useful for managing my repositories.
seonglaeUpdated Jul 15, 2023


2021.5 ~ 2021.8
When recording a screen, the viewer may not be aware of which key or mouse action the photographer is currently using. To address this, I developed an application that visualizes the current key or mouse action being entered on the screen. The name comes from VSCode's screencast. I customized the source code and wrapped it with Electron. The application has a structure similar to Intuiter, and is also distributed in Winget, making it easy to install and use.
notion image
notion image
seonglaeUpdated Feb 13, 2023


Vector Drawing Platform

2020.10 ~ 2022.9
I lead the project from planning and database design to full-stack development and server management.
notion image


In the DB design phase, I created a design that actively utilized PostgreSQL's JSONB column to handle fluid data. By using JSONB column Array or Object, I could easily develop change history or access records and add functions. The DB structure is implemented so that it can be managed in code by minimizing the relationship on the DB and implementing most of the business logic on the server. Meanwhile, the race condition that occurred in various ways in the ORM was solved by dynamically executing atomic SQL statements. Additionally, I implemented an ORM Restful API by creating a table for each class through Feather. By putting abstract classes of parents to inherit by grouping each table with the same structure, common properties could be managed with one code.


It was a project that required performance tuning due to large data serving and visualization. In terms of performance, the biggest factor in optimization was to remove common parts by placing a separate function for Array data visualization in the visualization call for the development instance. By maximizing the native member functions of JS Array (reduce, map, filter, every, some), we were able to improve performance with readable code. In the process of optimizing the performance, we optimized the performance of large-capacity 3D rendering by utilizing the Chrome developer tools. The Chrome Lighthouse, Memory, and Performance tools were able to find and fix areas that were using excessive memory or processing time.
Development was carried out using various built-in objects of Javascript. Deduplication or change detection using JS Set, and by using JS Proxy to intercept property value changes due to user actions, and add various logics in the middle, so you can manage the developed code in the same place. The project was carried out using Nuxt (currently Next.js), referring to the implementation of Vue's Reactivity from the built-in object, implementing a similar function in the project and writing the logic.


Since I directly manage the backend and infrastructure, development between the backend and the infrastructure went smoothly. I needed caching, so I decided to use Redis and added a check algorithm to my backend development. We used a total of three caching methods. First, we cached data that is frequently received with little modification in Redis and applied a deletion algorithm when modifying it. Second, immutable data is cached provided by Nginx, and the webserver cache is also used. Third, the data is cached by the client through the cache-control header. The two caching with URL-based cache-control were implemented smoothly because the possibility of duplication was excluded by the DB design that uses instance id as UUID.
InfluxDB is a logging DB that is similar to the implementation of the caching function. I am using InfluxDB as a log DB for the service. All client errors, server errors, and all API requests through the API are logged in the logging middleware to InfluxDB. We have created a system that easily manages the job status and error tracking by recording the request time, requesting user or job site, and visualizing the job.

Hardware capture application

2019.6 ~ 2019.10
notion image
This is a real-time project based on that accesses and controls in-house hardware for planning and development purposes. The project comprises a server and client, and the server calls a C++ library that controls the hardware based on events. The project uses C++ Node Addon, which is an interface for calling C++ code from Node.js. In other words, the hardware and interface were implemented using Node.js Addon. The project focuses on maintaining the flow of state management from the backend to the frontend, as it is crucial to share hardware status up to the front. Furthermore, for real-time storage of various sensor acquisition data, the project optimizes server performance by setting a separate thread that only stores data for each sensor using a Node.js thread. The project also includes a visualization part for real-time data, and it utilizes various techniques using Openlayers, Three.js for 3D, and optimizing geographic data visualization.

Capture Control Tower application

2019.6 ~ 2019.12
notion image
We also planned and developed a subsystem called Subs to check and manage the current shooting location of the hardware control vehicle mentioned above. Additionally, the above hardware control server acts as a client of the server of the control tower, displaying vehicle information in real-time like an air traffic control tower. This design allows multiple hardware to be controlled in real-time through a web browser.
Furthermore, for visualization performance, we built a system that serves as WMS or WMTS, rendering images through Geoserver for data stored in Postgis without visualizing vectors of large-scale geographic data on the client.

Dev Skills

NPM Modules

Code Separation

I believe that refactoring code into cohesive functions that can be separated and reused is an important skill for implementing higher-level functions in any programming language. That's why I modularize and manage parts that can be separated into NPM modules within the team. We use abstract classes or intuitive import and export folder structures to separate code by function in various modules.

Module Testing

Some of the in-house NPM modules are tested using a framework called Testyts. Currently, some modules have been moved to a testing framework called Vitest, which provides coverage visualization and various testing functions. We require tests to be added as functions are developed, and we have built a structure that separates and distributes the test code for distribution. In addition, we use the PNPM workspace to manage common dependencies in one monorepo for in-house modules.

Module Building

Modules written in TypeScript are built with tsc and then distributed in the company's NPM registry. C++ code is also built and distributed using node-gyp and Node Addon. In addition to tsc, we use esbuild or other build methods to distribute code. github-setter is a typical project that I distribute using esbuild.

Tech Stacks

As I have worked on several personal projects for a long time, I have come to realize that deploying on the web is relatively easy, but it takes a lot of effort and time to do it right. Through developing many projects, I have come to learn the importance of deployment and have grown personally.

Azure Pipeline

We use Azure Build Pipeline for building and uploading images to our in-house registry for every commit or tag in the main branch. We have also enabled direct deployment to an Azure Release Pipeline instance as an on-premises service.

Github Action

We use Github Action to build 3trees and Seongland Docker images, and then automatically upload them to the Github container registry. When working with GCP, I have experience using gsutil cp to transfer static build files to the GCP bucket as part of the deployment flow.
As a Github Action, the Intuiter builds electron, creates an exe, and distributes it as an exe distribution to Winget. It then automatically creates and adds a pull request to micosoft/winget-pkgs. This method is also applied to screencast, which is another electron-based project.
In Seongland, I have experience implementing a Github Action that builds and automatically distributes worker source code to Cloudflare workers.

Linux Container

Vercel service is used for simple web projects that do not require container image building, but some projects require the use of container images. Since Linux containers are difficult to deploy automatically, it was a challenging task. However, I have applied my understanding of the structure and history of the container to the deployment of many projects. I am now familiar with using Docker and docker-compose for web apps in various ways. I currently use Rancher Desktop mainly for local development.


Deploying instances based on docker run or docker-compose required an outage to update the service, so I had to use a different approach. Initially, I used a combination of LB and Cloud run on GCP as a container deployment platform when I didn't understand Kubernetes. However, since the platform is not open-source, I didn't know the internal structure, and there was no way to deal with an error when it occurred. Thus, I felt the need to use Kubernetes, which is more compatible with open-source technologies. Among several Kubernetes Distributions, we chose a platform called Okteto, which offers Managed Kubernetes clusters at a reasonable price. We currently use the corresponding platform to distribute 3trees and Seongland to each namespace of the Kubernetes cluster. The Kubernetes manifest files are managed as files in each repo and are distributed without interruption through the rolling update.

Cloud Service

AWS, Oracle Cloud, Azure

To understand and compare various cloud service structures, I personally created a gateway, public IP, instance, and VPC in each cloud and have experience setting web app access in the cloud service instance.


I have tried several cloud services, and I am particularly impressed with GCP. I have personal experience with Cloud run, Cloud Build, Cloud Registry, Load Balancer, Cloud Storage, and GCP App engine. I use GCP LB in front and connect to a GCP bucket, GCP App engine, or cloud run depending on the subdomain or route.
notion image
notion image
Although it is not a GCP service, I also analyze the use of pages I developed using Google Search Console and Google Analytics.


Cloudflare is not a cloud computing service, but we use it for DNS management. In addition to DNS management, Cloudflare offers various services that use domains, such as Cloudflare Worker, App, Analytics, and Zero Trust.


I believe that development task management is crucial for version control of enterprise-grade source code. Through several projects, I have experienced that development task management can make the project direction clear, improve efficiency, or make it very bad.

Azure DevOps

I have experience in creating a development culture within a team using branch policies and security in Azure DevOps. In-house Semantic Commit, Semantic Branch, and Semantic Versioning are used to consistently manage sources within the team.


Managing code by oneself for a long time makes it difficult to understand the code even if you have been working on it. Therefore, even when working on various projects on Github, we always create a branch for each issue and make a pull request. We also enforce branch protection rules for the main branch. For the same reason, we keep Semantic Commit, Semantic Branch, and Semantic Versioning consistent even on personal Github.
I believe that the key to programming is to eliminate repetition. When working on various projects with limited study time and stack, the amount of repetitive code writing increases. To solve this problem, I utilize various boilerplates as a Github template repository, and I share them by making them public.