How this works
Tasteless runs on Next.js 16 and React 19, written in TypeScript and styled with Tailwind v4. Content lives in two places — Supabase for Postgres and image storage, and git for the essays — and the whole thing is deployed on Vercel.
The type is small on purpose. Body text is 12px, kickers are 9px monospace with wide letter-spacing, and serif — the type you are reading now — is reserved for quotes and essays and never used for chrome. At 16px this would read as a blog. At 12px it reads as an index: a list of things, not a stream of posts asking to be read in order.
Most of what appears here arrives from a phone. A Telegram bot receives the message — a link, a photo, a stray thought — and hands it to a vision model, which classifies the kind, writes a title, and suggests tags. The post lands in the grid within seconds, no editor open, no draft saved and forgotten. Essays are the opposite: MDX files committed to git, written slowly, reviewed before they ship. The two backends exist because the friction is different — a link worth keeping should take no more effort than sending a text, but an essay is not something you want assembled by a bot in a hurry.
Every captured post gets a catalogue number the moment it is created, assigned once from a database sequence and never reassigned. Deleting a post leaves a permanent gap rather than letting the next post inherit its number — a number that could point somewhere else tomorrow isn’t a citable address. /001 is the first thing ever posted here, and it will always be /001.
The archive is also available outside the grid. Any post can be fetched as plain text at /raw/<number-or-id>, and the whole published archive is available as JSON at /index.json. Nothing is held back behind a special format for machines — it’s the same archive, just honestly available.