---
title: Kao-Z
canonical: "https://presque.cool/projects/kao-z/"
description: "Un générateur d'avatar d'inspiration japonaise. 828 éléments à combiner pour créer un visage unique et le partager."
---

<div data-lang="fr">

## 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/](https://presque.cool/kao-z/)

<div class="quick-overview">
  <div class="overview-item">
    <span class="overview-label">Durée</span>
    <span class="overview-value">~2 semaines</span>
  </div>
  <div class="overview-item">
    <span class="overview-label">Période</span>
    <span class="overview-value">Jan 2026</span>
  </div>
  <div class="overview-item">
    <span class="overview-label">Stack</span>
    <div class="tech-tags">
      <span class="tech-tag">React</span>
      <span class="tech-tag">TypeScript</span>
      <span class="tech-tag">Zustand</span>
      <span class="tech-tag">PWA</span>
    </div>
  </div>
  <div class="overview-item">
    <span class="overview-label">Statut</span>
    <span class="overview-value accent">✓ En production</span>
  </div>
</div>

---

## Pourquoi ce projet

J'ai découvert [icon-z.com](https://icon-z.com) par hasard sur les réseaux sociaux — un générateur d'avatars japonais créé par @topeconheroes avec des centaines 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.

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](/projects/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 : 828 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 : 828 fichiers SVG et un état à compresser

Le projet contient environ 828 fichiers SVG répartis en 12 catégories. Charger chaque fichier individuellement aurait créé des centaines 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 centaines 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

<ul class="tech-stack">
  <li><strong>React</strong> + <strong>TypeScript</strong> — Composants fonctionnels, typage strict</li>
  <li><strong>Vite</strong> + <strong>SWC</strong> — Build rapide avec Hot Module Replacement</li>
  <li><strong>Tailwind CSS</strong> — Configuration CSS-first, classes utilitaires</li>
  <li><strong>Zustand</strong> — State management avec persistence localStorage</li>
  <li><strong>@tanstack/react-virtual</strong> — Virtualisation de grilles larges</li>
  <li><strong>PWA</strong> — installable, offline</li>
  <li><strong>i18n</strong> maison — Français/anglais sans dépendance externe</li>
<li><strong>Compression</strong> — Brotli + Gzip sur les assets</li>
<li><strong>CSP</strong> — Content-Security-Policy avec hashes auto-générés</li>
</ul>

---

## Évolutions

| Date     | Version | Description                                                      |
| -------- | ------- | ---------------------------------------------------------------- |
| Jan 2026 | 1.0     | Version initiale — Adaptation de icon-z.com avec interface FR/EN |

---

## 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 centaines 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](/projects/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.

</div>

<div data-lang="en">

## 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/](https://presque.cool/kao-z/)

<div class="quick-overview">
  <div class="overview-item">
    <span class="overview-label">Duration</span>
    <span class="overview-value">~2 weeks</span>
  </div>
  <div class="overview-item">
    <span class="overview-label">Period</span>
    <span class="overview-value">Jan 2026</span>
  </div>
  <div class="overview-item">
    <span class="overview-label">Stack</span>
    <div class="tech-tags">
      <span class="tech-tag">React</span>
      <span class="tech-tag">TypeScript</span>
      <span class="tech-tag">Zustand</span>
      <span class="tech-tag">PWA</span>
    </div>
  </div>
  <div class="overview-item">
    <span class="overview-label">Status</span>
    <span class="overview-value accent">✓ In production</span>
  </div>
</div>

---

## Why this project

I discovered [icon-z.com](https://icon-z.com) randomly on social media — a Japanese avatar generator created by @topeconheroes with hundreds of graphic elements. The original version is excellent, but exclusively in Japanese.

I set myself a challenge: reverse engineering and English adaptation.

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](/projects/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: 828 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: 828 SVG files and a state to compress

The project contains about 828 SVG files spread across 12 categories. Loading each file individually would have created hundreds 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 hundreds 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

<ul class="tech-stack">
  <li><strong>React</strong> + <strong>TypeScript</strong> — Functional components, strict typing</li>
  <li><strong>Vite</strong> + <strong>SWC</strong> — Fast builds with Hot Module Replacement</li>
  <li><strong>Tailwind CSS</strong> — CSS-first configuration, utility classes</li>
  <li><strong>Zustand</strong> — State management with localStorage persistence</li>
  <li><strong>@tanstack/react-virtual</strong> — Large grid virtualization</li>
  <li><strong>PWA</strong> — installable, offline</li>
  <li><strong>i18n</strong> custom — French/English without external dependency</li>
<li><strong>Compression</strong> — Brotli + Gzip on assets</li>
<li><strong>CSP</strong> — Content-Security-Policy with auto-generated hashes</li>
</ul>

---

## Timeline

| Date     | Version | Description                                                     |
| -------- | ------- | --------------------------------------------------------------- |
| Jan 2026 | 1.0     | Initial version — Adaptation of icon-z.com with FR/EN interface |

---

## 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 hundreds 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](/projects/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.

</div>
