Aakarsh SinghProduct Engineer & New Media Artist
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 lenses 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 keep their references in. Items are de-duplicated on the way in, so re-importing a board doesn't litter your archive with copies.

Every item is enriched on import

Saving a reference is easy, and making it useful is the work, so we 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. That costs real work per item up front, but it turns the archive from a pile of images into something searchable and clusterable, and 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, because two references can share a subject and still feel nothing alike, so three labelled lenses keep that legible where a single "similarity" dial would flatten it onto one axis that's wrong half the time.

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

Because items aren't bucketed once, the detail view shows the primary cluster an item belongs to alongside 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 afford to throw them away, so we show the second attachment and accept the small UI cost.

When a cluster splits into sub-collections

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.

Scale-to-zero for bursty work

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, since the bill tracks actual work rather than idle capacity.

The onboarding flow
© 2026 Aakarsh Singh
EmailLinkedInAre.naGitHubInstagram