This article documents a real AI-assisted refactoring journey. Starting from a simple Next.js application with only a JSON formatter, I used Claude and the principles of Harness Engineering to evolve it into a multilingual toolbox with more than 80 online utilities, automated SEO, and a scalable architecture. More importantly, it shows how engineering rules gradually replaced developer memory.
Background: A Simple Project That Couldn’t Scale
Website: https://toolgarden.xyz
During everyday development, I constantly found myself opening different online tools:
- JSON Formatter
- Image Converter
- PDF Tools
- Base64 Encoder and Decoder
- URL Encoder
- File Conversion
- Markdown Utilities
Every tool lived on a different website. Switching back and forth was annoying, and most searches ended with pages full of ads.
So I decided to build my own online toolbox with AI—one website where I could access everything without searching every time.
Initially, the project was extremely simple. It was a standard create-next-app project with a single /json-format page.
app/
page.tsx
json-format/
page.tsx
components/
Header.tsx
Footer.tsxThe json-format/page.tsx file handled everything:
- UI rendering
- State management
- JSON parsing
- JSON formatting
- Error handling
- Tree view rendering
Adding a second tool, such as JSON Diff, meant copying an existing page, updating the homepage, adding navigation links, updating breadcrumbs, editing the sitemap, and configuring SEO.
Every new feature required remembering several unrelated modifications scattered across the project. This is a classic example of cognitive debt: the architecture depended on the developer’s memory instead of constraints enforced by the code itself.
Internationalization and SEO were equally painful. Almost every page needed manual updates. The project worked, but it clearly was not designed to scale.
What Is Harness Engineering?
Building a control layer around AI so software development becomes stable, repeatable, and reliable.
The Harness is not the AI itself. It is the infrastructure connecting developers, AI, the codebase, and development tools.
A Harness is responsible for:
- Providing consistent context
- Invoking tools
- Executing code
- Validating outputs
- Automatically fixing errors
- Ensuring output quality
| Prompt Engineering | Harness Engineering |
|---|---|
| Optimizing prompts | Designing the entire AI workflow |
| Better input | Better system |
| One-shot generation | Multi-step execution |
| AI output is the end | AI output is the beginning |
| Manual verification | Automated validation |
Harness Engineering is not a specific design pattern. It is an engineering philosophy that encourages projects to grow under constraints instead of relying on developer discipline.
Anything repetitive, easy to forget, or purely mechanical should be automated.
What Claude Changed
1. Creating a Single Source of Truth
The first step was introducing lib/tools/registry.ts. This became the project’s single source of truth.
export const toolRegistry = [
{
id: "json-format",
category: "format",
path: "/json-format"
}
]The homepage tool list, categories, navigation, breadcrumbs, sitemap, recommended tools, and SEO metadata are now derived from this registry.
Adding a new tool only requires registering it once. Everything else updates automatically.
Which files do I need to modify this time?
2. Introducing a Unified Tool Layout
Previously every page maintained its own title, description, breadcrumbs, JSON-LD, SEO metadata, and responsive layout.
Now every tool page follows the same small composition:
export default function JsonFormatPage() {
return (
<ToolLayout toolId="json-format">
<JsonFormatClient />
</ToolLayout>
);
}ToolLayout became responsible for everything shared across the project. Each tool only implements its own interactions.
3. Building a Clear Layered Architecture
Claude reorganized the project into clear layers:
lib/
utils/
tools/
registry.ts
seo.ts
sitemap.ts
components/
ui/
tools/
app/
[locale]/Each layer has a single responsibility. Pages handle state, events, and rendering. Business logic lives in lib/utils, while components focus on presentation.
For example, JSON formatting became a pure utility function:
export function formatJSON(input: string) {
// Parsing and formatting live in a pure utility.
// The function returns an outcome instead of mutating UI state.
}The page simply calls it:
const result = formatJSON(input);This makes the logic easy to unit test, independent of React and the DOM, and reusable in command-line tools or Workers. Business logic became framework-independent.
4. Replacing Colors with Semantic Design Tokens
Hard-coded colors disappeared. Instead of raw Tailwind color classes:
bg-gray-100
text-gray-500The project now uses semantic tokens:
--surface
--content-muted
--action- Easier dark mode support
- Easier branding
- Better theme customization
- No global search-and-replace for colors
Components no longer need to know what the colors actually are.
5. Engineering SEO Instead of Maintaining It
For a toolbox website, search engines are a primary discovery channel, so SEO should not be manually maintained.
The project automatically generates:
- sitemap.xml
- robots.txt
- canonical URLs
- hreflang
- Open Graph metadata
- JSON-LD
- llms.txt
- llms-full.txt
Everything is derived from the registry. Adding a tool requires zero repeated SEO maintenance.
6. Standardizing Responsive Design
Many UX improvements also became conventions:
- Editors automatically fill available space
- Two-column layouts adapt to large screens
- Fixed 40vh layouts are avoided
- The editing experience remains usable on small screens
- Spacing stays consistent across tools
These can look like small details, but once a site has dozens of tools, consistency becomes a product feature.
7. Turning Experience into Documentation
Finally, all engineering constraints were documented in two repository-level guides:
AGENTS.md
CLAUDE.mdThese documents define the project architecture, development workflow, naming conventions, the process for adding a tool, and guidelines for AI-assisted coding.
This was arguably the most valuable step. The most durable asset is not just the current code; it is the set of rules that guides future development.
The Harness Engineering Rules
The refactoring eventually evolved into a set of explicit engineering principles.
Rule 1 — Single Source of Truth
All tool definitions live in lib/tools/registry.ts. Configuration should never be duplicated.
Rule 2 — Everything Is Registry Driven
The homepage, categories, recommendations, breadcrumbs, and sitemap should always be generated automatically. Nothing should be manually synchronized.
Rule 3 — Adding a Tool Has a Fixed Workflow
A new tool requires a fixed sequence:
- Register it
- Add translations
- Implement utilities
- Create the page
- Wrap it with ToolLayout and reuse the metadata harness
If adding a tool requires another manually synchronized discovery step, the architecture should be improved.
Rule 4 — Keep Pages Thin
Pages should contain state, events, and rendering. Business logic should not live directly inside page components.
Rule 5 — Prefer Pure Functions
Business logic belongs in:
lib/utils- No React
- No DOM
- No side effects
- Fully testable
Rule 6 — Every Tool Uses the Same Layout
Every tool page uses the shared layout contract:
<ToolLayout />Consistency comes by default instead of through repeated page code.
Rule 7 — SEO Must Be Automatic
Every new tool automatically receives metadata, JSON-LD, sitemap entries, and llms.txt discovery without a separate checklist of handwritten SEO files.
Rule 8 — Always Use Semantic Tokens
Avoid raw color utilities:
text-gray-500
bg-red-100Prefer semantic tokens:
text-content-muted
bg-surfaceThis keeps themes independent from components.
Rule 9 — Even the 404 Page Is Part of the System
404 pages should support internationalization and show registry-driven tool recommendations. No page should become an isolated exception.
Rule 10 — Validation Is Part of Development
Every structural change must pass the same validation gates:
npm run lint
npx tsc --noEmit
npm run buildThe final step is testing the result in a real browser, including layout, interaction, console errors, 404 behavior, and SEO metadata.
The Results
After this refactoring, the project evolved from a single JSON formatter into a toolbox containing more than 80 online utilities.
Adding new tools became a repeatable workflow instead of a collection of manual updates. More importantly, the project became capable of continuous evolution.
- Maintenance cost no longer grows linearly with the number of tools
- SEO is inherited automatically
- Navigation updates itself
- Internationalization scales naturally
- Business logic stays reusable
- AI follows established rules instead of rediscovering the project structure every time
Final Thoughts
Harness Engineering is not about making architecture look elegant. Its purpose is practical: keeping a project consistent, maintainable, and scalable while it continues to grow.
Build the rails first, then let new features grow along them.
Once those rails exist, developers no longer need to remember which files must be updated, worry about missing SEO metadata, or chase inconsistent UI patterns.
Let the system remember the repetitive work. Save human attention for solving real problems.