ForgeKitFORGEKIT

Internal · Build Log · Trends

What the sessions
are telling us.

Velocity, outcomes, what worked, what's next. Updated after every session. 11 sessions in.

← Back to build log
11
Sessions
30+
Commits
Tests shipped
38
Rules written

Velocity

How long did each product take?

Sessions to go from zero to live. The trend is the point.

3
sessions

Leashline

first

Live at leashline.forgekits.build

First Rounds app — no template, no shared packages, patterns being discovered in real time

1
session

ForgeHome

Live at home.forgekits.build

Built on the Rounds template from Leashline. Same stack, same auth pattern, same deploy flow. Leashline paid the cost. ForgeHome got the benefit.

~0.5
sessions

Next Rounds app

target

Template + config swap

rounds-app template is complete. cp, find/replace name + colors + schema, db:push, done. The engine is paid for.

Leashline paid the full cost of figuring out the Rounds engine. ForgeHome got the benefit. The next app gets the template. That's the compounding.

What Worked

The moves that paid off

🔁

Same stack = compounding velocity

Every app uses Next.js 16, Drizzle, Neon, Clerk. No new tools to learn, no new deployment patterns, no new auth flows. Leashline took 3 sessions. ForgeHome took 1. The next Rounds app takes half a session. This is the compounding in practice.

🌱

Seed customers beat market research

Katie (Leashline) and Courtney (ForgeHome) are 50 feet away. They use the apps, not focus groups. The "AI prepares, humans deliver" design principle came from thinking about Katie in 10 minutes. That principle now applies to every ForgeKit product.

📐

Build the template before the instance

When scaffolding ForgeHome, we caught ourselves about to build the same structure as Leashline. Stopped, built rounds-app template first, then created ForgeHome as the first instance. ForgeHome proved the template. The template is now the asset.

🎯

Name the engine, then every vertical is a config

Rail (clients come to operator) vs Rounds (operator goes to client). Once named, every new product idea has an obvious engine assignment. House cleaner = Rounds. Insurance agent = Rail. No debate needed. The naming made the architecture portable.

💡

Recognize the pattern, build the skill

Mid-session adding ForgeHome to the website, we recognized it was always the same 3 files: nav entry + homepage card + product page. Stopped. Built /add-product as a Claude Code skill. Next product launch runs /add-product instead of starting from scratch.

🚫

Move beats Overdue — no shame states

ForgeHome has no red overdue state. Homeschool days mutate constantly. The app adapts instead of judging. "Move" advances the date gracefully. This product decision came from knowing Courtney personally. It's now a ForgeKit principle for any tool people use in their personal lives.

What's Next

The current priority stack

1

Forge for Gino

30-day

Contractor CRM for Gino's Electric in Medina OH. This is the first commercial product. Rail engine. Pipeline, contacts, SMS sequences. If Gino pays, the engine is validated.

2

Add/edit flows for Katie

Leashline

Katie cannot add clients, pets, or visits through the UI yet. She needs those before she can use it for real business. Phase 1 usability is the unlock for word-of-mouth.

3

Courtney uses it for a week

ForgeHome

Does she open it tomorrow without being reminded? That's the acceptance test. Don't add features until she's answered it.

4

Migrate leashline into monorepo

Engine

Leashline still has its own .git. Once migrated, all four products share one root. One npm install, one lint run, one place to update shared packages.

Patterns

What keeps coming up

📈

38 rules written — each one is friction that never repeats

Every rule in the playbook came from real pain. Next.js 16 proxy.ts export, Vercel BOM corruption, force-dynamic on DB pages, seed data with real texture. By session 11 the playbook prevents more problems than it takes time to read.

⚙️

Next.js 16 + Turbopack has its own tax — pay it once

The biggest recurring spin category is Next.js 16 edge cases: proxy.ts named export, config re-export through package boundary, force-dynamic on DB pages. These aren't random — they're the same 3 rules. Read them before scaffolding a new app and they cost nothing.

🔁

UI layout spins are always about mobile overflow

Four UI spins across two sessions, all mobile: background pattern bleeding into sidebar, dropdown overflow, objectPosition ignored, horizontal scroll from wide pseudo-elements. The pattern: test at 375px before declaring done. Every time.

🤝

The deploy rule that actually matters

Don't trust git push to trigger Vercel. Don't run vercel --prod from the monorepo root. Always cd into the app directory, then npx vercel --prod. This has burned time in 3 separate sessions. It's in the rules. Read it first.

Where We Spun

Lost time by category

Every spin from every session, grouped by type. A category that hits twice is a gap in the playbook.

Other

7
spins
  • Next.js 16: proxy.ts config can't be re-exported through package boundary
  • Dog walker stock photo took 3 rounds
  • Started scaffolding forgehome/ directly — wrong order
  • leashline has its own .git — can't stage as regular directory

Rule: Inline the matcher config directly in the app's proxy.ts. Never re-export config through a package.

UI Layout

5
spins
  • Background pattern bled through sidebar
  • mailto: fallback doesn't work in Chrome without a mail client set up
  • Dropdown right-overflow on mobile
  • objectPosition ignored for most of the chase

Rule: Scope the background CSS to the <main> content div only, not a fixed viewport overlay

Environment & Config

3
spins
  • dotenv missing from forgehome/package.json
  • Vercel auto-deploy from git push didn't trigger
  • RESEND_API_KEY not set on forgekit-website Vercel project

Rule: npm install dotenv in forgehome/ — it needs to be an explicit dependency, not just assumed from monorepo root

Demo & Narration

1
spins
  • TypeScript errors in generated trends page

Rule: Emit explicit type annotations on array declarations in the generator. Empty arrays need the type: const x: SpinCategory[] = [] — not const x = [].

Test Infrastructure

1
spins
  • Can't test Resend locally — domain verification only works in production

Rule: Deploy and test live. Use /api/debug-contact route to confirm key is set before chasing other causes.

Auto-generated from sessions/*.json. Editorial content (velocity, what worked, what's next) lives in scripts/build-trends.mjs — update it after each session. Run npm run build:trends to regenerate.