A link-in-bio platform built on an anti-greed foundation where the price drops the more people subscribe.
Product Lead · Web · Next.js · Convex
01 · Origin
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 and it had an audience (of mostly Designers) that liked it. Then Linktree acquired it, let it run for about 2 years and then shut it down. The loss was personal: the studio's own bento profile was among the casualties, therefore we started working on Bhann the week the shutdown email arrived.
The obvious response is to build a clone (that's exactly what we did at first) to fill the gap, serve the displaced users, run on standard SaaS pricing. That is the sensible business decision. Bhann is not that, it is the other response: build the replacement with a structural principle that makes it incapable of doing what Linktree did (getting acquired and killed).
Not a clone. A villain seeking vengeance for the death of a loved one, and its weapon is the pricing model.
Linktree Pro costs (at the time of writing) €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. 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.
02 · The Staircase
The pricing model has 21 tiers, and the staircase lived as a spreadsheet for a month before any code was written, the steps were redrawn a dozen times before they stopped moving. Tier 1, Pioneer, is for the first 99 paying subscribers, set to €30 per year. When the platform reaches 100 subscribers, the price drops to €26 for everyone and the tier becomes Founder. At 500, €22; at 1,000, €19, and so on in decreasing steps down to a floor of €6 per year at 1 million subscribers. Free accounts do not move the staircase, only paying subscribers count.
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.
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.
// 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 ish years, after that they cost me money.
Linktree does things Bhann cannot (yet) like social scheduling and 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 paid plan starts at €30 versus €54 and the gap widens every time a new subscriber joins.
03 · The Editor
The profile editor is a drag-and-drop bento grid built on react-grid-layout. Cards have 4 preset sizes, can be placed anywhere, and styled based on their content. Desktop and mobile layouts are stored independently so the same cards can have 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.
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.
// 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 and only for the Paid Subscribers: background (solid, pattern), 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 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.
04 · The Platform
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 and 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 as well as the ratio of income to expenses. The data comes directly from the Convex backend and refreshes in real time (every day at midnight). Anyone can see whether the platform is covering its costs before they decide to subscribe.
Analytics are built into every published profile: views, unique visitors, card clicks, top countries, and referrers. 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.
Outcomes
130 users generating about €80 in three months, by any standard growth metric, this is a failed launch. The honest assessment is that it is a structurally sound product but in a crowded category and without a marketing strategy, therefore 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 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 itself but rather 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. 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 weeks.
Try Bhann