I Built a Paid Article Platform in One Day with Claude Code

Publishing platforms take too much. 15-20% fees on every sale. Sell a $10 article and you get $8.

So I built my own. With Claude Code, it took one day.

https://draft-publish.com

Why I Built It

The options for selling paid articles are limited.

Platform Fee Problem
Medium 0% (reader pays $5/mo) Writers don't get paid per article
Substack 10% No CLI, browser-only editing
Gumroad 10% Not designed for articles
Self-hosted WordPress 0% Payment integration is painful

I'm an engineer. I want to write articles in my terminal and publish with a single command. Clicking around in a browser editor isn't my style.

So I decided to build a platform where you write Markdown and run draft push to publish.

Tech Stack

  • Backend: FastAPI + uvicorn (Python 3.12)
  • Frontend: Jinja2 templates + contenteditable editor (no React)
  • DB: SQLite (WAL mode)
  • Payments: Stripe Checkout + Stripe Connect
  • Auth: Google OAuth + X OAuth + password + SSH public key (for CLI)
  • Hosting: Mini PC at home + Cloudflare Tunnel
  • CLI: typer + rich

Why no React? Simple — compatibility with Claude Code. "Build this page with Jinja2 templates" moves dramatically faster than "design React components." No need for an SPA anyway.

How the Day Went

Started in the morning. By evening, the platform was live and ready to sell articles.

Sprint 1 (Morning): Foundation

Told Claude Code "I want to build a paid article platform with FastAPI + SQLite + Stripe" and built basic CRUD with Stripe Checkout integration.

  • Article CRUD (create, list, detail, delete)
  • Markdown rendering (markdown-it)
  • Stripe Checkout (purchase → Webhook → DB update)
  • Paywall (`` marker splits free/paid content)
  • User auth (Google OAuth)

The paywall mechanism is simple. Write `` in your Markdown. Everything above it is free to read. Everything below requires purchase. The server splits the HTML and only returns the free portion to non-buyers.

Sprint 2 (Early Afternoon): Editor

Built a hybrid contenteditable + Markdown editor. Split view with Markdown on the left, live preview on the right.

Features:

  • Toolbar (headings, bold, italic, links, images, tables, code blocks)
  • Keyboard shortcuts (Ctrl+B, Ctrl+I, Ctrl+K, Ctrl+E)
  • Slash commands (type / for a menu)
  • Image drag & drop
  • Auto-save (every 5 seconds)

The slash commands are Notion-style. /image to insert an image, /table for a table, /code for a code block. Told Claude Code "implement Notion-like slash commands" and it just worked.

Sprint 3 (Late Afternoon): CLI

This is the part I'm most proud of. Built a CLI with GitHub-style SSH authentication.

# Install
pipx install git+https://github.com/s-saga011/draft-publish.git

# Set server
draft remote https://draft-publish.com

# Create an article
draft new "Article Title" --price 5

# Put article.md and images in the folder
draft push

draft push auto-detects Markdown files and images in the folder, uploads them to the server, and rewrites image paths in the Markdown automatically.

Authentication uses SSH public keys. Register your public key on the web Settings page, and the CLI signs requests with your private key. GitHub-style, so no passwords to store.

Sprint 4 (Evening): Deploy

Deployed to a mini PC at home (i9-9880H, 32GB RAM).

# Auto-start with systemd
sudo systemctl enable draft

# Expose via Cloudflare Tunnel
sudo systemctl enable cloudflared

Cloudflare Tunnel eliminates the need for port forwarding and SSL certificates. The tunnel connects to localhost, and Cloudflare handles HTTPS. Infrastructure cost is zero beyond the domain ($10.46/year).

Payments: Stripe Connect

Since this is a creator platform, purchase payments need to be automatically split with creators. Used Stripe Connect.

How it works:

  1. Creator connects their Stripe account in Settings
  2. Reader purchases an article → Stripe Checkout handles payment
  3. Stripe automatically sends funds to the creator (minus 3% platform fee)

Total fee: Stripe payment fee 3.6% + platform 3% = 6.6%. Less than half of what other platforms charge.

Added a 30-minute refund guarantee too. One-click refund within 30 minutes of purchase. This is designed to weed out empty content. Articles with high refund rates naturally stop selling.

Multilingual Support

Both the articles and UI support English and Japanese.

  • Templates: All text output through a translation dictionary (i18n.py)
  • Auto-detection from browser language + manual toggle
  • Currency: Japanese → JPY, English → USD (Stripe payments switch currency too)
  • CLI: draft lang en to switch to English

I wanted the platform ready to sell internationally. Technical articles and data analysis articles have demand regardless of language.

Actually Selling Articles

Building the platform means nothing if nobody uses it. So I became my own first customer.

I ran AI-powered investment backtests and turned the results into articles. Backtested all S&P 500 stocks — 730,000 data points.

Workflow:

  1. Write backtest code with Claude Code
  2. Generate charts with matplotlib
  3. Ask Claude Code to "turn these analysis results into an article"
  4. Polish the output Markdown and draft push

From article creation to publishing, no browser needed. Everything happens in the terminal.

Current State

  • Live in production: https://draft-publish.com
  • Articles: 10 (Japanese/English)
  • CLI: One-line install via pipx

Still Todo

  • Exchange rate API integration (currently hardcoded)
  • More users (marketing)

Technically Interesting Points

SQLite Is Enough

"SQLite for a paid service?" you might think. But SQLite with WAL mode enabled is surprisingly capable. It handles up to ~100K monthly page views with no issues. No need to migrate to PostgreSQL until concurrent writes exceed 10 per second.

Server resource usage: 5.4GB/31GB memory, 0.04 CPU load, 10% disk. Nothing is happening.

Cloudflare Tunnel

Cloudflare Tunnel was the best choice for exposing a home server.

  • No port forwarding (don't touch router settings)
  • No SSL certificate management (Cloudflare handles it)
  • Free DDoS protection included
  • No static IP required

Write 4 lines in config.yml and register with systemd. Done.

tunnel: xxxxx
credentials-file: /home/user/.cloudflared/xxxxx.json
ingress:
  - hostname: draft-publish.com
    service: http://localhost:8001
  - service: http_status:404

SSH Key Authentication (CLI)

Implemented GitHub-style SSH authentication from scratch.

  1. Server generates a random nonce (challenge) and returns it
  2. Client signs the nonce with their private key and sends it back
  3. Server verifies the signature against registered public keys

No passwords to store. If ~/.ssh/id_ed25519 exists, authentication is automatic.

Building with Claude Code

Getting a working product in one day was thanks to Claude Code. What worked well:

  • Stripe Webhooks, OAuth, SSH auth — anything requiring "read the spec and implement it precisely" was fast
  • Jinja2 template mass-production was absurdly fast (full EN/JP support for all pages in half a day)
  • Bug identification and fixes were fast (paste the error log and get the cause + fix)

What was tricky:

  • Stripe Connect test vs production environment switching caused confusion
  • Cloudflare Tunnel DNS setup had a small hiccup

Both were external service configuration issues, not Claude Code problems. The code itself worked almost first try.

Takeaway

A paid article platform is buildable in one day with today's tech stack.

  • FastAPI + SQLite + Stripe is enough
  • Cloudflare Tunnel to expose a home server for free
  • Claude Code to 10x development speed

6.6% fee, 30-minute refund guarantee, CLI publishing. If you're tired of platform fees, give it a try.

https://draft-publish.com

CLI repo: https://github.com/s-saga011/draft-publish