Tech

Renewing the EXEM Website as a Solo Developer

2025.12.19 · Seunghun Park

Read the original in Korean
Renewing the EXEM Website as a Solo Developer

Renewing the EXEM Website as a Solo Developer

Author
Seunghun Park
Date
Dec 19, 2025
Description
How the EXEM website was renewed: the tools, AI experiments, and engineering principles behind a one-person build.
Featured
Featured
KO slug
exem-website-renewal-dev-story
Status
Published
Tag
Tech
Translation
AI draft
Translated from the Korean original. Some screenshots show the original Korean interface.

Introduction

 
💬
EXEM is taking a new leap forward, and it was an honor to be part of the start.
Hi, I'm Seunghun Park, a frontend developer on the EXEM BX Team.
On this next-generation website and back-office renewal project, I handled both client and server development.
 
💬
We are launching a website built for EXEM's next generation.
This renewal was an important project to reshape EXEM's branding and service experience. As 2025 comes to a close, we are unveiling the new website.
Thank you to everyone across the many teams who worked behind the scenes to make this launch happen.
 
 
Here is how I plan to write this post.
 
I expect a wide range of readers: EXEM employees, future applicants, and people at our customer companies. I thought about what each of you might be hoping to get out of this post.
  • How was the website made?
  • What did the developer pay attention to while building the website alone?
  • This looks nice. What tech did they use?
 
To match these likely goals, I'll keep this post more "experience-driven" than our earlier tech posts. It focuses on the technology used during development, my philosophy and values, and the lessons I learned.
 
In one line: "This is how the EXEM website was renewed." Let's get started!
 
 

1. Decisions for Results

 
Decisions in running a project come with many metrics.
  • Input: people cost, communication cost, infrastructure cost, etc.
  • Output: sales revenue, marketing results, etc.
  • Etc: difficulty, uncertainty, sustainability, etc.
 
Here is how I'd sum it up.
💬
In business, "value for money" matters.
 
Take on risk you can handle, use minimal resources, and produce maximum results. I think that is the core of business. Here are the strategies I used on the development side.
 
 

1-1. Don't Reinvent the Wheel

Libraries are a great way to save development time. They let you borrow skill, effort, and time from the developer ecosystem.
 
💬
The fewer resources you have, the more conservative you should be.
After development comes maintenance. You have to be calculating about the future. As a solo developer, I had every reason to care about "value for money" even more.
 
Let me sum up this section first: "Here are the good wheels I used for productivity and DX."
 
 

A Blog Built on Notion

You may have already noticed, but this blog is built with Notion and a library called react-notion-x, which renders Notion page data and UI inside our project. That said, I had to rework a lot of details to fit the site's look and feel.
Blog built on Notion - 1
Blog built on Notion - 2
 
The higher-level a library is, especially one that includes UI, the harder it is to tailor. The core feature of this library is simply rendering Notion pages as-is in a project. OpenGraph settings, analytics, CTA buttons, and similar features required building the matching CMS features in a separate back office.
 
Even so, it is powerful. It supports text, images, video, files, equations, and other media types, and building a WYSIWYG editor with responsive layouts takes a huge amount of resources. Being able to use Notion's high-performance WYSIWYG editor alone is a big advantage.
 
 

Scrolling with GSAP

The renewed website offers scroll-driven UX throughout its pages. We focused on delivering modern web UX that is hard to find on legacy websites, and even more so in B2B.
Main page
Main page
HQ tour
HQ tour
4 services and all-in-one
4 services and all-in-one
Text reveal effect
Text reveal effect
 
Along the way, I used an animation library called GSAP. It supports many advanced features, but it was paid, which limited its use. In April 2025 it became completely free, so we could adopt it on the website with confidence. Compared with the well-known Motion, it is harder to learn but offers a more fine-grained animation interface.
 
The current website also implements many scroll features on its own, without GSAP. But GSAP helped us solve many features that are hard to build by hand, such as inertia scrolling and fixed-duration scrolling.
 
 

Multilingual Support with i18n-ally

Besides Korean, the EXEM website supports English and may later expand to Japanese and Chinese. For this, I used next-intl, an internationalization library for Next.js.
 
To manage 1,200 translation keys efficiently and safely, I also adopted a VSCode extension called i18n-ally. Here is its best feature: instead of showing the raw translation key, it displays the key replaced with text in the primary language. That alone is reason enough to use it.
 
i18n-ally_before
Before
i18n-ally_after
After
 
 
It has many other features for managing translations safely and effectively. For details, see the i18n-ally documentation.
Usage summary by language
Usage summary by language
Checking missing translation keys and keys in use
Checking missing translation keys and keys in use
 
 

1-2. Wasting AI

These days you can't talk about productivity without AI. Beyond AI code editors and agents, earlier posts covered interesting topics such as automation workflows and QA agents. It's a great time to use AI smartly.
 
So I'll share cases where I "wasted" AI on things outside feature development. These are projects I would never have tried without AI.
In short: "Here's another way I used AI."
 
 

Ascii Generator

Ascii Generator
The main visual section of the current website is ASCII media made of specific characters and a key color. The requirements were:
  • Extract ASCII media from the source media at any desired resolution.
  • Change specific characters to the key color.
  • Keep 60FPS and sharpness.
  • …
 
I couldn't find a library that met these requirements, so I decided to build one.
 
I built a separate library called ascii-react and kept it apart from the project code. Then I built and deployed a temporary site where you can set various options and export the results.
 
ascii-react library
 
Now designers on the team can easily turn media into ASCII media.
 
This was not a project to maintain for long. I focused on short-term goals over performance and stability. Even when some issues bothered me, I ignored them if they didn't affect the result. We reached the MVP, "turning source media into ASCII", and used it on the website.
 
 

SEO R&D

For SEO R&D to apply to the website, I ran a toy project. SEO needs things like these:
  • Each page must have complete content.
  • Relevant metadata must be provided.
So I used AI to create fake data and lay it out on pages.
 
With AI prompts describing the concept and intent, I fleshed out a PRD and automatically generated content suited to each page. I focused on what affects SEO: semantic markup, component structure, page and category structure, and the sitemap.
SEO R&D - 1
 
As a result, I could produce a business-grade page every 5 minutes.
The pages were indexed by Naver and Google, and even showed up in AI summaries. We hit the MVP goal, "an effective indexing test", with few resources.
SEO R&D - 2
Had I known it would be used like this, I would have put more thought into the name.
 
 

1-3. Building DevTools

💬
In a way, this continues from "Wasting AI" above.
In frontend development, we usually follow the data flow by adding console.log or pausing execution with debugger or a breakpoint. But I wondered: "Could I build a DevTool that helps DX a bit more, not just for checking data but also for composing it?" So I used AI to build DevTools quickly.
 
DevTools are not visible to users, so their business value is low. That's why I focused on "spending no resources" and "seeing and generating the data I want easily" rather than code quality.
 
 

Website - HQ Tour

On the HQ tour page, clicking a specific floor on the last layer of the building opens the HQ tour modal starting from that floor. But the building is drawn with 3D distortion, so each area had to be built as a polygon by plotting vertex coordinates. It was tedious, so I built a DevTool and used it during development.
HQ tour page - 1
HQ tour page - 2
 
There is also a config that sets the switch timing between layers: a layer that shows and hides text, a layer that swaps hundreds of images based on scroll progress, and a layer that opens a modal on click. Timing is critical in this data, so I built a DevTool to check it against the UI.
HQ tour DevTool
 
 

Back Office - Authorization Management

Behind the website is a back office where staff can review and configure the data shown on the site and the inquiries we receive. Each staff member's access and edit rights to each page must be managed separately. I built and used a DevTool on the authorization management page too.
 
Authorization management DevTool
 
The back office's authorization structure is a bit interesting: I designed it as a tree structure using bitmasking.
Advanced authorization management
 
I aimed for detailed, hierarchical permission management like AWS IAM, and took the idea from how Linux's 777 permission system stores data as bits.
  • Read, create, update, and delete actions can each be set individually.
  • Authorizations are linked hierarchically by category and can be set in bulk.
  • Authorization data can be stored efficiently in the DB.
 
 

1-4. Make Difference

We are doing a renewal. Just looking prettier is not enough. We need an evolved strategy and UI/UX for users both inside and outside the company.
 
We looked for the answer in "marketing." We brought the core of marketing into service planning and development.
  • Understand and analyze customer needs.
  • Catch small signs of interest and turn them into big revenue and results.
  • Offer better proposals and value that customers don't yet know about.
 
Our project's users are customers outside the company and staff inside it. Here is what we did for both.
 
💬
I did most of the planning, design, and development for the back-office renewal myself. Please forgive any lack of polish in the visuals.
 
 

Making Work Easier for Staff

The back office serves as the CMS. It manages the blog posts, IR materials, and other content shown on the website.
Back office development - 1
 
During the renewal, we gathered improvement requests from staff in each team, and we are handling them before and after launch based on urgency, number of people affected, and effort.
List printing, designed for looks and function
Built with more polish and functionality than the original request to simply print lists
 
Also, unlike before, the back office now supports mobile. Staff can keep working anytime, anywhere, and respond to urgent situations.
Back office development - 2
Back office development - 3

Digging into Customer Interest

The website inquiry page is where we collect customer inquiries about products, investment, customer support, and more. Each inquiry is routed to the person in charge.
 
A customer inquiry is a sign of interest. We built features to analyze what lies behind that interest and use it for tailored responses.
Back office development - 4
The UI draws heavily on reference CRM services.
 
We collect a wide range of customer interests and requests, and combine them with visited pages and pages where visitors stayed a long time, so we can understand customers from multiple angles.
notion image
Areas of interest and requests
 
We also combine AI analysis, such as recent news about the inquiring company, laying the groundwork for building rapport with the customer and proposing tailored products.
Product inquiry details
 
It's still early after launch, so the design and features are at an early stage. But since sales, PR, and marketing lead to revenue, we have a roadmap to strengthen AI features, usability, and visual polish to support day-to-day work.
 
 

2. Development Philosophy

 
I'm in an unusual position. I'm the only developer running the project among a non-developer leader and colleagues. I alone am responsible for the future of this codebase. I had to stay sharp. I needed to take ownership and look further ahead.
 
Here is the philosophy, values, and strategy I brought to development.
 

2-1. Preparing for Change

📘
"Programming" and "software engineering" are different. If programming is just writing code, software engineering covers writing, changing, and maintaining it. You have to consider how time affects a program. Software Engineering at Google
 
In development, "change" is a companion you love and hate. Technology and paradigms keep evolving. Colleagues change. Leaders change. Requirements change. Code easily turns into a patchwork to meet requirements.
Becoming legacy is unavoidable. But how much you account for change at the design stage determines how long a project lives.
 
Here is how I prepared for change from several angles.
In short: "Work like a team, even when you're alone."
 
 

Separating the REST API

The renewed website uses Next.js for both Client and Server, and Supabase for the DB and Storage. With Supabase's JS SDK, even the client can query and modify DB data.
Separating the REST API - 1
Source: created by the author
 
 
But I thought about this:
💬
What if a backend developer joins and we need to switch to communicating with the server through a REST API?
 
It's the most likely staffing-change scenario. In that case, approach 1 would require converting every DB call made directly from the client into API calls to the server. As code piles up, that becomes a big job.
 
So from the start, I kept the traditional data flow where the client sends API requests to the server and receives responses. For the server role, I used Next.js API Routes. The Next.js API Routes talk to Supabase DB/Storage and return the results to the client.
Separating the REST API - 2
It's labeled "Next.js Server," but strictly speaking these are serverless functions running on the Next.js server side.
 
This way, if a backend developer joins and a separate server (ex. Spring) is built, the client can keep its current API design and calling code as is.
Separating the REST API - 3
 
It also keeps the benefits of a typical server-client data flow.
  • Intercept strategy for auth and HTTP status using an HTTP client library such as Axios
  • Stronger security through server-side DB access that is not exposed on the client
 
 

Documentation

When a fellow developer joins the team, they need the history. If it's recorded what requirements and context my code came from, and in what units of work it was built, that will help whenever someone needs a detailed understanding.
 
💬
On a development team this is standard practice, but it's very hard to be thorough when you develop alone. That's why I paid even more attention to it. I always wrote things down as if I were working with colleagues.
 
GitHub Issue
I created Issues based on work requirements or development goals. Nothing special.
GitHub Issue - 1
GitHub Issue - 2
 
GitHub Pull Request
Like most Pull Requests (PRs), mine summarize the code and changes for a specific work goal. I especially tried to leave at least some explanation for hard-to-understand or core logic.
GitHub Pull Request - 1
GitHub Pull Request - 2
 
To make PRs easy to find by label later, I created a variety of labels and used PR Labeler to apply them automatically in CI.
  • diff: size of the change
  • type: feature/bugfix, etc.
  • etc: special work such as Server, Test, Workflow
 
Writing PRs also takes documentation effort. I set up AI to write PRs automatically, show an overall code review of the changes in the dev environment, and even post the review as PR comments.
 
💬
Even so, I try to add at least a little "human touch."
  • I fill in what the AI missed and the parts where the developer put care into the design.
  • If AI fully automates PRs and reviews, human review and attention will inevitably shrink.
Until AI surpasses all the context and history people manage, we need a culture and system that keep human eyes and minds on the places that need them.
 
 
README
In a large project, it can be hard to understand how the project is structured, or even how to run it. You may also miss unusual conventions in a local part of the project. So I placed README.md files throughout the relevant domain folders to record how to run things, conventions, and design background.
readme - 1
readme - 2
 
These days, AI tools such as Deepwiki make it fairly easy to understand the structure of public projects. Developers can also easily write project structure docs with AI. In codex or claude code, you just type /init.
 
So these are the things I document:
  • Troubleshooting guides for things people easily miss or that depend on the environment
  • The designer's thinking, intent, and rationale behind conventions and structural design
The goal is that later, when what I considered in the design becomes "legacy" and better options exist, people can confidently replace the old design.
 
 

Rules and Systems

The smallest unit of work in development is the commit. I treat commits as meaningful records. They make it easy to see related file changes within one unit of work, let you trace the PR that contains them, and can serve as rollback checkpoints when needed.
 
Yet it's hard to keep up when you develop alone. You might think: "Nobody is reviewing my code, I'm rushing to ship, and you want strict commit rules? Sounds exhausting."
 
Of course, moving fast and delivering now matters. But I think the most important thing is that someone in the future can understand the intent and content of past work on a given file. Once time passes, that's hard to recover. So I created commit message rules and follow them strictly.
Following commit message rules
 
 
For rules to stick, you need a system that leaves no choice but to follow them.
I use lefthook as my git hook manager. It has a commit_msg job that runs at commit time. I wrote a shell script that checks commit messages against the rules and made that job run it.
git hook manager - lefthook
 
As a result, any commit that doesn't meet the commit message rules fails. The rules are a hassle, but I'd rather spread the effort out now than pass debt on to the next generation.
 
 

2-2. The Long Road over the Shortcut

The website renewal project moved very fast. We had to deliver maximum results in minimum time. But if you run staring only at your feet, you can trip at any moment and lose track of where you're going.
Here are my own cases of choosing between results now and maintainability later.
 
 
Going full-stack
I wasn't a full-stack developer on this project from the start. We began with 1 frontend and 1 backend developer, but the backend developer left the project. To keep the project going, we had no choice but to get backend support from another team.
 
But if it was temporary support rather than a formal assignment, I expected problems.
  • What about the work that backend developer is already handling?
  • Learning the history and redeveloping the backend server, plus the communication cost along the way
  • And uncertain maintenance after launch
Beyond the immediate cost, I thought it would be hard to sustain in the long run.
 
So after much thought, I decided: "Instead of getting backend support, I'll do the server development myself." I'm not a specialist backend developer, but I had the basics for building web applications, such as REST APIs, databases, and ERDs. On top of that, the ecosystem for full-stack development, including Supabase and Next.js, was well established.
 
My leader trusted me, and fortunately, here we are.
 
 
Monorepo design
Full-stack development inside a Next.js project has a nice benefit: the server and client can share much of their code within a single project. A monorepo has a similar benefit: related applications can share much of their code.
 
Monorepo design
 
Our monorepo currently has 2 applications: the website and the back office. Inquiries and applications submitted on the website must be displayed and managed in the back office with the same data types. In a monorepo, low-level shared code can be split into packages that each application uses.
 
With the monorepo, we unified code used in multiple places and improved maintainability and stability. These are 2 essentials for a project meant to go the distance.
 
💬
"But you can share code in a multi-repo setup too, not just a monorepo?"
Yes, you can share code across multiple repos with git submodule or subtree. But considering code similarity between applications, dependency management, and other code integration, I judged that a monorepo, with lower management complexity, was the better fit and chose it.
 
 

2-3. The Courage to Be Disliked

Ahead of the internal launch, important improvements kept piling up and we ran short on development time. My leader suggested: "Multilingual support takes time to set up, so let's build everything in Korean, duplicate it, and put in English translations."
 
That's how the pre-renewal website worked. There were separate PC/MO projects for responsive support, and each project had two identical sets of pages, one in Korean and one in English.
How the pre-renewal website was structured
 
Maintenance was hard, of course. Changing a single value meant editing 2 projects and 4 pages separately. Even minor changes took time and risked something being missed.
 
I strongly objected to choosing a future we knew would be bad just to handle the present. My view was well received, and we were able to adopt an efficient translation-key-based multilingual system.
 
Monorepo architecture
 
Stubbornness, in this case, is "the courage to be disliked": speaking up about a leader's decision for the sake of the project's future.
 
 

2-4. Being Replaceable at Any Time

📘
"Bus factor"
A measure of how many team members would have to be hit by a bus, and unable to work, before a project fails Software Engineering at Google
 
The world prizes being an "irreplaceable talent," someone uniquely valuable. From an individual's point of view, that's true.
But from the organization's point of view, losing an irreplaceable person is fatal to keeping a project going. That applies not only to voluntary reasons like changing jobs or quitting, but also to unavoidable ones like illness and accidents. Many software books call this the bus factor, or the lottery factor.
 
Think about solo development. Whether the developer is hit by a bus and can't work, or wins the lottery and quits, the project comes to a STOP. Going solo lets you move fast, but it's risky because there's no safety net for backup staff.
 
I want the code and systems I built to be handed over and maintained without problems, even when I'm not around.
  • I record plenty of history. Both AI and people have to put in the effort.
  • I put systems in place to design and enforce rules.
  • I shared development resources and access accounts with my leader in advance so they can respond in an emergency.
  • …
 
💬
I often tell my leader, "I'm preparing for a future without me." Unintentionally, it makes my leader nervous. Remember to explain what you mean.
 
 

3. Closing

3-1. Why We Changed the Website

💬
We're a B2B company. Does the website really matter that much?
EXEM is busy. We're even short on resources for building more stable, higher-quality products. In that situation, I want to explain why we pushed for a website renewal.
 
WHY
EXEM is a B2B company. B2B customers are not the general public but a small number of client companies. Revenue comes from contracts. If we win contracts, the website doesn't seem that important, and maybe we don't need one at all. But is that really true?
 
Yes, it's true. EXEM builds great services and sells well. Revenue today is not a concern. EXEM is strong today.
 
That's why we are preparing for EXEM's future. We wanted to achieve these goals:
  • We want to build EXEM's image as a more professional, sophisticated tech company.
  • We want to show our well-built services even better, and the right way.
  • We want anyone in our industry to know EXEM as a matter of course.
  • We want to notice first when someone shows even a little interest in EXEM.
  • We want customers to sign up for more services even when sales does a bit less legwork.
The point to focus on is "draw customers to us, notice the customers who reach us, and never let them slip away." So we thought hard about what we needed to do.
 
 
WHAT
So this is what we're doing.
 
💬
Change, and innovation beyond it
Over the past 25 years, EXEM has built its track record and reputation in the monitoring industry. We call the spirit, technology, and time of those who came before us our "legacy." Technology now changes every week. We need to keep pace and move even faster. We adapt to the times. We dare to say we will usher in a new generation.
 
That's why we pushed forward with EXEM's rebranding. I start to write "more ___" and then delete it. This isn't an improvement. It's a transformation. We're changing EXEM's logo, services, and external documents. We're changing our design, marketing, and branding.
 
And so the website changed too. It captures much of what has changed alongside it, and it will capture much more that is still to change.
 

3-2. Final Words

EXEM website renewal project development
 
So far, I've shared the experiences from developing the EXEM website renewal project, along with the convictions and values I tried to hold to. I hope you'll read it as a development story about the circumstances and the developer's thinking behind the new start of the EXEM site.
Among so many developers, being the one to renew the website that represents the company brought both excitement and pressure. I worked hard not to let EXEM and my colleagues down, and I'm grateful it bore fruit.
 
EXEM is a group of experts. Many EXEM colleagues are writing their own stories based on their expertise and experience right now. I'm looking forward to the voices this space will hold.
 
I hope EXEM's new website becomes the signal flare that spreads the word about EXEM's sophistication and expertise. I'll keep working to capture EXEM's technology and stories in even more varied ways. Thank you.
 
 

 
 

 
 
Recommended articles