//TIM.CHAO
Primarily translated by AI
Part of AI-DRIVEN DEVELOPMENT: BUILDING A PERSONAL BRAND SITE FROM SCRATCH · PART 3

Architecture & Implementation: Coding with Semantic Tools

April 9, 20266 MIN READAI

The design is finalized, the plan is in place, and it’s finally time to start writing code. But with AI tools available, “writing code” is very different from how it used to be. This post covers how I chose the technology, how I used semantic tools to navigate and edit code, and my hands-on experience of moving forward step by step according to the plan.

Technology Selection: Why These Choices

The tech stack was already decided during the spec phase, but here’s a brief explanation of the rationale behind the choices:

  • Next.js App Router: Server Components make data loading cleaner by eliminating the need to shuttling data back and forth between the client and server. The nested layout of the App Router also fits the structure of this website perfectly (public pages and the admin backend share the outer layer, but the inner layers are completely different).

  • Prisma ORM: Type-safe database operations where the schema is the documentation. Migration management is also more reliable than hand-written SQL.

  • Trilingual i18n: Using the translation group model—each piece of content has a `translationGroupId`, and records for zh-TW, en, and ja within the same group are linked via this ID. This is more flexible than embedding translations in JSON fields and makes querying easier.

  • pCloud Image Storage: Moved images from the database to external storage to prevent the database from bloating. pCloud’s API is simple enough; after uploading, you can use the URL immediately.

Serena MCP: Understand the Code Before You Code

One of the tools that impressed me most in this project is Serena MCP. It’s a semantic code navigation tool—unlike standard text search, it understands the structure of the code.

For example, if you want to know “where the `Article` model is referenced,” using `grep` to search for the string might return a bunch of irrelevant results. But Serena’s `find_referencing_symbols` can precisely tell you which functions and components actually use this model.

Here are a few of my most frequently used features:

  • `get_symbols_overview`: See which functions, classes, and interfaces are in a file, allowing you to grasp the structure without reading the entire file

  • `find_symbol`: Finds specific functions or type definitions using a name or path, such as `ArticleEditor/handleSave`

  • `replace_symbol_body`: Precisely replace the implementation of a specific function without affecting other parts of the file

  • `insert_after_symbol`: Inserts new code after a specific function, preserving the integrity of the file’s structure

What these operations have in common is that they operate on "semantic units of code" rather than "lines of text." This makes code modifications much more precise and significantly reduces the risk of fixing one issue while breaking another.

execute-plan: Proceed according to the list

Once a plan is in place, the `execute-plan` skill is used during the implementation phase. Its operation is straightforward: it reads the task list from the plan file, executes each task one by one, and checks them off as they are completed.

Each task typically includes:

  • The file path to be created or modified

  • The specific code content

  • Testing or validation commands to run upon completion

The benefit of this process is that it maintains a steady rhythm. You won’t get stuck wondering, “What’s next after this?” because everything is already laid out in the plan. You commit after completing each task, so looking back at the git log reveals a clear timeline of progress.

pCloud Migration: A Practical Example

Here’s a concrete example from my experience. Originally, images were stored in the database (in base64 format), but as the number of photos grew, the database size became a problem.

This task was broken down into several steps in the plan:

  • Create a pCloud API client

  • Modify the upload action to save the URL after uploading to pCloud

  • Write a one-time migration script to move existing images to pCloud

  • Remove the old Image model and related API routes

Each step is independently testable. Once the pCloud client is ready, the upload functionality can be tested on its own without waiting for the entire migration to complete. This approach makes large-scale refactoring less daunting.

My approach to coding has changed

Looking back, with these tools in place, the way I write code has indeed changed. Before, I would open a file, read it from start to finish, make changes, and then hope nothing broke. Now, I first use Serena to understand the structure, use the plan to confirm the direction, make modifications with precise semantic operations, and follow clear validation steps after making changes.

This doesn’t mean the tools write all the code for you—technical decisions and design judgments are still your responsibility. But they do make the process of “turning ideas into code” more organized and predictable.

In the next post, I’ll discuss the auxiliary tools that make the development process smoother—how RTK helps you save tokens, how Context7 lets you find the latest documentation, and how the automatic translation system works.