# Organic Software Is Not Vibe Coding

Source: https://www.bobzhu.tech/organic-software/
Markdown: https://www.bobzhu.tech/assets/agents/organic-software.md
Tags: Essays, AI, Systems

Summary: Organic software is expert-led, AI-assisted software that grows through real use. It is dynamic, but not loose: the builder keeps changing the app as the work reveals itself, while using judgement, tests, and feedback to stop the system from becoming a mess.

Feature image: https://storage.ghost.io/c/ea/80/ea80b01b-c9d0-45fd-a95f-5fbcd52ed925/content/images/2026/07/organic-software-feature.png
Feature image alt: A hand-drawn desk-garden scene where a software interface grows from an open notebook, with pruning shears and connected app windows around it.
Feature image caption: Organic software is software that grows, but only because someone keeps tending it.

I keep wanting a better phrase than vibe coding.

Not because the phrase is useless. It describes a real change: you can now sit with an AI coding tool, describe what you want, and watch software appear faster than it used to.

But it is too loose for the kind of building I care about.

The interesting version is not a person prompting their way through an app they do not understand. It is a person who understands the work very well, using AI to keep the software close to that work as it changes.

That is what I mean by organic software.

It starts small. It grows through use. It gets pruned when it becomes messy. It keeps a memory of why decisions were made. It is dynamic, but it is not careless.

## The app changes while I build it

Most useful software does not reveal itself all at once.

You build the first version. You use it. Something feels clumsy. A field is missing. A step appears in the real workflow that was invisible in the plan. A user does something sensible that the interface did not expect.

The old response was to collect those observations for the next sprint, next release, or next rebuild. Now you inspect the code, describe the change, ask an agent to help, review the diff, test the behaviour, and keep going.

That can look casual from the outside. It is not casual when done well.

The builder is making continuous product and engineering judgements: which changes are real, which are noise, which shortcuts are safe, and which parts of the app need to remain stable.

## Why vibe coding is too soft a label

Vibe coding has become the popular shorthand for natural-language software creation. It is useful as a cultural marker, especially now that the phrase has moved beyond developer circles and into mainstream discussion.

One version is exploratory prompting: describe a thing, accept a thing, keep poking until the result looks close enough.

The other version is expert-led building with AI in the loop. The expert may still use plain language. They may still move quickly. But they are not outsourcing judgement. They are using AI to compress implementation time while keeping responsibility for the system.

Organic software belongs to the second category.

AI does not remove the need for expertise. It increases the amount of change a person can attempt, which means it also increases the surface area of judgement.

## A better metaphor is gardening

Organic software is closer to gardening than magic.

A seed is the smallest useful version. Soil is the domain context around it: users, constraints, examples, data, policies, habits, edge cases. Pruning is the discipline of removing features, flows, abstractions, and screens that looked promising but made the app weaker.

Grafting is when a new capability can attach to the existing trunk without breaking it.

Seasons matter too. A personal tool can be rougher. A team tool needs clearer copy, better empty states, stronger error handling, and more stable expectations. The same app can move through those phases, but it should not pretend they are the same phase.

This is where organic software differs from loose improvisation. A garden changes constantly, but it still has structure. If everything grows everywhere, you do not have a garden. You have weeds.

## The operating loop

The loop is simple enough to write down:

1. observe the work
2. build the smallest useful change
3. use it in the real workflow
4. capture friction
5. ask the agent to implement within constraints
6. review the diff and behaviour
7. add tests, examples, notes, or guardrails
8. repeat
<figure class="kg-card kg-image-card kg-card-hascaption">
  <img class="kg-image" src="https://storage.ghost.io/c/ea/80/ea80b01b-c9d0-45fd-a95f-5fbcd52ed925/content/images/2026/07/organic-software-operating-loop.png" alt="A hand-drawn loop of notebook cards, app windows, check marks, pruning shears, and a central seedling showing an inspected software change cycle.">
  <figcaption>The loop only works when each change is small enough to inspect before it becomes part of the system.</figcaption>
</figure>
The important part is not the speed. It is the inspection.

A faster loop without inspection only produces faster drift. The app accumulates features without a spine. The codebase starts reflecting every recent request. The interface becomes a record of indecision.
<div class="reader-artifact reader-artifact-linear" data-reader-artifact="linear">
  <div class="reader-linear-header">
    <span class="reader-linear-key">OS-01</span>
    <span class="reader-linear-status">Inspected loop</span>
  </div>
  <h3 class="reader-artifact-title reader-linear-title">Keep the change small enough to judge</h3>
  <p class="reader-linear-summary">Organic building works when the next change can be reviewed against the work, not just accepted because the agent produced it.</p>
  <div class="reader-linear-meta">
    <span>Scope: one useful change</span>
    <span>Risk: drift</span>
    <span>Check: behaviour first</span>
  </div>
  <div class="reader-linear-track">
    <div class="reader-linear-step is-done">
      <div>
        <p class="reader-linear-step-title">Observe the real workflow</p>
        <p class="reader-linear-step-note">Name the friction before asking the agent to change anything.</p>
      </div>
      <span class="reader-linear-estimate">done</span>
    </div>
    <div class="reader-linear-step is-active">
      <div>
        <p class="reader-linear-step-title">Ship one bounded change</p>
        <p class="reader-linear-step-note">Keep the diff small enough that a human can still hold the intent.</p>
      </div>
      <span class="reader-linear-estimate">now</span>
    </div>
    <div class="reader-linear-step">
      <div>
        <p class="reader-linear-step-title">Review, test, and prune</p>
        <p class="reader-linear-step-note">Decide whether the change strengthens the app or only adds motion.</p>
      </div>
      <span class="reader-linear-estimate">next</span>
    </div>
  </div>
</div>
This is the same reason [AI does not automatically give you time back](https://www.bobzhu.tech/ai-does-not-automatically-give-you-time-back/). Faster output can make the work denser unless the surrounding loop changes.

## Where expertise enters

Expertise enters in four places.

First, domain taste. You know what the app should refuse to do. You can tell when a feature request is really a workflow problem. You can see when a technically impressive answer would make the actual work worse.

Second, technical judgement. You know when a shortcut is fine for a personal prototype and when it is creating debt that will slow every future change.

Third, product judgement. You can distinguish a missing capability from a missing explanation. You can decide whether the next change should be a new screen, a better default, a clearer empty state, or no change at all.

Fourth, evaluation judgement. You know what would count as better. Without that, AI-assisted building becomes a sequence of plausible changes with no reliable measure of improvement.

That is why this is not just a tool question. The same coding agent can produce very different outcomes depending on the operating behaviour around it. I made the [AI Proficiency Self-Assessment](https://www.bobzhu.tech/ai-proficiency-quiz/) for that reason: the product label matters less than how much context, action, autonomy, and verification the workflow actually has.

## The discipline that keeps it alive

Organic software needs a product spine.

The spine is short:

- who the app is for
- what work it supports
- what the smallest useful version is
- what it should not become
- what evidence would justify the next change
<div class="reader-artifact reader-artifact-notion" data-reader-artifact="notion">
  <div class="reader-notion-header">
    <span class="reader-notion-view">Product spine</span>
    <h3 class="reader-notion-title">The questions that stop the app from sprawling</h3>
    <p class="reader-notion-summary">A short spine gives both the builder and the agent something to check against.</p>
  </div>
  <div class="reader-notion-table">
    <div class="reader-notion-row is-header">
      <span class="reader-notion-cell">Part</span>
      <span class="reader-notion-cell">Question</span>
      <span class="reader-notion-cell">Failure mode</span>
    </div>
    <div class="reader-notion-row">
      <span class="reader-notion-cell" data-reader-label="Part"><strong>Promise</strong></span>
      <span class="reader-notion-cell" data-reader-label="Question">What work should this make easier?</span>
      <span class="reader-notion-cell" data-reader-label="Failure mode">The app becomes a pile of features.</span>
    </div>
    <div class="reader-notion-row">
      <span class="reader-notion-cell" data-reader-label="Part"><strong>Boundary</strong></span>
      <span class="reader-notion-cell" data-reader-label="Question">What should it refuse to become?</span>
      <span class="reader-notion-cell" data-reader-label="Failure mode">Every new request looks equally valid.</span>
    </div>
    <div class="reader-notion-row">
      <span class="reader-notion-cell" data-reader-label="Part"><strong>Evidence</strong></span>
      <span class="reader-notion-cell" data-reader-label="Question">What would prove the next change helped?</span>
      <span class="reader-notion-cell" data-reader-label="Failure mode">The loop gets faster but less reliable.</span>
    </div>
  </div>
</div>
It also needs a living decision log. Not a huge document. Just enough memory that future-you, or an AI coding agent, can see why the app took its current shape.

Tests and examples act like roots. They keep the system attached to behaviours that should not break. Notes and constraints act like labels in the garden. They stop the next change from trampling the last good decision.

The working posture is: let the app grow, but do not let it sprawl.

## A companion planner

I want to turn this into a small tool: an [Organic Software Planner](https://www.bobzhu.tech/organic-software-planner/).

The planner would help a builder write the product spine, growth loop, pruning rules, AI build packet, and release rings before opening a coding agent.

The useful output would not be a giant specification. It would be a compact brief you can paste into a coding agent, plus a review checklist that keeps you in control of the result.

That feels like the right companion to the idea. The article explains the posture. The tool helps someone practise it.

## Software closer to the work

The promise of organic software is not that AI makes software effortless.

The promise is that a good builder can keep software closer to the work. They can make smaller changes sooner. They can learn from use while the idea is still alive. They can prune before the system hardens into something awkward.

It is dynamic software, but it is not vibe-only software.
