Brand, build, and run an online comic book store from scratch — including a full platform rebuild when WooCommerce hit its ceiling.
Role
Founder
Client
Worlds End Books
Stack
WooCommerce → Medusa.js · React · Python
Sandman: Preludes and Nocturnes — Worlds End Books sells story arcs as
bundles. Issues one through eight of the 1989 Sandman series,
two hundred forty dollars for the arc. Issue seven, The Sound of Her
Wings, is highlighted as the first appearance of Death.
Worlds End Booksellers · the arc as the unitlive · worldsendbooksellers.com
Story arc · No. I
Preludes & Nocturnes
Sandman · 1989 · #1–8
Sleep of the Just · Imperfect Hosts · Dream a Little Dream of Me · A Hope in Hell · Passengers · 24 Hours · Sound & Fury · The Sound of Her Wings
#1Sleep of the Just
#2Imperfect Hosts
#3Dream a Little…
#4A Hope in Hell
#5Passengers
#624 Hours
#7Sound & Fury
#8Her Wings
arc bundle · 8 issues$240
Story arc · No. I
Preludes & Nocturnes
Sandman · 1989 · #1–8
#1Sleep of the Just
#2Imperfect Hosts
#3Dream a Little…
#4A Hope in Hell
#5Passengers
#624 Hours
#7Sound & Fury
#8Her Wings
arc bundle · 8 issues$240
Context
In early 2021 I started Worlds End Books, an online comic book store built around a simple premise: comics are better when you follow story arcs, not single issues. Most stores organize by publisher and title. I wanted to organize by story.
I’d been doing web work for clients for over a decade. This was the first time I was the client, the developer, the shipping department, and the customer service rep all at once.
The Problem
The early version ran on WooCommerce. It worked. Then it didn’t: not at the scale I needed, not with the inventory complexity I was dealing with, not with the custom arc-bundling product format that was central to how the store sold comics.
WooCommerce wanted me to think about products the way WooCommerce thinks about products. I needed to think about products the way a comic reader thinks about story arcs. Those two things are not compatible at depth.
World's End Booksellers full-stack blueprint. Three primary tiers drawn as an east elevation: I — Catalog (Flask · iPhone), II — Backend (Medusa · Postgres), III — Stage (Next.js · Coolify). Gold connector pipes carry push and read labels between tiers. Title block at left shows the brand mark, wordmark, and a live status indicator reading "live · in trade · 2026".
At the same time I was learning what it actually means to run a small business: cash flow, supplier relationships, shipping software, returns, customer communication. Every conversation I now have with a client about conversion rates or site reliability lands differently because I’ve been on the wrong end of a shipping error at 11pm on a Friday.
Approach
I rebuilt on Medusa.js, an open-source headless commerce platform, with a custom React frontend and a Python inventory management tool I wrote to handle the arc-bundling logic. No off-the-shelf plugin was going to solve the problem I had, so I stopped looking for one.
The Tooling Pipeline: six stops from phone to curated web shelf. I — Capture: photograph the issue with iPhone, file lands at /static/photos/we_8b3a1f.jpg. II — Seed: two-field Flask entry form, title "sandman 1989" and issue number 8. III — Enrich: Grand Comics Database match returns The Sandman (1989) #8 with creators Gaiman, Dringenberg, McKean. IV — Price: eBay Browse API live snapshot, low $48, avg $74, high $112. V — Publish: POST /admin/products returns 200, product linked with story_arc sandman. VI — Surface: /shop/c/sandman collection, 75 issues, issue #8 highlighted. Closing chop: shelved twice — once by issue, once by arc.
plate · ii · the tooling pipeline
From a phone in the pocket
to a curated shelf on the web.
The curator types two fields. The system fills in everything else —
from a 3.6 GB local sqlite, from live eBay listings, from a Medusa
backend on a Hetzner VPS. The data the curator never types is what
makes the shop feel curated.
DC · 1989S
/static/photos/we_8b3a1f.jpg
iphone 15 · 16:421.8 mb · 3024×2016
I
captureiPhone camera · /static/photos
Photograph the issue
Five seconds at the back counter. The phone’s already in the pocket; JPEGs land in /static/photos and the filename manifest is stored on the row as a JSON array. Reorderable, two-step delete in the management modal — the photo is the first piece of data, never the last.
flask · /entry2 fields total
title
sandman 1989
issue #
8
search GCD ↓
II
seedFlask · /entry · localhost:5000
Two fields, that’s it
The only place a human types. Title and issue number. Everything that follows arrives from a real database — the curator stays at the counter, not at a keyboard. Autosuggest on the title field stops you re-typing series you’ve already shelved.
gcd · matchgcd_issue#142893
The Sandman (1989) #8
dateAug 1989 · DC ComicsvariantCover A · standard
Neil Gaiman · wr M. Dringenberg · art D. McKean · cv
III
enrich3.6 GB · local sqlite · quarterly refresh
Grand Comics Database
A local copy of the volunteer-maintained GCD. Fuzzy match (progressive word-dropping, creator-name stripping) returns the issue with credits (writer · pencils · inks · cover artist), publisher, exact cover date, and any variant text in brackets. 209 unique creators normalised into a join table — searchable, not just stored.
ebay browse · activeoauth2 · last 90d
low$48
avg$74
high$112
32 active · 14 sold (90d)curator picks
IV
priceOAuth2 · live snapshot · low / avg / high
eBay Browse API
A live query against active eBay listings, keyed on series + issue + condition. Low, average, and high all land as a hint. The curator still picks the number — but the number arrives with the data, not as a guess from memory, and it can be refreshed in place from the inventory table later.
POST /admin/products200 · linked
handlethe-sandman-1989-8variantcover a · condition VFstory_arcsandmanstock1 · main locationprice$74.00 usd
V
publishPOST /admin/products · v2 · Hetzner
Push to Medusa
One tap. The row becomes a real Medusa product — handle, variant, stock at the main location, creators normalised to a join, story_arc metadata set from the comic’s first collection. Photos uploaded by filename with dedup on resync; series collections auto-created once a title has two or more issues.
/shop/c/sandmanThe Sandman
75 issues
#6
#7
#8
#9
#10
#11
filter · condition · year · creatormeilisearch · curated
VI
surfaceNext.js · /shop/c/[arc] · faceted
Story-arc collections
The data the curator never typed is what makes the shop. Story arc, series year, publisher, condition — all filterable, all faceted by Meilisearch. Every book is shelved twice: once by issue number, once by the arc it belongs to. Browsing The Sandman means browsing a real reading order, not a tag.
iphone · flask · sqlite · gcd · ebay · medusa · next.js · meilisearch
shelved twice · once by issue, once by arc
The brand had been designed by a hired designer who I gave a deliberate brief: nothing superhero, nothing primary colors, nothing that looks like it belongs in a mall. The result was moody, a little old-world, with a nod to Neil Gaiman’s Sandman. It felt right for a store that takes the medium seriously.
Outcome
Worlds End Books is still running. The rebuild is stable. The arc-bundling format has become the thing customers mention most. It’s the reason people come back.
Building something of your own changes how you do client work. You stop thinking about websites as deliverables and start thinking about them as businesses.