All projects TCGSL · Write-up
176 sets, one screen at a time176 Sets, ein Bildschirm nach dem anderen
TCGSL lists every English and Japanese Pokémon TCG set with its real logo and its best cards. Most of the work went into speed: the list is one small file, and each image is fetched only when it’s about to be seen, at the size it’s drawn.TCGSL listet jedes englische und japanische Pokémon-TCG-Set mit seinem echten Logo und seinen besten Karten. Die meiste Arbeit steckt in der Geschwindigkeit: Die Liste ist eine kleine Datei, und jedes Bild wird erst geladen, kurz bevor man es sieht, und nur in der Größe, in der es gezeigt wird.
- Type
- Web appWeb-App
- Stack
- Svelte 5 · Node · sharp
- Year
- 2026
- Code
- Public on GitHubÖffentlich auf GitHub
Every set, newest first
TCGSL lists every English Pokémon TCG set, from Base Set in January 1999 to the latest release: 176 of them at the moment. Each row has the release date, the set’s logo and symbol, its name and card count, and its most valuable card; on a wider screen the three most valuable fan out. The rows are grouped by year, a rail beside them jumps to any year, and on a phone the rail becomes a strip along the edge to drag through all 28 years. A switch at the top of the list changes to the Japanese sets: 181 since October 1996, in the same rows.
A set opens as a page of its own: the logo, the release date, the printed cards and the secret ones, the three most valuable cards with their Cardmarket trend price, and then every card. A card opens large, with its number, rarity and price, and the arrows step through the set. The newest sets have no prices yet, so they show their rarest cards instead. Settings has the family’s theme and language switches; the interface is in English and German, while the set and card names stay English, since these are the English sets.
One small file for the list
The list is one file: every set with its date, its counts and its three top cards, 12 KB compressed. A set’s full card list is a file of its own, fetched when the set is opened. Both are built from pokemontcg.io, whose answers needed care: valid requests failed with a 500 at random and worked on the next try, the newest sets keep their images on a second host, and printed numbers repeat within a set (a Classic Collection has three cards printed “106”), so cards are keyed by their id instead.
The server builds the snapshot again once a day, so a new set appears without a deploy. The new files go into a fresh folder and replace the old ones only once every set has come through; a failed run keeps yesterday’s list and tries again an hour later.
The Japanese list comes from TCGdex, which has the sets, dates and cards but no logos, and its pictures from Scrydex’s image server. Scrydex’s ids for the Japanese sets aren’t public, so the server tries the spellings TCGdex’s id suggests (M3 becomes m3_ja, CS3.5 becomes cs3pt5_ja) until the first card comes back as a real picture. A wrong guess still answers with an image, Scrydex’s placeholder, so every download is compared with it. 111 of the 181 sets have pictures; the others show the code printed on their cards instead of a logo. Japanese sets have no prices here, so a set page leads with its highest-numbered cards, the secret rares first.
Images at the size they’re drawn
The originals are PNGs: a set logo is about 99 KB, a card about 167 KB. The page draws a logo 100 to 136 pixels wide and a card thumbnail at around 110. So the server fetches each original once, resizes it to a fixed width for the screen it’s drawn on, encodes it as WebP and keeps the result on disk: a logo becomes about 12 KB, a card 18 KB, the small card beside a row 7 KB. It only makes the widths the page asks for and only fetches from the two image hosts, so it can’t be used as a general resizer, and every image is served as immutable, which lets Cloudflare’s edge answer from then on.
Only what’s about to be seen
With the browser’s own lazy loading, the top of the page had already fetched 186 images, 85 of them more than 3,000 pixels down: how far ahead to look is each browser’s choice. TCGSL watches its images itself and starts each one about a screen before it scrolls into view, the same in every browser. An image a phone hides, like the second and third card of a row, never comes into view, so it’s never fetched there.
Every row is in the page from the start, but the years off screen skip layout and paint until they come close, each with a guess of its height, so the scrollbar stays honest and a jump to 2004 lands on 2004. Every image has its box reserved, and a card shows its dominant colour until it arrives and then fades in, so nothing moves while the images load.
Part of the family
The tokens and components come from Folio, the family’s shared library, so the settings sheet is the one the other apps use. The server sends a strict Content Security Policy and forwards the visit counter, Census, without cookies, and an offline worker keeps the last list available without a connection.
Jedes Set, das neueste zuerst
TCGSL listet jedes englische Pokémon-TCG-Set, vom Base Set im Januar 1999 bis zur neuesten Erweiterung: im Moment 176. Jede Zeile zeigt das Erscheinungsdatum, Logo und Symbol des Sets, seinen Namen, die Zahl seiner Karten und seine wertvollste Karte; auf einem breiteren Bildschirm fächern sich die drei wertvollsten auf. Die Zeilen sind nach Jahren gruppiert, eine Leiste daneben springt zu jedem Jahr, und auf dem Handy wird sie zu einem Streifen am Rand, über den man durch alle 28 Jahre fährt. Ein Schalter oben in der Liste wechselt zu den japanischen Sets: 181 seit Oktober 1996, in denselben Zeilen.
Ein Set öffnet sich als eigene Seite: das Logo, das Erscheinungsdatum, die gedruckten und die geheimen Karten, die drei wertvollsten Karten mit ihrem Cardmarket-Trendpreis und dann jede Karte. Eine Karte öffnet sich groß, mit Nummer, Seltenheit und Preis, und die Pfeile blättern durch das Set. Die neuesten Sets haben noch keine Preise, deshalb zeigen sie stattdessen ihre seltensten Karten. In den Einstellungen sitzen die Schalter für Design und Sprache wie in den anderen Apps; die Oberfläche gibt es auf Englisch und Deutsch, die Namen der Sets und Karten bleiben englisch, denn es sind die englischen Sets.
Eine kleine Datei für die Liste
Die Liste ist eine Datei: jedes Set mit seinem Datum, seinen Kartenzahlen und seinen drei besten Karten, komprimiert 12 KB. Die ganze Kartenliste eines Sets ist eine eigene Datei, geladen, wenn man das Set öffnet. Beide entstehen aus pokemontcg.io, und dessen Antworten brauchten Sorgfalt: Gültige Anfragen scheiterten zufällig mit einem 500 und klappten beim nächsten Versuch, die neuesten Sets haben ihre Bilder auf einem zweiten Server, und gedruckte Nummern wiederholen sich innerhalb eines Sets (eine Classic Collection hat drei Karten mit der Nummer „106“), deshalb sind Karten über ihre ID verschlüsselt.
Der Server baut den Datenstand einmal am Tag neu, so erscheint ein neues Set ohne Deploy. Die neuen Dateien entstehen in einem frischen Ordner und ersetzen die alten erst, wenn jedes Set durchgekommen ist; ein gescheiterter Lauf behält die Liste von gestern und versucht es eine Stunde später noch einmal.
Die japanische Liste kommt von TCGdex, das die Sets, Daten und Karten hat, aber keine Logos, und ihre Bilder vom Bildserver von Scrydex. Dessen IDs für die japanischen Sets sind nicht öffentlich, also probiert der Server die Schreibweisen, die die ID bei TCGdex nahelegt (aus M3 wird m3_ja, aus CS3.5 wird cs3pt5_ja), bis die erste Karte als echtes Bild zurückkommt. Auch ein falscher Versuch liefert ein Bild, den Platzhalter von Scrydex, deshalb wird jeder Download damit verglichen. 111 der 181 Sets haben Bilder; die anderen zeigen statt eines Logos den Code, der auf ihren Karten steht. Japanische Sets haben hier keine Preise, deshalb beginnt ihre Seite mit den Karten mit den höchsten Nummern, die Secret Rares zuerst.
Bilder in der Größe, in der sie gezeigt werden
Die Originale sind PNGs: Ein Set-Logo hat etwa 99 KB, eine Karte etwa 167 KB. Die Seite zeigt ein Logo 100 bis 136 Pixel breit und eine Karte als Vorschau mit etwa 110. Also holt der Server jedes Original einmal, verkleinert es auf eine feste Breite für den Bildschirm, auf dem es erscheint, speichert es als WebP und hebt das Ergebnis auf: Ein Logo wird zu etwa 12 KB, eine Karte zu 18 KB, die kleine Karte neben einer Zeile zu 7 KB. Er erzeugt nur die Breiten, die die Seite anfragt, und holt nur von den beiden Bildservern, kann also nicht als beliebiger Bildverkleinerer dienen, und jedes Bild geht als unveränderlich hinaus, sodass ab dann Cloudflares Edge antwortet.
Nur, was gleich zu sehen ist
Mit dem Lazy Loading des Browsers hatte der Anfang der Seite schon 186 Bilder geladen, 85 davon mehr als 3.000 Pixel weiter unten: Wie weit er vorausschaut, entscheidet jeder Browser selbst. TCGSL beobachtet seine Bilder selbst und lädt jedes etwa einen Bildschirm, bevor es ins Bild rollt, in jedem Browser gleich. Ein Bild, das ein Handy ausblendet, wie die zweite und dritte Karte einer Zeile, kommt nie ins Bild und wird dort also nie geladen.
Jede Zeile steht von Anfang an in der Seite, aber die Jahre außerhalb des Bildschirms überspringen Layout und Zeichnen, bis sie näher kommen, jedes mit einer Schätzung seiner Höhe, damit die Scrollleiste stimmt und ein Sprung zu 2004 auch bei 2004 landet. Jedes Bild hat seinen Platz reserviert, und eine Karte zeigt ihre vorherrschende Farbe, bis sie da ist, und blendet dann ein, sodass sich beim Laden nichts verschiebt.
Teil der Familie
Tokens und Komponenten kommen aus Folio, der gemeinsamen Bibliothek der Apps, deshalb ist das Einstellungsblatt dasselbe wie in den anderen Apps. Der Server schickt eine strenge Content Security Policy und leitet den Besuchszähler Census ohne Cookies weiter, und ein Offline-Worker hält die letzte Liste auch ohne Verbindung bereit.