Tech ·

My First Tech Blog: Writing Whatever Comes to Mind


AI-polished translation · Read the original hand-typed draft (Chinese) →

TL;DR: In full-stack work, don’t build the front end before the back end. Nail down the backend logic and exactly what data you’re going to render first — then the front end falls into place on its own.

This is my first real tech blog. The title — “writing whatever comes to mind” — is the honest description: it started as a loose set of notes. What follows is a cleaned-up version of that original draft.

A trap I keep falling into: don’t start from the front end

When I’m vibe coding, a huge amount of my time actually goes into endlessly tweaking front-end styling. I won’t dodge the matter of taste — aesthetics genuinely have to be refined bit by bit. But the thing that really slows me down is the seam between front and back end: data rendering.

The front-end prototypes AI generates are almost always over-designed. And my old habit was exactly backwards — I’d write the HTML first, then circle back to design the backend interface. The result: when building a new feature, starting from the front end usually wastes a ton of time.

The order should be flipped — design the backend API and data structures first: figure out exactly what data you need to render, and only then decide how the front end should display it.

On the front end: let the backend data lead

Following from the last section: the prerequisite for writing the front end is settling what data the backend will render. Only once the backend data is well designed can the front end avoid over-designing and stop accreting logic and fields it never needed.

Pick a skeleton framework first

Choose a base framework as the skeleton layer for your AI front end — something like ai-elements, assistant-ui, or shadcn/ui.

The most exhausting part of vibe coding is still taste. Because everyone uses the same frameworks, what they render is, to a large degree, “uniformly plain, uniformly characterless.” I’m not claiming I have great taste either — I’m rolling the gacha too.

Don’t write production code straight from the components

Once the components are installed, don’t rush to write production code with them directly. My process:

  1. In the project’s design/ folder, write an HTML version of a given feature in three different design directions;
  2. Pick the direction you want. There are usually only two outcomes: one direction is right, or all three are mediocre;
  3. If none satisfy you, keep rolling the gacha, or paste a screenshot of some SaaS platform / product and let the AI keep generating;
  4. Once a direction is set and you want to compare finer details, write a few HTML variants within that direction;
  5. When everything’s ready, port it into the production component.

Distilling design primitives (Design Primitive)

As the project iterates and the codebase grows, features pile up, and following the process above, the design/ folder accumulates a lot of content.

So how do you carry your earlier design preferences and style into new features? My approach: have the AI read through design/, then organize and summarize the design style and primitives. After that you can reuse the general-purpose assets you already have, and new designs reference these primitives (Design Primitive). Once the product’s overall tone is more or less locked in, the odds of a failed “style gacha roll” drop too.

There’s another path: design the primitives up front, before the project even starts, rather than deriving them during development. To customize ahead of time, you need to think through a few things first:

  • The project’s main features
  • The target audience
  • Minimalist style or media-rich style, and so on
  • The planned features and interaction patterns

The AI will reference these features and the intended direction to design the primitives and set the tonal baseline. But this path demands an overall, up-front assessment and plan for the project — and if you haven’t even figured out what you want to build, I don’t think it’s a good starting point.

A thought sparked by Flue: is the agent harness already a thing of the past?

Flue is an open-source framework built on top of Pi Coding Agent that lets you freely define — and cluster — agents. Vercel has shipped a related product too, Eve, but Eve is tightly bound to Vercel’s platform capabilities and depends on its sandbox — meaning you’re forced to marry into the Vercel ecosystem.

That kind of hard lock-in is actually pretty risky. The recent Fable 5 ban and the delay of GPT-5.6 are all reminders of how much in-house capability — and open source — matters. I spent over a month studying Agent Sandbox, and I’d assumed Daytona Sandbox was a solid open-source solution — but this week it went closed-source too: its latest commits on GitHub were all wiped and it’s no longer maintained. Feels like I’m pivoting back to E2B sandbox.

Whether it’s software or models, there are plenty of excellent open-source projects, but you still have to read some of the underlying implementation — because a lot of them go closed-source the longer they run, gradually turning commercial. That’s the trend, and it’s inevitable; I get it.

What I actually want to say: maybe the harness doesn’t matter that much anymore

Talking about open source isn’t really the point. What I want to say is: given the capability of today’s models, I don’t think the harness is the point anymore.

Give it a Bash tool, plus a few task-specific tools your project needs, in a given environment, and the AI can basically get 80% of the work done. The earlier Claude Code source leak exposed a lot of details about harness engineering — but what I took away from Pi Coding Agent is this: simple tools can achieve almost the same performance as a closed-source framework.

Maybe the next phase isn’t about being a “harness engineer.”

Software is looking more and more like a black box. We used to say models had too many parameters and low interpretability; now software seems to be heading the same way — a lot of it is generated from a single sentence, natural-language programming, where many people don’t know the underlying logic and only know “this feature works,” nobody cares about the detail. AI generation keeps getting faster, the volume of code keeps growing, and no single person can review it all. That’s normal, and I admit it’s the trend. I don’t know how software will evolve, but I keep getting the feeling that software itself is becoming something optimizable, something you can gradient-descend on — like training a model.

How Flue actually feels to use

I’ve drifted again. The way Flue feels in practice: you give it a goal, a direction to optimize toward, then run, run, run, and wait for the output — nobody cares about the intermediate steps. That was my first impression of it. Its best fit is probably PR review, issue replies, and long-running tasks.

Defining an agent with Flue feels more like hiring someone to do exactly one thing: you just provide the skills and the tools, and hand the rest to the agent — the engine — to run.


A closing note: I feel like my writing has gotten noticeably worse, so I need to write more by hand from now on and slowly get my expression back. Even for AI-polished content, I’ll flag it and provide the original hand-typed draft.