Peter Hughes

Peter's Origin Leaf

The very first leaf on crann.ai, planted by Peter himself. A historic moment captured—the beginning of a new way to share focused spaces online.

scroll

Building crann.ai — A Journal

March 2026


What is crann.ai?

crann.ai is a social publishing platform built around a simple idea: everyone deserves their own corner of the internet. When you sign up, at least for now you get a subdomain — username.crann.ai — and inside it you can grow leaves: themed, public-facing spaces for whatever you want to publish. A personal blog, a community group, a business page, a photography portfolio. Each leaf is its own self-contained world with its own visual identity, content, and audience.

The name comes from the Irish word for tree (crann). Users grow a tree of leaves. It's a small bit of soul in the domain name.


Phase 1 — Foundation and Social Core

The first real feature commit was the social layer: leaf follows, a network activity feed, and a landing page.

This set the direction early. crann.ai isn't a static site builder — it's a social platform. Following a leaf means you see its updates in your feed. The feed uses cursor-based pagination so it scales without offset queries getting slow.

At the same time, dynamic SEO metadata was added to leaf and identity pages from the start. Public leaves are meant to be found.

Also in this phase: an AI-powered quick update — a conversational interface where you describe what you want to post and the AI drafts it for you. The idea of weaving AI into the content creation flow, rather than bolting it on later, was a deliberate early decision.


Phase 2 — Compliance First

Before going further with features, a full compliance layer was built. This felt counterintuitive at first — it's not the exciting part — but it was the right thing to do.

  • Privacy policy, terms of service, and cookie policy pages under a (legal) route group
  • A cookie consent banner with essential-only / accept-all options
  • Date of birth collection at signup with a 13+ age gate (COPPA)
  • Consent checkboxes for ToS and privacy policy at signup, with server-side validation
  • An OAuth accept-terms page for users who sign up via Google or GitHub and bypass the signup form
  • Soft-delete account deletion with a 30-day grace period and password verification
  • GDPR data export: a JSON download of everything we hold on a user

Getting this right early meant not having to retrofit it later around a growing feature set.


Phase 3 — Community, Events, and Org Leaves

The biggest single feature commit added an entire category of leaf: community leaves — spaces for groups, clubs, and neighbourhoods.

Alongside personal leaves (for individuals) and business leaves (for companies), community leaves have a distinct set of virtual pages:

  • Events — full CRUD, themed public event listings
  • Find Us — an embedded Leaflet map
  • Contact form — public-facing form with a submissions inbox and read tracking

This was also when AI-powered page content generation landed — owners can describe a page and get a full draft, with short/medium/long size options and syntax highlighting for code blocks via rehype-highlight.

A visitor navigation bar was added for logged-in users browsing someone else's leaf — including a "Browse" dropdown showing related leaves that share tags with the current one, loaded client-side to avoid blocking page render.


Phase 4 — Infrastructure and Routing

Shipping features surfaced some infrastructure issues that needed fixing properly.

The subdomain routing had a double-prefix bug: when accessing a leaf via username.crann.ai, the middleware was incorrectly prepending /s/{subdomain} to paths that already had it. Fixed by stripping the prefix before rewriting.

The deploy pipeline had a migration ordering issue — the migrate service was running against the previous image because the workflow wasn't rebuilding it before running migrations. Fixed in the CD workflow.


Phase 5 — Profile, Comments, and Brand Alignment

Several things came together in this phase.

Threaded post comments with rate limiting and moderation. This was the first social interaction that happens on someone else's content rather than your own.

A profile page redesign — the profile at username.crann.ai became a proper hub showing the user's avatar, their leaves as cards, and their connections. Avatar upload with a camera overlay for the owner.

Unified navigation: previously the site had separate nav components — VisitorNav, ProfileNav, various inline navs depending on the page. These were collapsed into a single SiteNav and SiteFooter used everywhere. This matters for consistency and makes future changes easier.

Brand alignment across the whole site — all colour references converged on semantic design tokens with the mint accent and Manrope font. AI-generated leaf themes were audited for contrast to ensure readability on any theme background.


Phase 6 — Password Reset and Help Center

Password reset was implemented properly:

  • SMTP with DKIM signing via Postfix
  • SHA-256 hashed tokens with a 1-hour expiry and single-use enforcement
  • Anti-enumeration: the response is identical whether or not the email exists
  • Rate limited to 3 requests per 15 minutes per IP

Alongside it: a full help center — hub, FAQ, getting started guide, articles on leaves, posts & pages, events, and account security. The help center matters for a platform like this because the "leaf" mental model is unfamiliar and users need orientation.


Phase 7 — Profile as Hub

The most recent significant change was merging the dashboard into the profile page.

Previously, after login you landed on /dashboard — a separate page that showed your leaves and activity. The profile at /s/{username} was a public-facing page.

These were consolidated: the owner's profile page at /s/{username} is now the authenticated hub. It shows the "Grow Something" section, the activity feed, and the leaf list. The dashboard redirects to the profile. The nav was updated accordingly — the logo links to your profile, the profile link goes to settings.

This simplification removes a conceptual split that didn't need to exist. Your public page and your home base are the same place. Visitors see the public view; you see the owner view.


What's Next

The core platform is working. The pieces that matter most for what comes next:

Custom domains. The architecture was designed for this from day one — Caddy's on-demand TLS, a DNS setup that supports per-domain certificates, a custom_domains table ready to be added. Users will be able to point their own domain at a leaf.

Leaf discovery. The tag-based related leaves browsing is a start. Building out proper search and discovery is the next social layer.


crann.ai is built with Claude Code and ChatGPT. The irony of an AI writing this retrospective is not lost.

crann.ai is live.

crann.ai is live.

A place to grow your ideas, share what you're building, and put down roots online — on your own terms.

Each leaf is a space you own. Write about what matters to you, share updates with your network, or build something entirely public. Your content, your subdomain, your corner of the internet.

What's here now

  • Personal leaves with custom subdomains (yourname.crann.ai)
  • AI-assisted writing to help you get started
  • Themed layouts that make your space feel like yours
  • Privacy controls — share publicly, with connections, or keep things private

What's coming

This is just the beginning. We're building crann.ai in the open, and there's a lot more on the way.

If you're here early — welcome. You're part of something from the start.