B

AAOA.studio · Case Study · Web · Next.js · Convex

They killed bento.me
We built something better

A link-in-bio platform built on an anti-greed foundation: the price drops the more people pay. Not a clone, a villain seeking vengeance for the death of a loved one.

Next.js 16 Convex · Clerk · Stripe Dec 2025 – Apr 2026 bhann.me ↗
Accent
Scroll
Opportunity
When Linktree killed bento.me, a real vacuum opened for designers who had built their online presence around a bento-grid layout. Every copycat that filled it reached for the same extractive model, maximum subscription price, forever. The structural bet: a pricing system that makes extraction constitutionally impossible. Every new subscriber lowers the price for everyone, including people who already paid.
Decisions left out
Social post scheduling, content calendars, and other Linktree feature parity items were not built, not as a strategic differentiator but as an integrity call. A lean team that cannot maintain a feature properly should not ship it. The scope stayed within what could be done well. The gap to Linktree's breadth is real and acknowledged in the comparison table.
Honest assessment
126 users. €80 in three months. A technically sound anti-greed model in a crowded space that nobody discovered. The product is structurally right. The distribution problem was never solved. The platform stays live while personally useful, and as a live proof-of-concept that decremental pricing is implementable, but without a marketing strategy, a good model is invisible.
0
commits in four months
Dec 2025 – Apr 2026
21tiers
pricing tiers, all decreasing
€30/year → €6/year floor
0+
card types in the editor
Social · media · commerce · interactive
0
TypeScript source files
96 TSX · 36 TS

Ch01

The origin. Linktree acquired bento.me. Then they killed it.

Bento.me was a link-in-bio tool built around a bento-grid layout, a flexible canvas of cards for links, social profiles, media, and whatever else a person wanted to surface. It was good. It had an audience that liked it. Then Linktree acquired it, and shortly after, shut it down. The loss was personal: the studio's own bento profile was among the casualties, hastily exported as a screenshot the week the shutdown email arrived.

The obvious response is to build a clone. Fill the gap, serve the displaced users, run on standard SaaS pricing. That is the sensible business decision. Bhann is not that. Bhann is the other response: build the replacement with a structural principle that makes it constitutionally incapable of doing what Linktree did.

Not a clone. A villain seeking vengeance for the death of a loved one, and its weapon is the pricing model.

Linktree Pro costs €54 a year ($4.50 a month). That price does not change based on how many people use Linktree. The more subscribers they have, the more revenue they extract, full stop. This is the standard model: grow subscribers, grow revenue, the two are proportional, the company keeps the difference between cost and price forever.

Bhann inverts the relationship. Subscriber growth lowers the price, for everyone, including the people already subscribed. The product still has to sustain itself but any margin beyond that goes back to the people paying for it. The platform cannot become a machine for extracting value from a captive user base because it is structurally prohibited from doing so.

B

Ch02

The staircase. Price drops as more people pay.

The pricing model has 21 tiers. Tier 1, Pioneer, is for the first 99 paying subscribers: €30 per year. When the platform reaches 100 subscribers, the price drops to €26 for everyone and the tier becomes Founder. At 500 subscribers, €22. At 1,000, €19. Free accounts do not move the staircase; only paying subscribers count. The descent continues in decreasing steps until the floor: €6 per year at one million subscribers. The staircase lived as a spreadsheet for a month before any code was written, and the steps were redrawn a dozen times before they stopped moving.

Three properties make this model interesting. First, everyone always pays the current market price or less, never more. When a new tier is reached, all subscribers move to the lower price. Second, when you subscribe, your tier index is locked: if you joined at €30 and the price drops to €19, you renew at €19, not €30. Third, the lock only ever improves. If you somehow locked at a higher tier index than the current market, you pay the current lower market price at renewal.

Tier name Subscribers Annual vs. Linktree Pro
PioneerNow 0 · 99 €30/yr €24 cheaper
Founder 100 · 499 €26/yr €28 cheaper
Architect 500 · 999 €22/yr €32 cheaper
Catalyst 1,000 · 1,999 €19/yr €35 cheaper
Builder 2,000 · 4,999 €16/yr €38 cheaper
· · · 16 more tiers · · ·
Legacy 1,000,000+ €6/yr €48 cheaper, floor reached

The staircase is implemented in convex/pricing.ts. A single stats table tracks the live paying subscriber count; free accounts never touch it. On every subscription event, the current tier index is looked up and stored on the user record as lockedTierIndex. At renewal, the system takes the minimum of locked and current market price, the user always wins any tie.

TypeScript · Convex pricing.ts · tier lock logic
// At subscription time: lock to current tier index.
// HIGHER index = LOWER price (better for user).
// Keep existing lock if it's already better.
const newLockedTierIndex = user.lockedTierIndex !== undefined
  ? Math.max(user.lockedTierIndex, currentTierIndex)
  : currentTierIndex;

// At renewal: pay whichever is lower, locked or current market.
const actualAnnualPrice = Math.min(lockedAnnualPrice, marketAnnualPrice);

There is also a lifetime option at €163.57, a one-time payment, no renewals, no subscriptions. The amount is not round, it is what the model's NPV calculation suggested was fair given projected infrastructure costs and the floor price trajectory, basically projected user cost for the next 10 years, after that they cost me money.

Feature
Bhann
Linktree Pro
Annual price (current)
€30/yr (dropping)
€54/yr ($4.50/mo)
Price drops with growth
Yes, structurally
Never
Early subscriber benefit
Locked to best price seen
None
Lifetime option
Yes, €163.57
No
Bento-grid profile editor
Yes
No
Social post scheduler
No
Yes
Analytics (views, clicks, geo)
Yes
Yes
Public financial transparency
Yes, live metrics page
No

Linktree does things Bhann cannot, social scheduling, a large partner ecosystem. The comparison is not a claim that Bhann beats Linktree across every dimension. It is that for a creator who only needs a link-in-bio page, which is most of them, Bhann starts at €30 versus €54, and the gap widens every time a new subscriber joins.

B

Ch03

The editor. A bento grid of intent.

The profile editor is a drag-and-drop bento grid built on react-grid-layout. Cards can be any size, placed anywhere, and styled individually. Desktop and mobile layouts are stored independently, the same cards, different positions, so a profile can be genuinely optimised for both form factors rather than one being a collapsed version of the other.

The card system supports 67+ distinct types. Social platform links, embedded media, commerce integrations (Gumroad, Ko-fi, Patreon, Stripe), professional portfolio cards (GitHub, Dribbble, Figma, Behance, Calendly), interactive toys (a tone matrix sequencer, an etch-a-sketch, an analogue clock), and a full-length case study card with block content edited in a Tiptap rich text editor. The tone matrix sequencer was built in a single evening, mostly as a joke, and then refused to be cut, it remains one of the most fun interactive cards. The set is large enough to cover almost any creator's real use case while keeping the interface coherent.

CARD CATEGORIES

Social media Music / media Commerce Portfolio Interactive Email capture Testimonials FAQ accordion Service menu Event RSVP Case study Map NFT gallery Tour dates Availability

Public profiles are server-rendered and edge-cached using Next.js ISR with a 60-second revalidation window. The first request after a cold edge miss hits the Convex backend; every subsequent request within the minute is served from Cloudflare's edge network without touching the database. Profile edits appear within 60 seconds without a redeploy.

TypeScript · Next.js [username]/page.tsx
// ISR: revalidate every 60 seconds.
// First request misses cache → hits Convex → caches at edge.
// Subsequent requests served from Cloudflare in <100ms TTFB.
export const revalidate = 60;

// Edge runtime for sub-100ms cold starts on Cloudflare.
export const runtime = "edge";

// LLM-friendly profile data embedded in server-rendered HTML.
// AI agents can read public profiles without client-side JS.
const llmProfile = generateLLMProfile(profile);

Themes are configurable at the profile level: background (solid, gradient, image, pattern), heading and body fonts, card border radius, spacing, and a full set of colour tokens. Individual cards can also override their own background and text colour. A card theme registry maps named themes to CSS variable sets, applied at runtime via a ThemeStyleInjector component that does not require re-rendering the grid.

THE DESIGN SYSTEM

The 67+ card types are a component library in the traditional sense: each card has defined variants, a token-based theming contract, and strict separation between layout structure and visual presentation. The ThemeStyleInjector applies CSS variable sets at the card level without touching the grid layout, so a profile's visual language can change entirely without a single DOM reflow. The same token architecture governs profile-level themes and per-card overrides, the same way semantic design tokens govern both global and local scope in a mature design system. It is what makes 67 card types feel like one coherent editor rather than 67 separate design problems.

Profile editor · bento grid · card palette
B

Ch04

The platform. Radical transparency, public metrics, early badges.

The anti-greed foundation only works if it is verifiable. A platform that claims to lower prices as it grows, but does not show you whether it is actually growing, is just a marketing pitch. The staircase only descends if the subscriber count actually climbs, so the climb has to be public: Bhann publishes its financials in real time.

The transparency page shows live MRR, total users, paying users, monthly infrastructure costs, initial build spend (€1,365.17), current balance, and a sustainability gauge, the ratio of income to expenses. The data comes directly from the Convex backend and refreshes in real time. Anyone can see whether the platform is covering its costs before they decide to subscribe.

Transparency page
Live MRR, paying users, expenses, and a sustainability gauge. Public and real-time, before you subscribe, you can see if the platform is healthy.
bhann.me/transparency
Staircase calculator
An interactive public tool that models whether decremental pricing is viable for any SaaS, configure stack, growth rate, and conversion to see projections at every tier milestone.
bhann.me/staircase
Founder badges
Join order is recorded on signup. First 100 get a gold Founder badge. Next 900 get Early Adopter. Badges are permanent and public on profiles.
join order → badge

Analytics are built into every published profile: views, unique visitors, card clicks, top countries, referrers, and device breakdown. Data is stored in a single consolidated record per profile, not one row per event, updated incrementally on each view or click. This keeps query costs proportional to the number of profiles, not the number of events, which matters at scale on a platform where infrastructure cost is part of the pricing argument.

TECH STACK

Next.js 16 + Edge runtime
ISR public profiles cached at Cloudflare edge. Sub-100ms TTFB. LLM-friendly server-rendered HTML for AI agents.
App router · ISR · revalidate: 60
Convex
Real-time backend, no separate API server. Database, server functions, cron jobs, and webhooks all in one. Live transparency metrics with zero infrastructure overhead.
Realtime · serverless · TypeScript
Clerk + Stripe
Authentication and payments. Stripe webhooks drive tier lock updates in Convex. Fallback checkout verification ensures no payment is missed if a webhook fails.
Auth · subscriptions · lifetime IAP
Transparency page · sustainability gauge · live metrics
B

Coda

The model is the product.

126 users. €80 in three months. By any standard growth metric, this is a failed launch. The honest assessment is that a structurally sound product in a crowded category, without a marketing strategy, is invisible, and visibility was never part of the plan.

What the numbers do not invalidate: the model works. The staircase pricing is implemented, auditable, and live. The transparency page shows real figures in real time. The founder badges are locked to join order in the database and cannot be revised. The platform does exactly what it claimed it would do, and nothing it could not maintain, the same integrity call that kept the social scheduler out of scope. The problem was not the idea, it was that ideas do not distribute themselves.

The lesson is about sequencing. A novel pricing model is a story that needs to be told, loudly, repeatedly, to the right audience. Building the model and assuming the story would spread on its own was the mistake. The platform will stay live as long as it is personally useful, and as a proof that decremental pricing is not theoretical. If the marketing ever arrives, the product is ready.

Bhann was built with Cursor and Claude Code throughout. The decremental pricing model, the bento editor's drag-and-drop layout logic, the ISR caching layer, the Stripe webhook and tier lock system, implemented in four months at the pace these tools make possible for a lean, designer-led team. The architecture decisions were never AI's to make: whether the pricing model was structurally sound, what the 67 card types should be and how they should compose, why the transparency page mattered to the anti-greed argument. Without LLMs as an implementation partner, a designer without a CS degree does not ship a full-stack Next.js + Convex platform. With them, it took four months.

Try Bhann