AmpleHelp, Observe Domains, & HookHQ

I love an excuse to play with new technologies and I’ve been learning and building a lot recently. My go-to tech stack is normally Vue, Hono, Firebase and Cloudflare Workers, but I’ve been working on 3 new apps / platforms and used it as an opportunity to learn new tools and platforms including:

  • Next.js
  • Nuxt
  • Convex
  • Clerk
  • Scalar
  • Cloudflare R2, Queues, Durable Objects, and Containers
  • Speakeasy
  • Langfuse
  • NX
  • Cursor, Windsurf, Claude, Devin, etc.

This post is an overview of each project, how it’s built, and some of my thought on the different tools and technologies I used to build them.

AmpleHelp

AmpleHelp is an AI-powered knowledge base platform that was born out of my frustration with other platforms I tried (including Confluence, Featurebase, and Hiver). I’ve tried many different knowledge base solutions when building Rack Manage and eventually landed on Atlassian Confluence primarily because of Refined Sites which let me build a complete help center that combined Jira + Confluence with custom branding, free hosting + domain, etc. Refined was completely free, but I paid a small fee each month for Jira + Confluence to make it publicly accessible … until Refined killed their Free plan and raised their prices. The features I was using on their free plan would now cost me $50 – $100/month on top of my existing Confluence subscription.

I was already using Featurebase for product feedback so I tried their knowledge base and really liked it, but their free plan is very limited and I really wanted a custom domain, so I couldn’t justify paying $50/month even if it came with many other features.

Finally, I tried Hiver because it offered a free knowledge base with custom domain hosting as well as a customer support platform which I thought would be great to move my entire help center (Jira + Confluence), but their pricing and plans are not very transparent, and I found their product lackluster. I didn’t understand that many features were for Google Workspace only, whereas I had been using Microsoft 365 for Rack Manage.

So I decided to build my own solution.

AmpleHelp is a knowledge base built on Nuxt with micro-services running on Cloudflare and auth + database on Firebase. It’s composed of three Nuxt apps in a shared monorepo for the management portal, knowledge base sites, and an internal admin app. Micro-services running on Cloudflare provide AI RAG, chat, and article generation, metrics (views, article ratings, usage), messaging (contact forms and webhooks), and an API interface.

It uses Cloudflare for SaaS for custom domain hosting, allowing users to choose a subdomain of *.ample.help, or bring their own domain. AI features run on Cloudflare Workers AI + AI Gateway, currently using BGE v1.5 for embeddings, Llama 3.2 for RAG/chat, and Llama 4 Scout for article generation. Additionally, AmpleHelp uses Langfuse for prompt management and observability.

A big focus of the project was building a powerful editor with all the features I wanted. Many of the platforms I tried had great looking help centers but lacked features in the actual text editor. I wanted lots of flexibility for things like code blocks, callouts, tables, images, embeds, etc. so AmpleHelp uses the powerful TipTap editor with a suite of custom extensions for everything listed above, along with better user experience and dark mode support.

While it’s not open to the public right now, I’m using it for all of my apps (including the three listed here) and plan to continue building it out to add additional (lightweight) customer support options so I can completely replace Confluence and Jira.

Join the waitlist for AmpleHelp here: https://amplehelp.com

Observe Domains

I’m a bit of a hoarder when it comes to domains. I used to try to put everything as a subdomain of my main domain, but over the years as I’ve launched more public facing projects / SaaS apps (or come up with an idea for one that never launches) I purchase new domains. I’ve also tried to consolidate them to Namecheap and Cloudflare, but I have some domains that aren’t supported on one registrar so I have to keep track of renewals in different places.

I looked into some solutions like DomainMOD, and while it’s powerful, I found the interface / user experience very clunky, and I wanted something that would be easy to host in the cloud (specifically Cloudflare Workers) so I wouldn’t have to pay for compute or put it on my home server which I don’t keep online 24/7.

Observe Domains was my weekend project to bring this solution to life. It’s a dead-simple domain registration monitoring platform powered by RDAP (the successor to WHOIS). Since I knew this would be a relatively small project I also used it as an opportunity to dip my toes in the waters of Next.js. While I’m not a fan of Vercel, Next.js has intrigued me for a while so I figured this would be a good opportunity to learn without too much commitment. It also opened the doors to a larger ecosystem that I don’t typically get when building on Vue, so I also swapped out my traditional toolkit of Firebase Auth + Firestore for Clerk and Convex.

Clerk Auth + Billing

I’ve tried Clerk before and even considered migrating Rack Manage off of Firebase Auth and over to Clerk, but ended up choosing not to because of the pricing and some of the custom auth integrations I’ve built on top of Firebase Auth, but one thing that really interested me about Clerk was their integrated payments.

The most annoying thing about building a new app is all of the boilerplate / generic work like auth and billing. I want to spend my time building the core features, not worrying about payment processing webhooks, entitlements and roles, feature gating, etc.

It also seems crazy to me that more auth systems don’t integrate deeply with payment processors to automatically track plans and entitlements, so I was excited to try Clerk Billing, and I’ve been genuinely impressed with how easy it was to get setup. It’s a batteries-included approach that saved me so much time. It takes just a few lines of code to add a pricing table or checkout page. Their login page is extremely flexible with catch-all routing, and they provide an extensible settings page, so I can just piggyback off of their existing UI to add tabs for my product settings.

While it’s still in beta and missing some core features (+ it would be nice to see a Merchant-of-Record offering in the future), I 100% recommend it and will consider using Clerk for all future projects I build.

Observe Domains Features

I wanted Observe Domains to be simple and fast. With DomainMOD you have to define your registrars, accounts, and domains manually which is tedious. They do support importing domains but this process was excruciatingly slow for me and error prone, resulting in duplicates that I then had to go manually correct in another tedious process.

With Observe Domains you type your domain, press enter, and in seconds you see all the details. It retrieves and stores RDAP data published by registrars and notifies you via email and/or webhook when your domain has been transferred, expired, or is coming up on a configurable expiration warning period.

Additionally, Observe Domains can check SSL certificates for expiration by making period requests to your domain, inspecting the TLS handshake packets and extracting information about the certificate and protocols.

You can automatically sync domains from your registrar or DNS provider (currently supporting Cloudflare, AWS Route53, Gandi, DNSimple, and Spaceship) so Observe Domains will detect when you register a new domain and start monitoring it automatically.

The entire platform is realtime, powered by Convex (which conveniently integrates deeply with Clerk), for a great user experience. I initially started to build Observe Domains on Supabase, but found it to be too expensive for this project and I heard good things about Convex.

The developer experience was very different from what I was used to, but like Clerk, it’s also a batteries-included approach to a database which handles a lot of things for you. It is opinionated which leads to some limitations, but once I got the hang of it, I found it very easy to use.

This post is not sponsored by Convex, but if you want to help me out, sign up with my referral code and Convex will give you some additional monthly benefits: https://convex.dev/referral/CARTER3847

Sign up for Observe Domains now at https://observe.domains.

HookHQ

With each SaaS platform I build, I find myself repeating some of the same tasks over and over again. Like my problem with auth + billing, I wanted a way to make sending webhooks to customers easier. With Rack Manage, AmpleHelp, and Observe Domains I ended up building slightly different implementations of a webhook engine. Rack Manage has a powerful payload editor using Monaco Editor but has a pretty basic backend server. AmpleHelp had a limited frontend but a more powerful backend built on Cloudflare Queues. When I started building webhooks in Observe Domains, I decided I need to just have one good implementation and share it across all my projects.

While there are existing solutions that solve this problem like Svix or Hookdeck Outpost, I like Cloudflare Workers and wanted something I could run there. While these apps do have docker images I could put on Cloudflare Containers, Containers is still very much in beta, and I expect it will cost a lot more than workers once it’s GA.

HookHQ is also a Next.js app, this time built with BetterAuth based on the better-auth-cloudflare Next.js starter app. It provides a management portal for creating environments, endpoints, and event types, an end user portal for creating new endpoints, and an API for sending events or managing endpoints.

It’s a multi-tenant solution with shared infrastructure for separating endpoints that belong to different apps or users, and allows targeting events to groups based on subscriptions, or dispatching events directly to an endpoint.

It’s nothing too flashy, and won’t be as performant as a Rust or Go based solution like some of the products mentioned above, but aims to simplify my development process and will be more than enough for my needs.

HookHQ is still very much in development, but once ready it will be open source and available to deploy with a single click on Cloudflare with the “Deploy to Cloudflare” button.

I also plan to support Hookdeck’s Event Destinations initiative through HookHQ.

To learn more about HookHQ, head over to https://hookhq.dev

A Note on AI Tools

These projects are largely “vibe-coded” and my first attempts at heavily using AI tooling. I’ve used ChatGPT and GitHub Copilot in the past for design help and inline code completions, but had never used coding agents before these projects.

I started with Windsurf and enjoyed it but often found myself flipping between different models trying to find the best results, running into issues with models not using tool calls properly, and running out of credits and having to top up my balance. When Anthropic started blocking Windsurf’s access I tried using the bring-your-own-key setup but hit constant rate limits from the Claude APIs, so I eventually cancelled my plan and moved to Cursor. I liked that Windsurf was cheaper than Cursor and wanted to support the “underdog”, but it was becoming more difficult to get good results.

At the same time as Windsurf, I had also been testing out Devin. I initially signed up because of DeepWiki which I thought was very cool (though I’ve barely used it since signing up), but later started using the Devin agent.

I initially had some good success with Devin and I really like the concept of sending a Slack message before I head out the door or go to bed and coming back to see the task completed, but it feels like it’s progressively gotten worse, and is limited due to it’s cost and message limits. Maybe I’ve just started to give it bigger tasks that it struggles to handle, but even on some tasks that seemed fairly easy to me it would get hung up on bugs, need frequent correction, and waste credits seemingly doing nothing.

On multiple occasions I would give it a small task, come back to see it had been running for a long time and was only half way through the task or stuck on a step, whereas I could complete the task manually, or give it to a cheaper agent / LLM and have it done almost immediately.

With the limited number of messages per session, my attempts to correct Devin would often fill the context and force me to throw away a session. At $2.25/credit a “small” session (2-5 credits as defined by Cognition) could easily waste $10 making it prohibitively expensive when it’s only capable of completing small tasks anyway.

I really like the idea of being able to assign it a task from anywhere and have it spin up it’s own developer environment. The ability to actually run code, interact with the browser, and perform tests in it’s virtual machine is attractive, and I understand that compute is expensive, but I can’t find enough value for the price. I do hope that Cognition’s acquisition of Windsurf will help improve both products, and if Windsurf introduces a background agent in their monthly subscription like Cursor, I’d definitely switch back at least to try it out.

That being said, since switching to Cursor I haven’t had to think about my selected model or usage limits once. It just works. I don’t like that the pricing isn’t nearly as transparent as Windsurf, so it’s hard to tell how close I am to the agent usage limits, but I haven’t hit any limits or overages.

Their background agent isn’t as intelligent as Devin, it just runs a model in the background but doesn’t have all the compute and memory, though I’ve still seen good results out of it.

It’s also not as conversational as Devin. I can easily correct or interrupt Devin and it will reply to my Slack messages with a ton of info, but Cursor replies with the bare minimum. I’ve stopped using background agents altogether but am excited to see what happens in that space in the future.