DEV Community

Cover image for Building an AI Side Project That Actually Ships — Lessons from Shipping 3 MVPs
Shaw Sha
Shaw Sha

Posted on

Building an AI Side Project That Actually Ships — Lessons from Shipping 3 MVPs

Listen, I have the hard drive graveyard to prove it. Most of my AI side projects have a lifespan of about two weeks. They start with a burst of excitement—"I'm going to build the ultimate AI writing assistant!"—and end with a directory full of half-finished Jupyter notebooks, a dead docker-compose.yml for a local LLM, and a $120 bill from a GPU rental I forgot to shut down.

But something clicked in the last two months. I shipped three MVPs. Three actual products that people used, gave feedback on, and one even made a little money.

The dirty secret? I barely touched a model. I stopped treating AI as the science experiment and started treating it like a utility. Here is exactly how I shifted my mindset, and the boring infrastructure choices that made it possible.

The Graveyard of GPU Dreams

My first project was a content repurposer. The idea was solid: take a blog post, get an AI to rewrite it for Twitter, LinkedIn, and a newsletter.

The execution was a nightmare. I decided I had to run it locally. "No vendor lock-in!" I told myself. I spent a week getting Ollama to work. Another week trying to get the context window large enough. Another week trying to fine-tune it on my writing style. Three weeks in, I had a lot of terminal output, a few half-baked responses, and zero users.

The project died before it ever saw a single API call from a browser.

I realized I was optimizing for the wrong thing. I wasn't building a model. I was building a product. And the fastest way to build a product is to assume the AI is a solved problem and just call it.

Lesson 1: The API is just a function call

The moment I stopped caring about where the intelligence came from and started caring about what it produced, my velocity exploded.

I built my second MVP, a simple "Feedback Classifier" for a SaaS landing page. It took a string of text and decided if it was a Bug, a Feature Request, or Praise.

Here is the entire backend logic for the AI part:

# file: classify.py
# The hardest part of this was importing the library
from openai import OpenAI
import os

client = OpenAI(api_key=os.getenv("AI_API_KEY"))

def classify_feedback(text: str) -> str:
    response = client.chat.completions.create(
        model="gpt-4o-mini",  # Cheap, fast, good enough
        messages=[
            {"role": "system", "content": "You are a product manager. Classify the following user feedback into exactly one of these categories: 'Bug', 'Feature Request', 'Other'. Return only the category name."},
            {"role": "user", "content": text}
        ],
        max_tokens=10,
        temperature=0
    )
    return response.choices[0].message.content.strip()
Enter fullscreen mode Exit fullscreen mode

That’s it. No CUDA, no Docker containers eating my RAM, no llama.cpp compilation errors. Just a function call.

This project was live in 3 days. I didn't even have a database at first. It just logged the results to a text file and sent me an email.

The lesson is brutal but simple: If you are a solo developer building an MVP, you do not have the time or money to compete with OpenAI's infrastructure. Stop trying. Just use theirs.

Lesson 2: The Swiss Army Knife is a Trap

My second project died because I wanted it to do everything. "AI Marketing Assistant!"

It was going to write emails, analyze competitors, generate images, run SEO checks, and summarize Slack threads. I built the UI for six different features. I got the wireframes done. I hooked up the DALL-E API. I started on the SEO checker.

I never finished.

Scope creep is the silent killer of AI projects. The allure of "just add another prompt" is too strong. You end up with a dozen mediocre features and zero users.

Project 3 was different. Project 3 was a Changelog Generator.

It does one thing:

  1. You paste in a git log.
  2. It writes release notes.

That's it. One text area. One button. One API call.

# The "integration" for the user
git log --oneline -10 | pbcopy
# Paste into web app, get release notes.
Enter fullscreen mode Exit fullscreen mode

It took me 6 hours to build the whole thing. It got its first user that same week. Why? Because it solved a single, sharp pain point. Nobody likes writing release notes. My app didn't try to do their taxes or write their TPS reports.

Ship a laser, not a Swiss Army knife.

Lesson 3: Speed is the Feature

You know what users love? Watching the text stream into the box.

I spent zero time on a design system for the Changelog app. It's a vanilla HTML page with a bit of Tailwind CSS. But I spent time making the response stream.

// The "wow" feature: streaming
const response = await fetch('/api/generate', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ log: gitLog })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    outputDiv.innerHTML += decoder.decode(value);
}
Enter fullscreen mode Exit fullscreen mode

Users told me it felt "magical." Not because of the model, but because they saw the work happening in real time.

Your first user doesn't care if you used React or jQuery or a stone tablet. They care if the result is useful and fast.

Lesson 4: Infrastructure is your Unseen Co-Founder

This is the part that usually gets glossed over in "How I built an AI app" blog posts, but it's the reason I actually shipped three things.

I tried the indie hacker route.

  • RunPod / Vast.ai: Cheap GPUs, but managing containers for inference is a part-time job. I spent more time writing Dockerfiles than writing app code.
  • Vercel AI SDK: Amazing developer experience, but the pricing for the hosting + API calls didn't match my "free-tier for beta testers" model.
  • Direct OpenAI / Anthropic: This works, but managing multiple API keys, budgets, and models across different projects gets messy fast.

What I actually needed was a single endpoint. A universal API key that just worked, that I could use for cheap classification models ($0.15 per million tokens) and expensive reasoning models ($15 per million tokens) without signing up for five different services.

I needed to stop thinking about AI infrastructure entirely.

By the way, this is where I landed.

For my current batch of side projects, I use a unified API service that acts as a gateway. It routes my requests to the best model for the job (GPT-4o for complex tasks, Claude Sonnet for writing, Haiku for classification) and I just pay for what I use.

I've been using tai.shadie-oneapi.com for this. It's dead simple. One API key, one base URL, access to pretty much every major model out there. No monthly subscription hostage situation, no "you need to be on the Enterprise plan to use this model" nonsense. It's just pay-as-you-go.

It sounds boring to write about, but getting the infrastructure right is the difference between shipping three MVPs in two months and sitting on a half-finished git clone of a local LLM for six months.

The Real Lesson

If you take anything away from this, let it be this:

The model is a commodity. Your time, your focus, and your ability to ship a finished product is the only moat you have as a solo developer.

Stop tweaking the prompt. Stop trying to self-host. Stop building a platform when you should be building a tool.

Ship the damn product. Your first user is waiting.

Top comments (0)