- After years of stitching together Freshdesk, Gmail, Airtable and HubSpot, we used AI coding tools to build our own CRM, Coral, from scratch.
- Vibe-coding trades traditional upfront planning for judgment calls made in real time — and trades technical debt for a new risk: comprehension debt.
- Total cost so far: about $2,000 to build, $10/mo to host, $350/mo in ongoing development — with an estimated 28-month break-even versus our old toolset.
- Eight weeks in, the platform already flexes to new workflows in hours instead of the weeks a traditional build would take.
- Documentation and clear governance rules turned out to matter more with AI-built software, not less.
Why now?
A dissatisfaction with our current software
As a digital agency managing 100+ websites for nonprofit clients, our team at 118Group has spent years feeling a familiar tension: no piece of pre-built software ever quite fit the way we actually worked.
Since some products worked well for certain types of work but not others, we leaned into piecing together multiple platforms to get the best of each. This is often called an integrated ecosystem — something we cover in more depth in our article on streamlining tech ecosystems.
Freshdesk, for example, was great for managing the support tickets we received from our web-hosting clients, but terrible for managing project work. Gmail was great for inbound and outbound email communication, but awful for understanding client history and context.
Over time, this approach led to a sprawling inventory of tools — each one great at a specific job, but collectively a headache: multiple subscriptions and logins to manage, and key information scattered across a dozen different places, for every one of the client accounts we manage.
Eventually, we grew tired of this and moved to licensing an all-in-one solution — HubSpot — hoping to simplify our toolset and make our work easier.
But this route had its own downsides.
HubSpot is a robust, flexible platform designed to meet a wide range of organizational needs, but getting it to work just right for a specific workflow requires specialized expertise — often meaning you have to pay experts to build your setup. Plus, HubSpot leans heavily into feature-gating: if you wanted access to specific parts of the platform, you’d often need to make a major price jump to an upgraded plan, even if you only really needed 10% of what was being offered.
For a long time, these felt like the inevitable tradeoffs of choosing between an all-in-one platform and an integrated ecosystem: tools that mapped neatly onto your workflows but required a patchwork of integrations to manage, or a single platform that kept everything in one place but forced your workflows to bend to fit it.
Building a custom solution that offered the best of both worlds was simply too complex and costly for most organizations to tackle.
That started to change around 2024 – and it eventually led us somewhere we didn’t expect: building the solution ourselves.
The new economics of custom solutions
Building a custom solution that mapped exactly to our workflows and needs had been a dream for us at 118Group for a long time. Back in 2020, we’d even started brainstorming what this solution would look like, motivated by the idea of replacing at least a few of the dozen or so software products we were paying for but not thrilled with.
So what stopped us? Cost.
Though we had the development skills to build our dream platform in-house, it would have required a massive investment of time from our development team — time we’d otherwise be spending on client work. We estimated a working prototype would take about 6 months, at 15 hours a week of our team’s time.
So we lost steam. Client projects came in, we got busy, and we continued to trudge along with our existing set of tools.
It would be another few years before ChatGPT came onto the scene, showing all of us the start of what could be an incredibly disruptive future for software development. While the early models were game-changing for a number of tasks, they were nowhere near as proficient at handling complex software development tasks as later generations of these products would be. We used them for small coding tasks or troubleshooting here and there, but that was about the extent of our adoption of these tools for real coding work.
Then came Claude Code, along with a suite of platforms for building custom applications using natural language, like Replit.
Now you could chat with an agent and watch your workflows come to life in real time — and these platforms keep evolving, with better integrations into existing tool sets, better troubleshooting and autonomous testing, and cleaner code with fewer bugs and vulnerabilities.
What would have taken us 6 months and 400 hours of valuable development time suddenly seemed within reach for a few weeks of work and a few hundred dollars worth of tokens.
We had to try.
A responsibility to experiment
The conversation surrounding the risks and opportunities of AI is happening across every part of the economy. Nonprofit organizations are no different, and with so much chatter, it can be difficult to find the signal — how will these tools actually improve how we work?
We had our own answer already forming. But the same tension we’d just described feeling ourselves — tools that never quite fit, sprawl that never quite resolved — wasn’t unique to us. We’ve worked with dozens of nonprofit organizations over the years to streamline and improve their tech ecosystems, and we’ve watched the same pattern play out again and again: half a dozen different products stitched together to achieve workflows that could be consolidated and improved with a single, custom-built solution.
If that was true for us, it was almost certainly true for them. And as their trusted digital partner, we knew it was our responsibility to explore, experiment, and ultimately bring the real, game-changing applications of these technologies back to the organizations we serve — not just talk about them.
So we decided we needed to put this theory to the test, and we needed a real application for it.
Real data, real workflows, real consequences. We knew that if we were going to advocate for this new AI-built custom software solution, we’d need to build, deploy, and use it ourselves.
So we got started.
How to vibe-code a CRM
The planning stage
Coding with AI agents has dramatically changed how software gets planned.
Traditional thinking in software development held that making a change to your product becomes exponentially more difficult as you move through the stages of requirements planning, design, coding, and testing, due to increasing architectural complexity.
This phenomenon, known as the cost of change curve, encourages heavy upfront planning to mitigate these more difficult changes later in the process. This planning might involve heavy diagraming and data planning activities, ensuring the technical details are well established before writing any code to avoid costly rework later.
Coding with AI agents changes that math in two distinct ways.
The first is economic: when code can be regenerated or restructured by an agent in minutes rather than rebuilt by a developer over days, the cost of being wrong later drops sharply — weakening the case for buying insurance against it upfront.
The second is more direct, and it’s the bigger shift: the technical translation work itself doesn’t disappear; it changes hands. Drawing an entity-relationship-diagram, deciding cardinality, working out what happens when a record gets deleted — that’s the act of turning an idea into a data model.
Traditionally, a person did that translation, on paper, before any code existed. When coding with AI, those same decisions still get made — the agent still has to decide how a website property relates to a contact — they just get made inside the agent’s process now, guided by our natural-language description of what we want, rather than drawn out by a person first.
The diagram isn’t missing because it’s no longer needed. It’s missing because the agent is now drawing it in code in real-time.
With an AI agent driving the technical decisions, planning shifts toward something only a human can provide: judgment. What should we build first? What should it feel like to use? Where should its edges be?
That’s where our planning energy actually went. And it started somewhere that might seem almost too simple to count as planning at all: giving the thing a name.
Giving it a name
Early in the project, it became clear we needed to give this new platform a name. Continuing to call it “Custom-Built CRM” or “AI-Built CRM” felt technical and dry — we wanted some excitement and identity around what we were building.
So we picked a name and a simple logo. Coral.
It’s a small decision, but a telling one: nobody could hand this off to an agent. Once the project had a name, it stopped feeling like an experiment and started feeling like something we were actually building — which made it easier for the whole team to talk about, plan around, and get behind about it.

Defining the vision
Often, when working with our clients on projects, one of our most important questions involves a little bit of magic:
If you could waive a magic wand, what would you build?
The point of this question is to get the client to articulate their dream or ideal scenario. If you could get everything you wanted, exactly the way you wanted it, what would that look like?
Setting out on this experiment of vibe-coding our own CRM, we wanted to see if we finally did have our magic wand. Could we actually build and deliver a solution that doesn’t force us to compromise?
For us, it started with a series of “What if…?” questions:
Given that we’ve never actually had a magic wand, the next phase of the conversation required the client to ground themselves in reality. What was most important, and what could they afford?
Defining the app’s boundaries
Having a superpowered AI developer at your fingertips for a project like this makes it even more important to define the product’s boundaries.
When you can build anything you want – where do you stop?
Between FreshBooks, Mailchimp, and Sonar, the shape of the project was starting to take form — not everything we’d wished for, but a deliberate, bounded version of it. The technical decisions were still ahead of us.
Choosing the tools
The main tool we used for this project is Replit – an AI development platform that uses Claude to turn natural-language prompts into real, working software. In one workspace, you can chat with an AI agent and see your software come to life in real time.
We considered Claude Code, Anthropic’s more developer-oriented coding tool, but it requires setting up a local environment, a repository, and somewhere to host the build. These were decisions we didn’t want to make until we could validate that our vision was even possible.
Replit brings all of these pieces into a single browser tab, allowing you to plan, build, preview, and deploy your app to a live URL without ever leaving its workspace. The lack of friction between input (your prompt) and output (working software) encourages a level of play and exploration essential to this stage of the experiment.
This frictionless workstyle comes at a cost. Once you’ve built your entire infrastructure – code, database, hosting – on a single platform, migrating elsewhere requires substantial effort.
We decided that at this early stage, the tradeoff was worth it.
The development stage
Coding with natural language
The ability to code using natural language — English, in our case — and to deploy and test that code instantly is drastically different from traditional software development.
Imagine you wanted to associate a contact property, such as Jane Doe, with a website property, such as janedoe.com, so that any email received from that contact gets mapped to the website property.
A traditional development workflow would start by building a user story and addressing several important questions, such as:
- Can one website property link to multiple contacts?
- Can one contact have multiple website properties?
- If a website property gets deleted, what happens to the contacts linked to it?
Based on how the developer wants the relationship between these properties to behave, they might draw up an entity-relationship diagram that articulates all of this — reviewed by another member of the team before moving into actual development.
When vibe coding, it might start with a simple prompt: “I’d like to link these two objects.” Your AI agent may present you with a handful of clarifying questions like the ones above, or it may make key assumptions based on what it thinks is your most likely answer.
Those aren’t just clarifying questions — they’re edge cases: the unusual-but-real situations that don’t show up in the happy path, but eventually show up in real use. Traditional development tries to identify and resolve them upfront. Vibe coding still resolves them — it just does it in the moment, guided by a guess, rather than because someone asked first.
And this is the key difference: there’s no diagramming, planning, or review stage before implementation. Your AI agent is mapping these objects and drafting the same kind of code a traditional developer might, but producing no visual artifact anyone can review later. The entire process is code-based, which makes it difficult for a non-technical team member to follow what’s actually being done.
This is where comprehension debt begins to accumulate.
The comprehension gap
In traditional software development, teams often take shortcuts when writing code, aiming for something “good enough” for now, with the intention of fixing it properly later. The term “debt” is apt because fixing that code later usually costs more — other things get built on top of the shortcut, and the more that depends on it, the more expensive it becomes to untangle.
When vibe-coding, the author never really writes or touches the code, and rewriting it later can be done quickly and cheaply by an AI agent — which softens the classic technical debt problem, since redoing something no longer costs days of developer time. But it doesn’t eliminate the underlying risk. It just trades one problem for a different one: comprehension debt.
Once you’re no longer the one writing the code, you’re no longer forced to understand the architecture as you go. Code still gets produced — but the mental model connecting that code to what it actually does can quietly go missing.
Comprehension debt is the gap between code that works and a team that understands why it works — a debt owed not by the codebase, but by the people responsible for it.
Early on, you might not notice. Everything works, and the build is simple. But as complexity grows, the gap between the code and your understanding of it widens — until something breaks, and no one can explain why. You’re now stuck using AI to solve AI problems, with very little understanding of what’s actually happening underneath.
During our build, there was a moment when no one on our team could explain why we were each seeing different email counts inside Coral. We were all looking at the same shared inbox — it made no sense that the numbers didn’t match. We had to work with our AI agent to unpack how emails were being received and routed, piece by piece, before we could even understand the problem, let alone fix it.
This is the part of the experiment when we understood how the nature of product testing changes in an AI coding environment.
Testing your application
Vibe-coding introduces an entirely different experience for testing and validating your application — and the reason starts with how the code itself gets made.
When vibe coding, AI is writing the code, not you — and it will rewrite the same lines a dozen times over the course of a project, chasing a dozen different requests. That means the value of testing and validating any one specific piece of code is short-lived: whatever you verify today may not exist in the same form by next week’s request.
So how does testing change in the era of AI?
Imagine you’re building a car. Traditional development tests like a car manufacturer: before brakes go on the vehicle, they’re tested on their own, in isolation — do they engage properly, release properly, hold up under stress. Only after the brakes have been tested independently, and then again once installed, does the car go out for a test drive. Vibe coding is closer to building the entire vehicle — brakes included — in one continuous motion, and taking it straight out for that test drive.
Nothing was tested in isolation first, so if something's wrong, you find out at the worst possible moment: at speed.
That’s why testing has to change shape. Instead of testing each individual function on its own, vibe coding requires stepping back and testing the larger picture: Can a user actually submit a request? Does it trigger the right notification? Does this information map cleanly to the right property? Testing becomes more intuitive than cerebral — you’re checking whether the thing behaves correctly, not tracing through code to understand why it does.
The frustrating part is what happens next. Because the AI keeps rewriting sections of code to satisfy new requests, problems can resurface in parts of the application you already reviewed and confirmed were working — weeks after you moved on.
If vibe-coding already feels like building the runway while you’re taking off, this is the version where you’re also playing whack-a-mole while you do it.
The rollout stage
Testing could only tell us so much. Eventually, the only way to know if Coral actually worked was to let it touch something real.
Jumping with a parachute
Committing your team’s entire workflow to an AI-built platform is still a big leap, even without a formal go-live moment to dread.
For one, there’s no support team. You built the app — so if something goes wrong, you’re the one who has to figure it out. And you probably don’t fully understand how it works. You might have a solid understanding of what it should do, but a limited one of how it’s actually doing it — the same comprehension gap we ran into earlier, just showing up now with a real client on the other end of it instead of a teammate.
So, to make adopting the platform feel less scary, we kept running our existing CRM, HubSpot, in parallel with Coral while we continued to flesh out issues and bugs. It isn’t ideal to manage two platforms with email flowing through both — but it gave us the confidence we needed to actually start using Coral for real.
Sending that first outbound email to a real client through Coral was scary. It was a lot less terrifying knowing we could pivot straight back to HubSpot if something went wrong, without missing a beat.
Managing bugs and clients
No matter how much testing you do before launch, real-user interactions will always surface bugs and edge cases you didn’t catch.
There are typically dozens, if not hundreds, of potential edge cases in any piece of software — far too many to identify and resolve ahead of time. With less upfront planning built into the vibe-coding process, those edge cases get even less advance consideration than they would under traditional development.
That said, resolving these issues once they surface has become much faster. Real use is often the only way they ever surface at all.
We ran into an issue sending a client an attachment with a special character in the filename — instead of "Hosting & Support Options," the ampersand rendered as a garbled string of characters. It was a little embarrassing to explain, but minor enough not to be a real black eye — and it took us two minutes to fix.
So, the trade-off with launching vibe-coded software is that you are likely going to have MORE bugs, but you will be able to resolve them more quickly.
How it’s going
What the cost looks like
There are two main cost factors to consider when running your own custom application on a platform like Replit: the monthly cost hosting, and the costs associated with ongoing development and updates.
Right now, we are spending about $10/month to host Coral on Replit and about $350/mo in ongoing development. This sounds steep, but we’ve spent the past couple of weeks making daily upgrades to the platform, which has largely driven the high monthly cost.
In total, we’ve spent about $2,000 building Coral on Replit.
Does all of this make sense?
In the short run, the answer may seem like an obvious no. Between HubSpot and Airtable, the main platforms we’ve been able to replace, we were spending about $80/mo. Now that we are hosting Coral on Replit, we are only really saving $70/mo after investing $2000 in the initial build.
Assuming we pause all additional development (which we won’t), it would take us about 28 months to break even on this investment.
This was a bit like buying a home instead of renting one. Renting is cheaper month-to-month — but you're stuck with the floor plan you're given. Buying costs far more upfront, and it takes a long time to pencil out on a spreadsheet. But the house is yours.
From an operational perspective, this has been a total game-changer.
While we outline some of the main advantages we’ve gained with this move below, suffice it to say that we are better able to both communicate and deliver value to our clients – and how much might that be worth?
A platform that is always evolving
At the time of writing, it’s been about 8 weeks since we fully adopted Coral as our CRM, and since then we’ve already introduced new features and workflows tailored to our needs.
This was one of our magic wand scenarios – having a platform that could mold to our workflows as the company evolves, and that is exactly what we have with Coral.
For example, since launch, we have wanted to better understand current client email volume. In one day, we rolled out a lightweight, easy-to-use analytics dashboard that surfaces ONLY the insights and data that actually matter to us.
We also decided that we wanted to better visualize how long certain client requests have been pending in our queue. In one afternoon, we implemented a sophisticated color-coding system that transitions from green to red based on a ticket’s duration in our workspace.
These types of feature rollouts would have taken weeks before the vibe-coded era, and this new adaptability makes working with your technology a fundamentally more enjoyable experience.
Comprehensive client data sets
This is the wish we opened with: all our client data in one place, so a single question about a client doesn’t send us digging through three different tools. We may not have hit full nirvana, but we’ve gotten a lot closer than HubSpot, Airtable, or Mailchimp ever got us alone.
We’ve been able to better segment our contact list based on much more specific variables — like which version of WordPress a client’s website is running, or who’s booked a meeting with us every month for the past six months.
Remember the GoDaddy outage scenario from earlier — wanting to quickly reach every client on a specific host the moment something breaks? That’s no longer hypothetical. We can build that exact segment, by WordPress version or hosting provider or whatever else matters in the moment, in the time it takes to ask.
That WordPress detail, worth noting, is coming from Sonar — the separate app we built specifically to keep this kind of website data flowing into Coral without putting our whole CRM at risk. The boundary we drew earlier is quietly doing its job every time we run a report like this.
We’ve also built a much more robust analytics engine.
Previously, we learned to live with whatever default reports came bundled with the platforms we used — none of them exactly what we wanted, but good enough to offer some insight into our operation. With AI as our assistant, we can generate reports for things we actually care about. When a question about our client base comes up, we can answer it almost instantly, using natural language, without configuring a single report-generation tool.
Ongoing issues and bugs
We’re experiencing far fewer bugs at this stage of the build than we were early on, but issues still come up — and the frustrating part is that they’re unpredictable about where they land.
For example, we recently decided to let our staff upload their own profile images for use across our meeting scheduler and team collaboration workspaces. For some reason, this update broke the ability to send emails with image attachments — and we didn’t notice until we’d drafted a long client update with an attachment, only to watch the email fail.
We were back in familiar territory: asking an AI agent to fix a problem another AI agent had just created.
Fortunately, once we knew what to look for, chasing this one down took less than an hour — a fraction of what waiting on a developer’s availability would have cost us in a traditional build.
What we’ve learned
We wish we had done a better job of visualizing key workflows — like email routing to staff — as we built them. Without that documentation, we spent a lot of time on tedious tests to resurface these rules weeks after the code was written. Vibe-coding makes it easy to skip documentation in the rush of progress; do this at your peril.
When anyone can pilot AI agents against your codebase, you need hard rules for how that's done. One team member's work was completely erased and overwritten by another's before we set clear rules. Identify a single builder — ideally the person with the deepest technical knowledge — and run updates, feature requests, and troubleshooting through them.
Spending tokens fixing an issue an AI agent created while fixing something else it also built is its own kind of frustration — especially when it can't resolve the issue and you keep spending anyway. On harder problems, we'd spend $20–$30 at a time going back and forth. Taking a break and coming back fresh usually led to a faster, cheaper resolution.
Even given the challenges outlined in this article regarding vibe-coding, since we adopted our new platform, we haven't shed a single tear for the ones we've moved away from.
Having a tool that is completely geared towards how our team likes to work, built on a platform that can continue to adapt to our needs, is simply…delightful. Running a feature review, comparing subscription levels, working with onboarding teams, and committing to prefabricated solutions feels archaic to us now that we've moved to our custom build.
That being said, we aren't necessarily ready to move our entire operation to AI-built solutions. Payment processing and credit card storage remain part of our business that we entrust to developers and teams specializing in securing this type of information.
With this initial experiment completed and its lessons well understood, we are excited to explore opportunities to work with our clients to transform their workflows with custom solutions.
