✱presque.cool
← Back to projects
Kao-Z icon

Kao-Z

Jan 2026 App
Visit project ↗

A Japanese-inspired avatar generator. 3,598 elements to combine into a unique face and share it.


Le pitch

Kao-Z est un générateur d’avatars SVG personnalisables. On combine des éléments (visage, cheveux, yeux, accessoires…) avec des contrôles de position, zoom et couleurs, puis on exporte en PNG/SVG ou on partage via URL.

Essayer : presque.cool/kao-z/

Durée ~2 semaines
Période Jan 2026 → Oct 2026
Stack
Preact TypeScript Zustand PWA
Statut ✓ En production

Pourquoi ce projet

J’ai découvert icon-z.com par hasard sur les réseaux sociaux — un générateur d’avatars japonais créé par @topeconheroes avec des milliers d’éléments graphiques. La version originale est excellente, mais exclusivement en japonais.

Je me suis fixé un défi : rétro-ingénierie et adaptation en anglais. Les illustrations sont de @topeconheroes, réutilisées avec son accord, et il est crédité dans l’app.

Pas d’objectif d’apprentissage particulier cette fois. J’aime fabriquer des générateurs d’avatars, et je voulais me frotter à des assets graphiques différents de ceux dont j’avais l’habitude (Star Wars Avatar). C’était l’occasion de voir si je pouvais appliquer les leçons apprises sur les précédents générateurs.


Rétro-ingénierie d’un site japonais

icon-z.com n’est pas open source. Pour comprendre comment il fonctionnait, j’ai procédé par inspection : analyse du DOM pour comprendre la structure des couches SVG, interception des requêtes réseau pour identifier comment les assets étaient chargés, téléchargement des fichiers SVG catégorie par catégorie.

Le résultat : 3 598 fichiers SVG répartis en 12 catégories, un système de couleurs à 5 canaux (fill, border, tone, accent, secondary), et une logique de composition par superposition de couches.

Ce travail de rétro-ingénierie m’a donné une compréhension suffisante pour reconstruire l’expérience dans un contexte différent — interface FR/EN, stack React, et un système de partage par URL qui n’existait pas dans l’original.


Le défi technique : 3 598 fichiers SVG et un état à compresser

Le projet contient 3 598 fichiers SVG répartis en 12 catégories. Charger chaque fichier individuellement aurait créé des milliers de requêtes HTTP — une latence inacceptable.

La solution : bundling JSON

J’ai créé un système de bundles : un fichier JSON par catégorie contenant tous les SVG pré-chargés. Au lieu de milliers de requêtes, une seule par catégorie suffit.

Encodage URL compact

L’avatar complet (12 sélections + 5 couleurs + 4 paramètres de position) devait tenir dans une URL partageable. La première approche — sérialiser l’état en JSON puis l’encoder en Base64 — produisait des URLs d’environ 90 caractères. C’est fonctionnel, mais long.

J’ai opté pour un encodage binaire : chaque sélection est stockée sur 10 bits (supportant jusqu’à 1023 éléments par catégorie), les couleurs en 3 bytes RGB chacune, et la position en 3 bytes (X et Y en int8 signé, zoom + flag closeup dans le dernier byte). Le tout tient dans 34 bytes, encodés en Base64 URL-safe — soit environ 46 caractères. Moitié moins que la version JSON.

Autres défis :

  • Composition temps réel — 12 couches SVG superposées dans le bon ordre, avec le système de couleurs CSS à 5 canaux
  • Grille virtualisée — Des centaines d’éléments à afficher sans lag grâce à @tanstack/react-virtual

Stack technique

  • Preact + TypeScript — Composants fonctionnels, typage strict
  • Vite + SWC — Build rapide avec Hot Module Replacement
  • Tailwind CSS — Configuration CSS-first, classes utilitaires
  • Zustand — State management avec persistence localStorage
  • @tanstack/react-virtual — Virtualisation de grilles larges
  • PWA — installable, offline
  • i18n maison — Français/anglais sans dépendance externe
  • CSP — Content-Security-Policy avec hashes auto-générés

Évolutions

Date Version Description
Jan 2026 1.0 Version initiale — Adaptation de icon-z.com avec interface FR/EN
Oct 2026 1.10 Le premier chargement tombe de 94 Ko à 39 Ko de JavaScript avec Preact à la place de React. Le sélecteur de couleur personnalisée recolore le visage en direct.

Bilan

Ce que j’ai appris :

  • Que j’apprécie vraiment travailler avec des assets créés par des designers/illustrateurs. C’est différent de tout faire soi-même — on se concentre sur l’expérience utilisateur plutôt que sur la création graphique.
  • L’encodage binaire pour les URLs de partage — penser en bits plutôt qu’en chaînes de caractères change la façon d’aborder la sérialisation.

Ce que je referais pareil :

  • Le système de bundles JSON — c’est la clé pour gérer des milliers d’assets sans sacrifier les performances
  • L’encodage URL binaire — les URLs restent courtes même avec beaucoup de paramètres

Ce que je changerais :

  • Ajouter une version traduite en japonais, en hommage à la version originale.
  • L’expérience accumulée sur Star Wars Avatar a rendu Kao-Z plus fluide : moins de tâtonnement sur l’UI, meilleure séparation des responsabilités dès le départ. Mais l’inverse aurait aussi été vrai — la rétro-ingénierie et la gestion de centaines de SVG auraient été utiles en amont.

The pitch

Kao-Z is a customizable SVG avatar generator. Combine elements (face, hair, eyes, accessories…) with position, zoom, and color controls, then export to PNG/SVG or share via URL.

Try it: presque.cool/kao-z/

Duration ~2 weeks
Period Jan 2026 → Oct 2026
Stack
Preact TypeScript Zustand PWA
Status ✓ In production

Why this project

I discovered icon-z.com randomly on social media — a Japanese avatar generator created by @topeconheroes with thousands of graphic elements. The original version is excellent, but exclusively in Japanese.

I set myself a challenge: reverse engineering and English adaptation. The artwork is by @topeconheroes, reused with their permission, and they are credited in the app.

No particular learning objective this time. I enjoy building avatar generators, and I wanted to work with graphic assets different from what I was used to (Star Wars Avatar). It was an opportunity to see if I could apply the lessons learned from previous generators.


Reverse engineering a Japanese site

icon-z.com isn’t open source. To understand how it worked, I proceeded by inspection: analyzing the DOM to understand the SVG layer structure, intercepting network requests to identify how assets were loaded, downloading SVG files category by category.

The result: 3,598 SVG files across 12 categories, a 5-channel color system (fill, border, tone, accent, secondary), and a composition logic based on layer superposition.

This reverse engineering work gave me enough understanding to rebuild the experience in a different context — FR/EN interface, React stack, and a URL sharing system that didn’t exist in the original.


The technical challenge: 3,598 SVG files and a state to compress

The project contains 3,598 SVG files spread across 12 categories. Loading each file individually would have created thousands of HTTP requests — unacceptable latency.

The solution: JSON bundling

I created a bundle system: one JSON file per category containing all pre-loaded SVGs. Instead of thousands of requests, just one per category is needed.

Compact URL encoding

The complete avatar (12 selections + 5 colors + 4 position parameters) had to fit in a shareable URL. The first approach — serializing state as JSON then encoding in Base64 — produced URLs of about 90 characters. Functional, but long.

I opted for binary encoding: each selection is stored in 10 bits (supporting up to 1023 elements per category), colors in 3 bytes RGB each, and position in 3 bytes (X and Y as signed int8, zoom + closeup flag in the last byte). Everything fits in 34 bytes, encoded in URL-safe Base64 — about 46 characters. Half the size of the JSON version.

Other challenges:

  • Real-time composition — 12 SVG layers superimposed in the correct order, with the 5-channel CSS color system
  • Virtualized grid — Hundreds of elements to display without lag thanks to @tanstack/react-virtual

Tech stack

  • Preact + TypeScript — Functional components, strict typing
  • Vite + SWC — Fast builds with Hot Module Replacement
  • Tailwind CSS — CSS-first configuration, utility classes
  • Zustand — State management with localStorage persistence
  • @tanstack/react-virtual — Large grid virtualization
  • PWA — installable, offline
  • i18n custom — French/English without external dependency
  • CSP — Content-Security-Policy with auto-generated hashes

Timeline

Date Version Description
Jan 2026 1.0 Initial version — Adaptation of icon-z.com with FR/EN interface
Oct 2026 1.10 First load falls from 94 KB to 39 KB of JavaScript with Preact in place of React. The custom color picker recolors the face live.

Takeaways

What I learned:

  • That I really enjoy working with assets created by designers/illustrators. It’s different from doing everything yourself — you focus on user experience rather than graphic creation.
  • Binary encoding for share URLs — thinking in bits rather than strings changes how you approach serialization.

What I’d do the same:

  • The JSON bundle system — it’s the key to managing thousands of assets without sacrificing performance
  • Binary URL encoding — URLs stay short even with many parameters

What I’d change:

  • Add a Japanese translation, as a tribute to the original version.
  • The experience accumulated on Star Wars Avatar made Kao-Z smoother: less trial and error on the UI, better separation of concerns from the start. But the reverse would also have been true — the reverse engineering and management of hundreds of SVGs would have been useful upstream.