evolv.ai - ideas that grow with you

We started with a simple question: why does most AI image editing feel like a coin toss? Nature doesn’t work that way. It improves through small changes and selection - variation, evaluation, inheritance, repeat. We wondered what would happen if an editor worked the same way: highlight a part of an image, ask for a change, get a handful of options, pick the best, then keep going. That became evolv.ai.

What inspired us

Biology’s incrementalism. Instead of chasing a perfect one-shot prompt, we wanted a tool that behaves like evolution: generate modest variations, select the “fittest,” and carry that forward.

How we built it

We built a web app that feels like a conversation. You upload an image, draw a region you want to change, write a short prompt, and the system returns four variants. You pick one, it becomes the new state, and you repeat.

  • Frontend: Next.js (App Router) with a small canvas editor that bakes the “mask” into the pixels client-side. That lets us send a single image per round and keep the API simple. The chat UI shows prompts and images as messages, with a picker grid for the four variants.
  • Backend: Flask with a thin, composable API.

    • POST /conversations creates a thread from a base image and returns the server URL and conversation id.
    • POST /conversations/{id}/edits accepts a “modified” image (the one with the selected area baked in) and a prompt, then produces four variants.
    • POST /conversations/{id}/select advances the thread to the chosen image.
    • GET /images/{id} serves PNGs by numeric id. We store files on disk under originals/, modified/, and outputs/, and map ids to paths in SQLite. A tiny messages table logs each user edit, the four generated outputs, and the eventual selection so we can reconstruct or branch.
  • Model layer: a stubbed generate_four_edits_from_two_bytes(mod, orig, prompt) that can be swapped for any inpainting/edit model later. The contract stays the same: return four images, we store and serve them.

This architecture is intentionally boring: the frontend owns the editing experience; the backend is a generator and an append-only memory.

What we learned

We learned that “human in the loop” isn’t a slogan; it’s an interface constraint. When we reduced the problem to “four good options and a clear choice,” prompts got shorter, edits got more precise, and users stopped fighting the tool.

We learned that state is product. By logging each round as messages (edit → generation → selection), we made pause, resume, and branching free. The history isn’t just for audit; it’s creative memory.

We also learned to prefer edge simplicity over purity. Baking masks into the image on the client means no special file formats, no complex decode on the server, and fewer failure modes.

Challenges we faced

  • Canvas and CORS. Loading server images into a canvas without tainting it required proper CORS headers on GET /images/:id and careful fetch(..., { cache: "no-store" }) to avoid stale pixels.
  • Conversation semantics. We needed to handle “open review” (four outputs generated, no selection yet) so users could switch threads mid-step. Logging a generation without a following selection gave us a clean resume point.
  • Keeping the API minimal. It’s tempting to add knobs (negative prompts, seeds, samplers). We resisted. For the MVP, four variants and a short prompt are enough. The loop carries the intent.

Why this matters

Most AI editing tools ask you to be a poet who is also a scientist. Nature doesn’t. It asks you to notice, choose, and keep going. Evolv is that idea made practical for images: a small, sturdy loop where variation comes from the model and selection comes from you.

If you want the math-y epilogue, the “sum of small wins” view is:

$$ \text{Result} \approx \sum_{t=1}^{T} \Big( \underbrace{\text{Variation}(\text{state}t,\ \text{prompt}_t)}{\text{model}} \xrightarrow{\ \text{selection}\ } \underbrace{\text{state}{t+1}}{\text{you}} \Big) $$

but the real story is simpler: highlight, generate, pick, repeat. It’s a natural process, and it makes creativity feel a lot more human.

Built With

Share this project:

Updates