I Vibe Coded a Bitcoin App with Ruby on Rails in 24 Hours

I Vibe Coded a Bitcoin App with Ruby on Rails in 24 Hours

Bitcoin Companies 10 min read
TL;DR

I built a Bitcoin treasury leaderboard in 24 hours using Rails 8, seeded 200+ companies with Claude Code, and deployed with one command. Total cost: ~$265/mo. Here’s the full breakdown.


I Vibe Coded a Bitcoin App in 24 Hours

Disclaimer: Rails is my main language. Some call it “the boring stack.” I call it the stack that ships.

I’ve been coding Rails for years. It’s not sexy. It doesn’t get Twitter hype. But it works. Rails has been here for 20 years, battle-tested by millions of apps. Every problem has a gem. Every pattern is documented. Full stack: handles front AND back seamlessly.

Don’t reinvent the wheel when the wheel has been rolling for two decades.

This is Bitcoin Companies - a verified Bitcoin treasury leaderboard I built in 24 hours:

Bitcoin Companies leaderboard showing verified treasury rankings


Why I Built This

The Backstory

I was working on Hongbao Bitcoin, but it wasn’t getting traction. Social media marketing led to posting fatigue - constantly creating content, chasing algorithms, hoping for virality.

So I decided to fully focus on one marketing channel that paid off on my previous projects: SEO.

I got inspired after watching this talk about building a business through SEO:

The approach: create something useful, optimize for search, let Google do the distribution. No posting fatigue. No algorithm games.

The Problem

Companies claim “We hold X BTC” with zero proof.

  • No on-chain verification
  • No public addresses
  • Trust-based claims in a trustless industry

The irony is painful. Bitcoin exists because “don’t trust, verify.” Yet corporate treasuries operate on pure trust.

The Inspiration

Marc Lou built TrustMRR - verified MRR badges for SaaS founders. Stripe connects, revenue verified, badge displayed. No more fake screenshots.

Same concept applies to Bitcoin treasuries. Don’t trust the press release. Verify the blockchain.

The Gap

bitcointreasuries.net lists companies but no verification. Anyone can claim anything. The data exists, but there’s no proof layer.

I needed a leaderboard with PROOF. On-chain verification. Public addresses. Cryptographic signatures.


Building the Dataset with Claude Code

The Challenge

I’m not known in the Bitcoin space. Manual data entry for 200+ companies would take weeks. I needed to launch with real data, not an empty app.

Existing sources:

Claude Code to the Rescue

I used Claude Code to parse and structure data from multiple sources:

$ bin/rails db:seed

Seeding companies from bitcointreasuries.net...
  Created: MicroStrategy (MSTR) - 450,000 BTC
  Created: Marathon Digital (MARA) - 44,394 BTC
  Created: Tesla (TSLA) - 9,720 BTC
  Created: Coinbase (COIN) - 9,480 BTC
  Created: Block Inc (SQ) - 8,027 BTC
  Created: Riot Platforms (RIOT) - 7,362 BTC
  ...
  Created: Swan Bitcoin - 215 BTC
  Created: Unchained Capital - 187 BTC

✓ 214 companies seeded successfully
✓ Total treasury: 3,135,847 BTC

The workflow:

  1. Feed Claude Code the source data
  2. Generate structured seed files
  3. Cross-reference for accuracy
  4. Human verification pass
  5. Import to database

Result: 200+ companies seeded in hours, not weeks.

# db/seeds/companies.rb - Generated with Claude Code
companies = [
  {
    company_name: "MicroStrategy",
    domain: "microstrategy.com",
    ticker: "MSTR",
    claimed_btc: 450000,
    company_type: "software"
  },
  # ... 200+ more
]

AI accelerates the boring parts. Human verification ensures accuracy. Launch with real data, not an empty app.


The Blog: Why Not Ghost or Webflow?

I considered the usual options:

Platform Pros Cons
Ghost Nice editor, built-in SEO Separate system, $9-25/mo
Webflow Beautiful designs Less dev control, $14+/mo
Headless CMS Flexible More complexity, API calls

What I Chose: Sitepress + Markdown

The blog lives in the same Rails app. No separate system. No API calls. No extra hosting costs.

  • Claude Code for fast iteration - Write content, deploy, iterate
  • Full custom layouts - No platform limits
  • Markdown files - Version controlled with git
  • SEO fully under my control - Meta tags, structured data, everything
# app/content/pages/blog/my-article.html.md
---
layout: post
title: "My Article Title"
description: "SEO description here"
---

Article content in markdown...

One codebase. One deploy. Full control.

Blog layout with Table of Contents, FAQ sidebar, breadcrumb navigation, and embedded tweets for proof


Why Ruby on Rails (The Boring Stack)

Don’t Reinvent the Wheel

Rails has been here for 20 years. The wheel has been rolling smoothly.

  • Every problem has a gem
  • Every pattern is documented
  • Full stack: handles front AND back seamlessly
  • Same applies to PHP/Laravel - mature stacks win

I didn’t need to choose between 50 npm packages. I didn’t need to debate state management. I just built features.

SEO Out of the Box

Server-side rendering by default. Google indexes complete HTML. No hydration. No “loading…” spinner.

Feature Rails/PHP (SSR) React SPA
SEO Works by default Requires Next.js/SSR
Google sees Complete HTML Empty div + spinner
Time to content Immediate Wait for JS
Complexity Low High

React SPAs render in the browser. The server sends an empty HTML shell, JavaScript downloads, executes, fetches data, then renders. Search engines see nothing useful on first load.

Rails renders HTML on the server. The page arrives complete. Google indexes everything. Users see content immediately.


My Exact Tech Stack

Layer Technology Why
Backend Rails 8.1.2, Ruby 3.2.8 Latest Rails with Hotwire default
Database SQLite3 Simple, fast, no ops overhead
Frontend Stimulus + Turbo No build step, native Rails
CSS TailwindCSS v4 + DaisyUI v5 Rapid UI development
Assets Propshaft + Importmap No Webpack/esbuild complexity
Payments BTCPay Server Self-sovereign Bitcoin payments
Deploy Kamal 2 One command Docker deploys

SQLite in Production?

Yes. SQLite works excellently for read-heavy applications. 37signals (the creators of Rails) run SQLite in production for several products.

For a leaderboard with occasional writes and many reads, SQLite eliminates:

  • Database server management
  • Connection pooling complexity
  • Separate backup procedures
  • Monthly hosting costs

The database lives in a single file. Deployment is simpler. Backups are trivial.


SEO: Why Server-Side Wins

PageSpeed Scores

Without doing any optimization :

PageSpeed mobile score showing 91 performance

PageSpeed desktop score showing 97 performance

The SEO Advantage

Rails renders HTML on the server. The page arrives complete. Google indexes everything. Users see content immediately.

No hydration delays. No layout shifts from client-side data fetching. No “loading…” states indexed by Google.

vs React/Next.js

React has a complexity tax:

  • 50 npm packages vs rails new
  • State management debates vs Rails conventions
  • SSR configuration vs server-side by default
  • Build tool complexity vs zero config

I’m not anti-React. It’s excellent for highly interactive apps. But for SEO first app, Rails wins on every metric that matters.


Deploying with Kamal

Kamal is a Docker-based deployment tool from 37signals. Built into Rails 8.

bin/kamal deploy
# That's it.

What Kamal Does

  • Builds your Docker image locally
  • Pushes to a container registry
  • SSHs into your server
  • Pulls the new image
  • Performs a zero-downtime swap
  • Cleans up old containers

Time from commit to production: ~2 minutes.

No CI/CD pipeline to configure. No Kubernetes. No managed platform lock-in.


Bitcoin Integrations

BTCPay Server for Payments

Companies pay $0.50 in BTC to register. Self-sovereign payments, no payment processor.

# app/services/btcpay_service.rb
class BtcpayService
  def self.create_invoice(email:, xpub_id:)
    body = {
      amount: "0.50",
      currency: "USD",
      checkout: {
        defaultPaymentMethod: "BTC",
        redirectAutomatically: true
      }
    }
    # Returns invoice with checkout URL
  end
end

BTCPay handles the payment UI, exchange rate conversion, and confirmation tracking.

Balance Verification - The Journey

First attempt: Ledger’s xpub-scan

Ledger xpub-scan demo

Problem: Quickly hit threshold/rate limits. Fine for personal use, not for scanning 200+ companies. + Unmaintained as public archive

Solution: CryptoAPIs HD Wallet API ($40/mo)

CryptoAPIs HD Wallet Sync API documentation

Now handles xpub balance lookups reliably. Worth every penny for production use.

# app/services/crypto_api_service.rb
class CryptoApiService
  def self.fetch_xpub_balance(xpub)
    # Syncs HD wallet and returns total balance
    # Handles ypub, zpub, xpub formats
  end
end

Total Cost Breakdown

Monthly Running Costs

Service Cost Purpose
Hetzner VPS $5/mo Hosting (Rails + SQLite + BTCPay)
CryptoAPIs $40/mo HD Wallet / xpub balance lookups
RankerFox $20/mo SEO tracking & keyword research
Claude Code Max $200/mo Development (vibe coding)
Total ~$265/mo

What’s Free

  • Domain: ~$10/year (one-time)
  • BTCPay Server: Self-hosted
  • SSL: Free built-in with Kamal
  • Email: Mailgun free tier 100 emails / day

Compare to Typical SaaS Stack

Service Cost
Vercel Pro $20+/mo
Supabase/Planetscale $25+/mo
Auth0 $23+/mo
Total $70+/mo minimum

And that’s before any Bitcoin APIs.

The Claude Code ROI

$200/mo sounds expensive. But:

  • Built entire app in 24 hours
  • Traditional dev time: weeks
  • Ongoing iteration: hours instead of days

It pays for itself in speed.


Key Sources

Data Sources

Inspiration

Rails and Deployment

Bitcoin Integration

Performance

Stephane Bounmy

Stephane Bounmy

Built BitcoinCompanies so my kids can learn Bitcoin on a map full of 🐉 🐋 🐳 🦈 🐬 🐙 🐠 🦀 🦐.
Turns out adults like it too.