Home/Mare
AboutCV

Mare

January 2026 — Present · Web · Product · Co-founder & Product Engineer @ Mare

TechnologiesNext.js, TypeScript, FastAPI, Supabase, pgvector, Modal, GCP
ContextProduct
MediumWeb
LocationRemote
LiveView live ↗

See also:Mare — Landing Page

Mare is a tool for designers, artists, and researchers whose reference archives have outgrown folders. I co-founded it and built the product end to end: the ingestion pipeline, the clustering layer, the interface, and the deployment. We're in closed beta with 100+ creatives onboarded and around 10,000 reference items processed. Import is one-click from Are.na and Pinterest plus a Chrome extension for capture; items inside are images and links.

How it works

Items pass through an enrichment pipeline that gives each one a hybrid embedding and a set of structured fields. On top of that index sits a clustering layer that reads the library through more than one lens, because no single notion of "similar" captures every kind of structure people put into their archives. The user-facing surface boils that down to three modes that emphasise different signals, an Unclustered rail for items the system isn't confident about, and sub-collections inside clusters that have their own internal structure.

Stack

Next.js and TypeScript on the frontend, a FastAPI service on the backend, Supabase for auth and relational data, pgvector for vectors. LLM-heavy work runs as a separate Modal service so GPU spend sizes independently of the rest of the API. Stripe handles billing.

Deployment

Web and API ship as separate containers on Cloud Run. Cloud Tasks runs async jobs, Cloud Scheduler handles periodic work, Cloudflare R2 holds assets (zero egress and an S3-compatible API). Secrets live in GCP Secret Manager. I migrated us off a single-instance Celery and Redis setup, replacing the always-on worker and broker with the current Cloud Run plus Cloud Tasks split.

Six decisions inside Mare

Import where people already collect

Mare imports in one click from Are.na and Pinterest, plus a browser extension for anything else, instead of asking people to abandon the tools they already hoard references in. Items are de-duplicated on the way in, so re-importing a board doesn't litter your archive with copies.

Every item gets understood, not just saved

Saving a reference is the easy part; making it useful is the work. The decision that shapes everything else: enrich every item on the way in (identify it, describe it, pull its themes and colour palette, link related items) rather than storing it raw and computing later. It costs real work per item up front, but it's what turns the archive from a pile of images into something searchable and clusterable; the lenses, search, and recall all read from that layer. None of it is fixed, though: you can talk to Mare about any item to correct or extend what it pulled, and every cluster comes with alternate names you can keep or rename.

Three lenses on the same library

Mare organises the same archive three ways at once: Balanced (subject and category), Aesthetic (mood and colour), and Semantic (underlying theme), with a Recluster that re-runs them as the library grows. "Similar" isn't one thing: two references can share a subject but not a mood, or a mood but not a subject. Three labelled lenses keep that legible; a single "similarity" dial would flatten it into one axis that's wrong half the time.

Soft membership: an item can live in more than one place

Items aren't bucketed once. The detail view shows the primary cluster an item belongs to and the next-best cluster it also fits into, with the strength of each visible. Most archive UIs flatten 'this also belongs here' out of the model because exposing it costs simplicity. But that flattening is exactly where the cross-references live, and a tool whose job is connecting things you've saved can't really afford to throw them away. We show the second attachment and accept the small UI cost.

Hierarchy where the data calls for it, flat where it doesn't

Clusters can hold sub-collections, but only where the items inside warrant nesting. A 123-item collection might decompose into seven sub-collections; a 12-item one stays flat. Most reference apps either enforce a tree, which forces structure where there isn't any, or refuse one, which loses structure where there is. Letting hierarchy fall out of the data, and letting people drill into a fuzzy boundary, is where the more interesting cross-references in someone's archive end up living.

Pay for work, not for idle

The async work (enrichment, clustering) runs in bursts, so an always-on worker and broker would mostly sit idle burning money. I moved us off Celery and Redis onto request-driven managed queues and a worker that scales to zero. The GPU-heavy model work (self-hosted embeddings and an LLM) runs isolated on its own serverless-GPU service, so it scales and bills independently instead of inflating the base cost. For an early product that's the right shape: you pay for work done, not for capacity you're not using.

The onboarding flow
© 2026 Aakarsh Singh
EmailGitHubLinkedInAre.na