Building Breakwater with AI
Recently I’ve been blown away with how good the AI models have become at helping me with my work. Over the past year, starting with ChatGPT conversations, then switching to Cursor as my primary editor, then diving into Claude Code, AI has become more and more useful in my day to day. But something changed in November-December… the models got much better at building web applications, and it has changed how I work.
Late last year, I started thinking about how we could better manage the distribution of Docker images from a private repository to Honeybadger customers who were interested in self-hosting. I looked at deploying our own instance of Harbor, an open source container registry with authentication, but then it started to feel like a capital-p project. I had plenty of other things to do, so I put it on the back burner. But as I thought more about it, I realized that while it felt like a less-than-exciting work project, it could be a fun side project if I turned it into a product. Because of course other people will have this problem and go look for a solution, right?
Breakwater, an app that helps software creators license their Docker images, is that product. You set up your products, associate them with your private repository, and create customer licenses for them. Customers can then use those licenses to pull your images the same way they would from Docker Hub or any other registry. If you want a way to sell your app as a self-hosted product, and you can package it as a Docker image, Breakwater is for you. In this post I’m going to walk you through how I built it with AI, and share some observations on how AI is changing the game for SaaS creators.
From idea to plan
Over the Christmas break I sat down with ChatGPT to hash out what the product would do and what features would be interesting. I find myself going to ChatGPT first when I have an idea to flesh out, or a question about how to approach a problem, etc. I think that’s primarly because ChatGPT was the first AI chatbot I started using, but it helps that its icon lives in my menu bar. I’m sure Claude would be just fine for this, too.
But anyway, I planned to build a front-end for Harbor, and layer on concepts like Customers and Licenses — the things you need when you’re distributing software commercially rather than hosting public images that are freely available to pull. Here’s my initial prompt:
I’m interested in having a docker registry for customers where they use a web app to get credentials that are then used when pulling images. The goal is to sell licensed software that is delivered as docker containers, and once a customer purchases a license, they will have access to pull the containers. What technologies do you recommend I use for this?
I didn’t say anything about Harbor, as I wanted to leave ChatGPT open to suggest anything. Naturally, Harbor got priority placement in its recommendations. Here’s the initial response:
Short version: Use a standard OCI registry with token-based auth in front of it, and have your web app mint per-customer pull tokens/robot credentials based on license state. Don’t reinvent the registry itself; glue existing pieces together.
After presenting that and an overall architecture design, it presented three options:
- Use Harbor as the registry and implement licensing in the web app, using the Harbor API to manage robot accounts and projects.
- Use a standard OCI registry like distribution and implement token-based authentication using a custom web app.
- Use a managed registry service like Amazon ECR, Google Artifact Registry, or Azure Container Registry.
I decided to go with option 1, since it seemed like the fastest path to a working solution. I also liked the idea of being able to use its features for pulling images from upstream sources (my future customers’ own registries) and enforcing quotas. When I selected option 1, ChatGPT then generated a high-level implementation plan which seemed reasonable.
Then, knowing that I love to dive head-first into building stuff without doing much research, I asked about what solutions already existed for this problem:
Before we get too far into this, is there a SaaS that already offers this kind of functionality?
It gave me info about Quay.io and JFrog Artifactory as well as providing suggestions for making GHCR or AWS ECR do what I wanted. None of those solutions were exactly what I was looking for, so I decided to plow ahead:
I think I want to build my own thing rather than relying on a SaaS. Can you help me come up with a project plan? I’m thinking I’d build a Rails app for this.
It gave me a reasonable-looking plan, so I decided to go with it, and I asked it to give me the plan as a markdown download so I could save it to my new Rails project and use it with Claude Code.
Brainstorming the brand
Once I had settled on what I wanted to build, I decided to start a new chat session to brainstorm a name. It gave me names emphasizing licensing / entitlement, names themed around harbors / registries / containers, names focused on keys / access / authentication, names centered on delivery of software artifacts, etc., ending with a top-10 list of recommended names. After a bit of back-and-forth, and my suggestion to focus on “terms related to defending a harbor”, Breakwater was the top choice. As we wrapped up the name selection process, ChatGPT suggested creating a brand board, so I had it do that.
It provided three options, and each of them had a vibe (Strong, crisp, premium, enterprise SaaS. Feels like Cloudflare, HashiCorp, or Stripe.), color palette, typography, logo/mark ideas, iconography, and a UI direction. After I picked the option “Modern Industrial Security”, it provided a detailed brand board with all the elements mentioned above, and then suggested building a landing page, logo concepts (in SVG format), etc., and I asked it create the landing page using Tailwind. The current home page is still largely what ChatGPT created, though I made some changes while workshopping with Claude as the project progressed.
I wrapped up that chat by asking for a final deliverable before getting to work:
Can you give me the brand board, visual design instructions, etc., in a markdown file I can download to be used to guide an AI while building HTML and CSS for my Rails app?
Claude gets to work
Once I had the brand and vision in place, I switched to Claude for the actual development work. Claude quickly built me a Rails 8 app using Tailwind, following the color scheme in the brand board doc that I downloaded from the conversation with ChatGPT. It took just a few hours to get the models in place, get Harbor running, get the Rails app working with the Harbor API, and have authenticated pushes and pulls working. All along the way, I had Claude updating the project plan document to keep track of progress and to provide context for new work sessions. Every phase (Harbor infrastructure, Rails app skeleton, Harbor integration, etc.) was a new Claude session, and at the end of each session I would have Claude update the project plan document and generate a new document summarizing the decisions made and the work done in that phase.
As I played with the app I realized that using Harbor was adding friction — my models weren’t lining up well with Harbor’s structure — so I revisited my first chat with ChatGPT, picking up where we left off with this:
I’ve been going down this path with Harbor, and I’m not sure it’s working for me… I’m feeling a bit of friction between my app and Harbor. I’m not sure I’m ready to abandon that approach yet, but I would like to explore option B: providing an auth token layer for plain registry. Can you dive into that option a bit more?
And of course ChatGPT was happy to help. After a bit of back and forth and clarifying questions on both sides, I was ready to point Claude in the new direction, and I asked for an updated plan from ChatGPT:
I’d be interested in seeing a detailed implementation plan that includes the info you mentioned, with the plan written as downloadable markdown so I can use it to drive an AI in my project to build the task list.
With the new plan in hand, and with an hour or two of work time per day, Claude and I made good progress. Claude was much faster than I would have been at building the auth token support in my Rails app that the registry needed for handling Docker authentication. After about ten hours of work, I had a working Rails app that was deployed and ready for alpha testing.
When plans change
Eventually I realized that my registry + authentication setup wouldn’t support a key feature I wanted: being able to grant or deny access to images based on tag versions. The registry didn’t pass that information along to the Rails app when it received a pull request, so I couldn’t implement version-based licensing. I was pretty bummed by this, and, packing it up for the night, I explained my disappointment to my wife. I knew what needed to be done — build an authenticating proxy in front of the registry — but it felt like a lot of work, and I wasn’t sure it would be worth it. I considered dropping the feature, but then my wife said:
Why don’t you just ask Claude to help you build it?
Well, duh.
So the next morning I had Claude help me build an authenticating proxy in Go that would sit in front of the registry and pass the information to the Rails app that I needed. Again, it went much, much faster with Claude than if I had tried to do it on my own. The initial code session for that took less than an hour, and within three hours or so, over the course of a few days, it was done.
It was around this time that I decided to start having Codex review Claude’s work, and that has been awesome. I’ll ask Codex to do a review of the current changes, then copy paste Codex’s findings into my Claude Code session, and have it implement the fixes. Then when I push a PR to GitHub, Copilot will review the changes and provide feedback, which I’ll then have Claude address. My solo project has turned into a team project, and it’s been a blast.
Why this works so well
Claude is amazing when it’s helping you with work that you already know how to do. Being an expert web developer and operator (19 years of running SaaS apps and counting!) and using AI to build a new web app is crazy fast for a few reasons:
-
Claude has been trained on a lot of web app code. Granted, not all of that code is awesome, so Claude doesn’t always generate the exact code I would write, but it’s usually pretty good. Having Claude generate code much faster than I could write it, even if it’s not perfect, is a win.
-
I know what features I need. “Claude, build vendor onboarding. Claude, build an audit log.” I can describe the features at a high level because I know the domain well. And when I don’t know exactly what I want, Claude can often suggest relevant features or improvements. I can literally type, “what’s this app missing” and Claude will offer suggestions that are usually very good. Or I can type, “I’m thinking of building X, please help me create a plan to build it and ask me questions to flesh out the details”, which is surprisingly helpful in finding blind spots and ironing out implementation details.
-
I know good output when I see it. I can validate that Claude is not just producing something, but is producing the right thing. When Claude’s implementation doesn’t quite fit my needs, a simple prompt gets it back on track. AI in the hands of a novice can be dangerous… if I asked ChatGPT a question about a medical condition or a legal issue, I’d have no idea whether it was accurate or not. But when I ask Claude to build a feature, I know what it should do and how it should work. I know how to evaluate the generated code for potential security and performance issues.
-
I don’t have to focus 100% on the work. Getting in the zone while writing code is awesome. I love experiencing flow while working on a project. But having work get done while I’m doing something else is also awesome. I can spin up a task with Claude, then switch to doing something else, and come back to find a working feature. I can prompt Claude Code Web to do something from my phone when I’m out and about, and then when get back to my computer, I can review and ship what it built for me.
-
It’s easier to get started on a task. Activation energy is a thing. Starting with blank slate, whether it be prose or code, can feel daunting, but starting with a prompt can be low-effort. For example, I’m usually not excited to work on frontend code. Typing something like “I want the product page to be updated when a repository is linked to it” can get me 80% or 90% of the way there, making it feel less daunting to get started.
I’m sure there are more benefits I could list, but you get the point. I’m so much faster at delivering features with AI than I am without it. I’ve lost track of how many times I’ve sat down to build out the next phase of the plan and it’s done within ten minutes. Build an admin UI? Done. Add a multi-step vendor onboarding workflow? Done. Create a documentation portal? API? Self-hosted analytics? Done, done, and done.
I’m not spending time in the editor, typing code. Claude is typing the code. I’m directing the work, thinking about the bigger picture, and shipping faster than ever before. It’s amazing.
Looking ahead
B2B SaaS in 2026 is going to be wild thanks to Claude and other AI coding assistants. It’s scary, exciting, and mind-blowing all at the same time. The barrier to building new products has dropped dramatically. Solo founders and small teams can move at a pace that wasn’t possible before, and be more ambitious in what they can build. The bottleneck is no longer “can I build this?” Instead, it’s “should I build this?” and “do people want this?” and “how will I get this in front of people?”
I’m excited to see where Breakwater goes, and I’m even more excited about what this new era of AI-assisted development means for indie hackers and bootstrappers everywhere.