Le pitch
Marvel Archive est un catalogue de comics Marvel couvrant plus de 60 ans de publication (1965-2025). Plus de 40 000 single issues, navigables par année, série ou créateur, avec recherche plein texte. Le tout statique, offline, et construit sur les données d’une API aujourd’hui fermée.
Consulter : presque.cool/marvel-archive/
Pourquoi ce projet
En février 2022, j’ai voulu expérimenter avec l’API Marvel Developer — une API REST officielle qui donnait accès au catalogue complet des comics Marvel. L’idée : construire un site de consultation élégant autour de cette base de données massive.
Le projet est pragmatique : seuls les single issues apparaissent. Pas de TPB, pas d’omnibus, pas de rééditions. L’objectif était de cartographier le catalogue de publication original, numéro par numéro.
La mort de l’API
Le 29 octobre 2025, Marvel a fermé son API Developer. Du jour au lendemain, le site a cessé de fonctionner.
En février 2026, j’ai reconstruit Marvel Archive autour d’une version locale des données — un cache JSON organisé par année, récupéré avant la fermeture. Ce qui était un projet d’expérimentation API est devenu un véritable travail d’archivage : les données ne changeront plus, mais elles restent accessibles.
L’API disparue a donné au projet une raison d’être qu’il n’avait pas au départ. Il ne consomme plus un service, il en conserve la trace.
L’architecture : 51 000 pages statiques
Le site génère environ 51 000 pages HTML à la compilation. Chaque issue, chaque série, chaque créateur, chaque année, chaque page de pagination a sa propre URL statique. Le build pèse environ 1 Go et nécessite 8 Go de RAM (--max-old-space-size=8192) pour traiter ce volume.
Le pipeline de données :
JSON par année (1965.json ... 2025.json)
→ Content Collections Astro (typage strict)
→ Index en mémoire (Map par série, créateur, année)
→ getStaticPaths() génère toutes les routes
→ 51 000 pages HTML statiques
Les index sont construits une seule fois au build et mis en cache : Map<seriesId, Issue[]>, Map<creatorId, Issue[]>, Map<year, Issue[]>. Chaque lookup est O(1).
L’optimisation
Avec 51 000 pages et 40 000+ issues, l’optimisation n’est pas un luxe — c’est une contrainte structurelle. Le site doit être rapide à construire et à consulter.
Au build :
- 8 Go de RAM alloués via
--max-old-space-size=8192— sans ça, Node.js plante avant d’avoir fini - Index pré-calculés en un seul passage — les
Mappar série, créateur et année sont construites une fois au démarrage et réutilisées pour toutes les routes. Pas de re-parcours des données à chaque page - Projection minimale — chaque issue est réduite à un résumé (titre, date, couverture, IDs) avant d’entrer dans le système de routes, limitant l’empreinte mémoire
- Content Collections avec loaders inline — les fichiers JSON par année sont fusionnés en une seule collection typée, évitant la duplication de parsing
Au runtime :
- Preact (~3 Ko) au lieu de React (~40 Ko) pour le seul composant interactif, hydraté en
client:idle - Pagefind — recherche plein texte entièrement côté client, sans serveur ni API. L’index est généré après le build et chargé à la demande
- Cache Workbox — images en cache 30 jours, fonts 1 an. Les pages visitées sont disponibles offline via le Service Worker
- Lazy loading des couvertures avec animation shimmer pendant le chargement
- Script anti-flash inline — le thème est appliqué avant le premier paint, zéro flash blanc
- Prefetch automatique — Astro précharge les liens visibles, rendant la navigation quasi instantanée
- Zéro compute serveur — tout est statique, servi depuis un simple hébergement de fichiers
La navigation par année
L’entrée principale du site est une grille d’années (1965-2025). Cliquer sur une année affiche tous les numéros publiés cette année-là, paginés. C’est un mode de consultation qui invite à la sérendipité — on tombe sur des couvertures oubliées, des séries méconnues, des curiosités éditoriales.
Quatre chemins de navigation coexistent :
- Par année — exploration chronologique
- Par série — filtrage par titre
- Par créateur — bibliographie complète d’un auteur ou dessinateur
- Recherche plein texte — via Pagefind, un moteur de recherche statique recommandé par Astro, qui indexe les pages après le build sans serveur ni API
Le choix Preact
Le site est construit avec Astro — zéro JavaScript par défaut, rendu statique. Mais la modale de paramètres (thème, langue) nécessite de l’interactivité côté client.
Utiliser React (~40 Ko) pour une seule modale était disproportionné. Preact (~3 Ko), avec une API quasi identique, était le bon compromis : même modèle de composants, fraction du poids. Le composant est chargé en client:idle — il n’est hydraté qu’une fois la page au repos.
Le design Marvel
L’identité visuelle s’inspire directement de la charte officielle de Marvel.com :
- Rouge Marvel (
#ec1d25) comme couleur d’accent - Dark-first — fond sombre avec texte clair, mode light disponible
- Couvertures en ratio 2:3 avec animation shimmer au chargement
- Script anti-flash — un snippet inline qui applique le thème avant le premier paint, évitant le flash blanc
Stack technique
- Astro — Génération statique, Content Collections, prefetch automatique
- Preact — Composant interactif (modale settings), chargé en
client:idle - Tailwind CSS — Variables CSS custom, dark/light mode
- Pagefind — Recherche plein texte statique, indexation post-build
- PWA via
@vite-pwa/astro— Offline, cache Workbox (images 30j, fonts 1 an) - i18n maison — Français/anglais, détection navigateur
- CSP — Content-Security-Policy avec hashes auto-générés
Évolutions
| Date | Version | Description |
|---|---|---|
| Fév 2022 | 1.0 | Version initiale — Consultation via API Marvel Developer |
| Oct 2025 | — | Fermeture de l’API Marvel — le site cesse de fonctionner |
| Fév 2026 | 2.0 | Refonte complète — Données locales, Astro, Preact, Pagefind, PWA |
Bilan
Durée : 1 semaine (février 2022, refondu en février 2026).
Ce que j’ai appris :
- Que la génération statique peut absorber des volumes de données massifs — 51 000 pages, à condition de pré-indexer et de gérer la mémoire
- Que la fermeture d’une API peut transformer un projet d’expérimentation en projet d’archivage avec une raison d’être plus forte
Ce que je referais pareil :
- L’approche pragmatique — ne montrer que les single issues donne une cohérence éditoriale au catalogue
- Preact plutôt que React pour un besoin d’interactivité minimal — le gain de poids est significatif
Ce que je changerais :
- Ajouter des filtres visuels plus poussés (par genre, par décennie, par popularité)
- Explorer une timeline visuelle interactive pour naviguer dans les 60 ans de publication
The pitch
Marvel Archive is a Marvel comics catalog spanning over 60 years of publication (1965-2025). Over 40,000 single issues, browsable by year, series, or creator, with full-text search. Fully static, offline-capable, and built on data from a now-defunct API.
Browse: presque.cool/marvel-archive/
Why this project
In February 2022, I wanted to experiment with the Marvel Developer API — an official REST API that provided access to the full Marvel comics catalog. The idea: build an elegant browsing site around this massive database.
The project is pragmatic: only single issues are shown. No TPBs, no omnibuses, no reprints. The goal was to map the original publication catalog, issue by issue.
The death of the API
On October 29, 2025, Marvel shut down its Developer API. Overnight, the site stopped working.
In February 2026, I rebuilt Marvel Archive around a local version of the data — a JSON cache organized by year, retrieved before the shutdown. What started as an API experiment became a genuine archival project: the data won’t change anymore, but it remains accessible.
The defunct API gave the project a purpose it didn’t have at the start. It no longer consumes a service, it keeps a record of one.
The architecture: 51,000 static pages
The site generates approximately 51,000 HTML pages at build time. Every issue, series, creator, year, and pagination page has its own static URL. The build weighs about 1 GB and requires 8 GB of RAM (--max-old-space-size=8192) to handle this volume.
The data pipeline:
JSON per year (1965.json ... 2025.json)
→ Astro Content Collections (strict typing)
→ In-memory index (Map by series, creator, year)
→ getStaticPaths() generates all routes
→ 51,000 static HTML pages
Indexes are built once during the build and cached: Map<seriesId, Issue[]>, Map<creatorId, Issue[]>, Map<year, Issue[]>. Every lookup is O(1).
Optimization
With 51,000 pages and 40,000+ issues, optimization isn’t a luxury — it’s a structural constraint. The site needs to be fast to build and to browse.
Build time:
- 8 GB of RAM allocated via
--max-old-space-size=8192— without it, Node.js crashes before finishing - Pre-computed indexes in a single pass — the
Mapstructures for series, creators, and years are built once at startup and reused across all routes. No re-traversal per page - Minimal projection — each issue is reduced to a summary (title, date, cover, IDs) before entering the routing system, limiting memory footprint
- Content Collections with inline loaders — yearly JSON files are merged into a single typed collection, avoiding redundant parsing
Runtime:
- Preact (~3 KB) instead of React (~40 KB) for the only interactive component, hydrated with
client:idle - Pagefind — fully client-side full-text search, no server or API. The index is generated after build and loaded on demand
- Workbox caching — images cached for 30 days, fonts for 1 year. Visited pages are available offline via Service Worker
- Lazy loading covers with shimmer animation during load
- Anti-flash script inline — theme is applied before first paint, zero white flash
- Automatic prefetch — Astro preloads visible links, making navigation near-instant
- Zero server compute — everything is static, served from simple file hosting
Year-by-year navigation
The site’s main entry point is a year grid (1965-2025). Clicking a year shows all issues published that year, paginated. It’s a browsing mode that invites serendipity — you stumble upon forgotten covers, obscure series, editorial curiosities.
Four navigation paths coexist:
- By year — chronological exploration
- By series — filter by title
- By creator — an author’s or artist’s full bibliography
- Full-text search — via Pagefind, a static search engine recommended by Astro, which indexes pages after build with no server or API
The Preact choice
The site is built with Astro — zero JavaScript by default, static rendering. But the settings modal (theme, language) requires client-side interactivity.
Using React (~40 KB) for a single modal was overkill. Preact (~3 KB), with a near-identical API, was the right trade-off: same component model, fraction of the weight. The component is loaded with client:idle — it’s only hydrated once the page is idle.
The Marvel design
The visual identity draws directly from the official Marvel.com brand guidelines:
- Marvel red (
#ec1d25) as the accent color - Dark-first — dark background with light text, light mode available
- Cover images in 2:3 ratio with shimmer loading animation
- Anti-flash script — an inline snippet that applies the theme before first paint, preventing white flash
Tech stack
- Astro — Static generation, Content Collections, automatic prefetch
- Preact — Interactive component (settings modal), loaded with
client:idle - Tailwind CSS — Custom CSS variables, dark/light mode
- Pagefind — Static full-text search, post-build indexing
- PWA via
@vite-pwa/astro— Offline, Workbox caching (images 30d, fonts 1y) - i18n custom — French/English, browser detection
- CSP — Content-Security-Policy with auto-generated hashes
Timeline
| Date | Version | Description |
|---|---|---|
| Feb 2022 | 1.0 | Initial version — Browsing via Marvel Developer API |
| Oct 2025 | — | Marvel API shutdown — site stops working |
| Feb 2026 | 2.0 | Full rewrite — Local data, Astro, Preact, Pagefind, PWA |
Takeaways
Duration: 1 week (February 2022, rewritten February 2026).
What I learned:
- That static generation can absorb massive data volumes — 51,000 pages, provided you pre-index and manage memory
- That an API shutdown can transform an experiment into an archival project with a stronger purpose
What I’d do the same:
- The pragmatic approach — showing only single issues gives the catalog editorial coherence
- Preact over React for minimal interactivity needs — the weight savings are significant
What I’d change:
- Add more advanced visual filters (by genre, decade, popularity)
- Explore an interactive visual timeline to navigate 60 years of publication