01 · How it's built
Eight months, one developer, a cross-poster that runs itself.
DEADSTOCK lists a Shopify store on Grailed and keeps the two in step. Underneath is a small cloud platform: a control plane, a private server for every seller, and a real browser doing the posting. This is how it fits together.
- commits since April 2026
- 1,128
- commits since April 2026
- lines of Python and TypeScript
- 124k
- lines of Python and TypeScript
- automated tests, most against a real Postgres
- 3,400+
- automated tests, most against a real Postgres
- Shopify App Store submission
- 1
- Shopify App Store submission
Counted from the repository, October 2026.
02 · The parts
Four pieces, each doing one job.
Part 01
A control plane
Next.js and TypeScript on a self-hosted Postgres. It signs sellers in, connects their Shopify store over OAuth and webhooks, starts their server, decides their plan, and watches the whole fleet: health, versions, alerts.
Part 02
One private server per seller
Each seller gets their own machine, started from a pre-made image and reachable only through Cloudflare. A Python service, its own database, a dashboard, and a real Chrome — nothing is shared between sellers.
Part 03
A browser that posts
Grailed has no public listing API, so DEADSTOCK fills in Grailed's own sell form in the seller's signed-in browser, then reads the live listing back to prove it went up as intended.
Part 04
Two-way sync
Sold on Grailed: Shopify stock goes down. Sold in the store: the Grailed listing comes down. Every action is written to a ledger first, so nothing happens twice and nothing is ever added back by itself.
03 · Hard problems
What took the time.
No oversells
Anything that touches stock or money fails closed: when the system cannot be sure, it waits and asks instead of acting. Listings are matched to their product photo, not just the title.
Datacenter walls
Cloud servers get challenged on sight. The fix was to read Grailed from inside the seller's own signed-in page, where they are just a seller looking at their listings.
AI with limits
Claude reads titles and descriptions to suggest the category, size and measurements. Rules check every answer, each seller has their own spending limit, and a breaker stops posting cleanly if credits run out.
Safe to change
Deploys check that the new version is healthy and roll themselves back if not. One switch pauses posting across every server. Every fix ships with a test that failed before it.
Secure by default
Only a server's owner can reach it. The sign-in browser is locked down, cloud metadata is firewalled off, and the code goes through red-team passes, with every finding fixed and tested.
Leaving cleanly
When a plan ends or the app is uninstalled, a grace period, then a takedown that removes only what DEADSTOCK can prove it posted, then deletion of the seller's data on Shopify's timeline.
04 · Stack
Built with.
- Python
- FastAPI
- TypeScript
- Next.js
- React
- PostgreSQL
- PostgREST
- Docker
- Playwright / Chrome DevTools
- Shopify GraphQL Admin API
- Clerk
- Cloudflare
- DigitalOcean
- Caddy
- GitHub Actions
- Claude via OpenRouter
05 · Try it