Built with

The stack

Every service resell.store talks to, what it does here, and what you lose without it. Only Postgres and an auth secret are truly required: the rest switch features on.

Every service

ServiceRole hereWhat it unlocksNeeded?
PayPalMultiparty payments: sellers connect, orders paid to them with our fee, money held until deliveryReal checkout (PayPal or guest card), escrow, automatic payouts, refundsOptional: a test checkout without it
AI model (Anthropic by default, via the AI SDK)Identifies items, prices them, writes listings, answers buyers, words countersEvery agentOptional: research falls back to plain numbers
Channel3Product catalog: what it is, new and resale prices, maker photosThe catalog and resale research stepsOptional
KernelCloud browsers reading eBay, Poshmark and Depop listingsLive comps and the shopping sidekickOptional
RenderWeb service, Postgres, Workflows and a Cron JobHosting with store subdomains, retried timers that move moneyWhere it runs; locally, a cron route does the timers
Postgres + pgvectorEverything, plus listing embeddingsSearch by meaningRequired
JinaEmbeddings for listings and searchesSemantic searchOptional: text search alone
Cloudflare R2Photo and video storageUploads off the databaseOptional: bytes stay in Postgres
ResendSending emailSign-in links, sale and offer emails, digestsOptional: logged instead
Better AuthSessions and email sign-in linksAccounts shared across store subdomainsRequired
React EmailThe 10 email templatesEmails that look like the appBuilt in
MCP TypeScript SDKThe two MCP serversBring your own AIBuilt in
DrizzleSchema, queries and migrationsType-safe data accessBuilt in

Each service sits behind one file in lib/server/ with a …Configured flag (aiConfigured, channel3Configured, kernelConfigured, paypalEnabled(), r2Configured, embeddingsConfigured), so the app checks the flag instead of crashing on a missing key. The full list of variables is on Environment variables.

How they fit together

One sale, start to finish.

  1. Maya lists her yellow Le Creuset dutch oven. She signs in with an email link (Better Auth, sent by Resend from a React Email template) and uploads a photo, which goes to R2.
  2. Research. The AI model looks at the photo and names it. Channel3 finds the product and what it costs new. Kernel browsers read what the same pot is listed for on eBay, Poshmark and Depop. The model weighs it all and suggests $185.
  3. Published. The model writes the words. On publish, Jina embeds the listing into a pgvector column.
  4. Jess finds it by searching "yellow cast iron pot". Postgres full text and the vector match are merged into one ranking.
  5. Jess pays through PayPal. The order is made out to Maya's PayPal with resell.store's fee in it, and the money is held.
  6. Maya ships; Jess gets it. Jess taps "It's all good" and the money goes to Maya. If Jess never says, a Render Workflow task releases it 13 days after shipping, retrying until PayPal says yes.

Read more