- TypeScript 77.9%
- CSS 13.8%
- Shell 4.5%
- Makefile 2.4%
- Dockerfile 0.9%
- Andere 0.5%
- Add a "Skin tone" tab to the detail panel of the 330 emoji that support skin tones; emoji showing two people take a tone per person - The choice applies to the whole grid and to symbol, code points, UTF-8 bytes, description and all exports, and is kept in the URL - Generate Noto Emoji graphics for all 2,030 variants - Remember the selected panel tab by name, as the tabs differ between sources Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| .devcontainer | ||
| data | ||
| public | ||
| scripts | ||
| src | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| Caddyfile | ||
| compose.yaml | ||
| Dockerfile | ||
| index.html | ||
| LICENSE | ||
| Makefile | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| tsconfig.json | ||
| vite.config.ts | ||
Icon Atlas
Eine durchsuchbare Übersicht freier Open-Source-Icons aus mehreren Icon-Sets. Die Seite ist rein statisch, kommt ohne Analytics und Cookies aus und lädt nichts von Dritten nach.
Enthaltene Icons
| Quelle | Icons | Lizenz | Herkunft |
|---|---|---|---|
| Phosphor Icons | 1.512 | MIT | @phosphor-icons/core |
| Material Symbols | 3.929 | Apache 2.0 | google/material-design-icons (s. u.) |
| Emoji | 1.923 | Unicode License (Daten: MIT) | Unicode-Zeichen, Daten aus emojibase-data |
Es werden ausschließlich Icons aufgenommen, deren Lizenz die freie – auch kommerzielle – Nutzung erlaubt. Marken- und Logo-Icons sind als Grafik frei lizenziert, die Marken selbst gehören weiterhin ihren Inhabern.
Funktionen
- Suche über Namen, Tags und Kategorien beider Quellen (Fuse.js), Treffer im Namen stehen vorne
- Quelle: alle, nur Phosphor, nur Material oder nur Emoji
- Gewicht: Thin, Light, Regular, Bold, Fill, Duotone
- Material-Stil: Outlined, Rounded, Sharp
- Hautton für Emoji, im Detail-Panel
- Größe (16–400 px) und Farbe, Zufalls- und Reset-Button. Die Größe gilt für Downloads, Kopien und Snippets; im Raster werden Icons höchstens mit 96 px angezeigt
- Alle Einstellungen stehen in der URL (
?q=…&source=…&weight=…&style=…&size=…&color=…) und lassen sich als Link teilen - Detail-Panel mit SVG-/PNG-Download, Kopieren und Code-Snippets
Datenschutz
Besucher lösen keine Anfragen an Dritte aus: Schriften und Icon-Daten werden
von der Seite selbst ausgeliefert, der Produktions-Build setzt eine
Content-Security-Policy, die fremde Ziele blockiert, und Links nach außen
senden keinen Referrer. Gespeichert wird nur im sessionStorage (zuletzt
gewählter Tab im Detail-Panel).
Emoji
Emoji sind Unicode-Zeichen und werden mit der Emoji-Schrift des jeweiligen Geräts dargestellt; die Seite liefert selbst keine Emoji-Schrift aus. Sie sehen deshalb je nach Betriebssystem unterschiedlich aus, und Gewicht, Farbe und Material-Stil wirken auf sie nicht, nur die Größe.
Das Detail-Panel zeigt zu jedem Emoji das Symbol, die Beschreibung (Unicode-
Kurzname), die Codepoints (U+1F600) und die UTF-8-Bytes (F0 9F 98 80).
Alle vier lassen sich einzeln kopieren, dazu Schreibweisen für HTML, CSS und
JavaScript. Die Suche findet Emoji über Beschreibung, Schlagworte, Gruppe oder
das eingefügte Zeichen selbst.
Über den Pfeil „More actions“ im Detail-Panel lassen sich Emoji als Bild speichern (zweite Seite) oder in die Zwischenablage kopieren (dritte Seite), jeweils in der eingestellten Größe. Es gibt zwei Varianten:
| Aktion | Grafik stammt von | Lizenz |
|---|---|---|
| Noto PNG / Noto SVG | Noto Emoji, wird mit der Seite ausgeliefert | Apache 2.0, frei nutzbar |
| Device PNG | Emoji-Schrift des Geräts, im Browser gezeichnet | Sache des Schrift-Herstellers; bei Apple und Microsoft nicht frei |
Der Tab „Noto“ zeigt die Noto-Grafik zur Vorschau. Die meisten Grafiken
stammen aus dem Paket @iconify-json/noto. Die dort fehlenden 285 (Flaggen,
Ziffern-Tasten und einige weitere) liegen unter data/noto-emoji/ und kommen
direkt aus dem Noto-Emoji-Repository; pnpm sync-noto lädt sie neu. Die
Flaggen sind laut Repository gemeinfrei bzw. nicht urheberrechtlich geschützt.
Unabhängig davon kann die Verwendung von Hoheitszeichen je nach Land
eingeschränkt sein.
Hauttöne
330 Emoji gibt es in fünf Hauttönen (2.030 Varianten). Bei diesen Emoji zeigt
das Detail-Panel einen Tab „Skin tone“ mit Farbpunkten; bei Emoji mit zwei
Personen (🤝, 💏, …) lässt sich jede Person einzeln einfärben. Die Wahl gilt
für alle Emoji im Raster, steht in der URL (?tone=3&tone2=5) und bestimmt
Symbol, Unicode, UTF-8-Bytes, Beschreibung und alle Exporte. Die Varianten
erscheinen nicht als eigene Suchtreffer.
Zuordnung der Gewichte
Material Symbols kennt andere Achsen als Phosphor. Die Gewichte werden so abgebildet:
| Einstellung | Phosphor | Material Symbols |
|---|---|---|
| Thin | thin |
Strichstärke 100 |
| Light | light |
Strichstärke 300 |
| Regular | regular |
Strichstärke 400 |
| Bold | bold |
Strichstärke 700 |
| Fill | fill |
Strichstärke 400, gefüllt |
| Duotone | duotone |
Kontur 400 über der Füllung mit 20 % Deckkraft |
Duotone gibt es bei Material Symbols im Original nicht. Die Variante wird hier aus Kontur und Füllung zusammengesetzt, deshalb gibt es dafür keine Code-Snippets.
Entwicklung
Am einfachsten im mitgelieferten Devcontainer (.devcontainer/): Ordner in
VS Code öffnen und „Reopen in Container“ wählen. Abhängigkeiten und Icon-Daten
werden beim Erstellen eingerichtet, die Ports 5173 (dev) und 4173 (preview)
weitergeleitet.
Ohne Container: Node.js ≥ 22 und pnpm.
pnpm install
pnpm dev # Entwicklungsserver (im Container: pnpm dev --host)
pnpm build # Produktions-Build nach dist/
pnpm preview # Build lokal ansehen
dist/ ist eine rein statische Seite (ca. 105 MB, davon ca. 90 MB Icon-Daten,
die nur bei Bedarf geladen werden) und kann von jedem Webserver ausgeliefert
werden. Für die URL-Parameter ist kein Rewrite nötig.
Betrieb mit Docker
Zum Bauen und Ausliefern genügt Docker mit dem Compose-Plugin (oder Podman); Node.js wird auf dem Host nicht gebraucht.
make up # Image bauen und starten: http://localhost:8080
make logs # Logs verfolgen
make down # stoppen und entfernen
make help # alle Ziele anzeigen
Das Image baut die Seite in einer Node-Stufe und liefert dist/ anschließend
mit Caddy aus (Dockerfile, Caddyfile,
compose.yaml). Der Container spricht nur HTTP auf Port 8080 und ist für den
Betrieb hinter einem Reverse Proxy gedacht, der TLS übernimmt. Besucherzugriffe
werden nicht protokolliert.
Der Container läuft als unprivilegierter Benutzer mit schreibgeschütztem
Dateisystem, ohne Linux-Capabilities und mit Prozesslimit (compose.yaml).
Ein Speicherlimit ist nicht gesetzt, weil rootless Podman auf Raspberry Pi OS
das ohne aktivierten Memory-Cgroup (cgroup_enable=memory in
/boot/firmware/cmdline.txt) nicht erlaubt. Caddy setzt zusätzlich Sicherheits-Header wie
X-Frame-Options und Permissions-Policy (Caddyfile).
Standardmäßig ist der Port nur an 127.0.0.1 gebunden. Anpassen über
Variablen:
PORT=3000 make up # anderer Port
BIND=0.0.0.0 make up # im LAN erreichbar
Podman statt Docker
Ist kein docker installiert, nimmt das Makefile automatisch podman
(erzwingen mit make up DOCKER=podman). podman compose braucht zusätzlich
einen Compose-Provider, z. B. brew install podman-compose, und unter macOS
eine laufende Podman-Maschine (podman machine init && podman machine start).
Autostart mit rootless Podman (systemd)
Auf einem Linux-Server richtet scripts/install-autostart.sh eine systemd-
User-Unit ein, die den Container nach jedem Neustart des Hosts startet –
ohne Root-Rechte und ohne aktive Login-Session (Lingering).
make autostart # Unit installieren, aktivieren und starten
make autostart-print # nur die erzeugte Unit anzeigen
make autostart-remove # deaktivieren und entfernen
systemctl --user status icon-atlas.service
Port, Adresse und Image stehen entweder in einer .env neben compose.yaml
(Vorlage: .env.example) oder werden beim Installieren mitgegeben und dann
fest in die Unit geschrieben:
PORT=3000 BIND=0.0.0.0 make autostart
IMAGE=icon-atlas:latest-arm64 make autostart # vorgeladenes Image, kein Build auf dem Gerät
Das Skript baut das Image beim Installieren im Vordergrund und prüft, dass es
vorhanden ist; die Unit selbst startet nur noch (up -d --no-build) und
schlägt fehl, wenn der Container danach nicht läuft. Nach Änderungen am
Projekt deshalb make autostart erneut ausführen. IMAGE muss für den
Autostart beim Installieren gesetzt sein, ein Eintrag nur in .env genügt
dafür nicht.
Schlägt das Aktivieren von Lingering fehl, einmalig als root
loginctl enable-linger <user> ausführen und das Skript erneut starten.
Images für andere Architekturen
Die Seite besteht nur aus statischen Dateien. Der Build läuft deshalb immer
nativ auf dem Rechner, der baut; nur die Caddy-Stufe ist architekturabhängig.
Cross-Builds brauchen docker buildx, aber keine Emulation (QEMU).
| Ziel | Plattform | Geräte |
|---|---|---|
make image-amd64 |
linux/amd64 |
x86-64-PCs und -Server |
make image-arm64 |
linux/arm64 |
MacBooks mit M-Prozessor, Raspberry Pi 3/4/5 mit 64-Bit-OS |
make image-armv7 |
linux/arm/v7 |
Raspberry Pi 2/3/4 mit 32-Bit-OS |
make image-all |
alle drei |
Die Images heißen icon-atlas:latest-<arch>. Ohne Registry lassen sie sich
als Datei auf das Zielgerät bringen:
make save-arm64 # schreibt images/icon-atlas-latest-arm64.tar.gz
scp images/icon-atlas-latest-arm64.tar.gz compose.yaml pi:icon-atlas/
# auf dem Zielgerät, im Ordner icon-atlas/
gunzip -c icon-atlas-latest-arm64.tar.gz | docker load
IMAGE=icon-atlas:latest-arm64 docker compose up --detach --no-build
Mit Registry baut make push REGISTRY=registry.example.org/user ein einziges
Multi-Arch-Image für alle drei Plattformen und lädt es hoch; jedes Gerät zieht
sich dann automatisch die passende Variante.
Woher die Material-Daten kommen
Das Google-Repository ist mehrere Gigabyte groß. Statt es zu klonen, nutzt das
Projekt die npm-Pakete @material-symbols/svg-{100,300,400,700}, die aus genau
diesem Repository gebaut werden (Apache 2.0).
-
pnpm generate(läuft automatisch vordevundbuild) liest die SVGs und schreibt-
src/lib/material.generated.json– Suchindex (Name, Codepoint, Kategorien, Tags) -
public/data/material/<stil>/<variante>/<n>.json– SVG-Pfade in Blöcken zu je 400 Icons, die der Browser erst lädt, wenn sie gebraucht werden -
src/lib/emoji.generated.json– Emoji mit Beschreibung, Gruppe und Schlagworten ausemojibase-data -
public/data/noto/<codepoints>.svg– Noto-Emoji-Grafiken aus@iconify-json/notounddata/noto-emoji/, die erst beim Öffnen eines Emoji geladen werden
Alles davon ist generiert und steht in
.gitignore. -
-
data/material-symbols-metadata.jsonenthält Kategorien und Tags. Die Datei ist ein eingecheckter Schnappschuss der Google-Fonts-Metadaten, damit der Build ohne Netzwerk reproduzierbar ist.
Icons aktualisieren
pnpm update @phosphor-icons/core @phosphor-icons/react
pnpm update "@material-symbols/*" --latest
pnpm update emojibase-data @iconify-json/noto --latest
pnpm sync-metadata # Schnappschuss der Tags/Kategorien erneuern
pnpm sync-noto # fehlende Noto-Grafiken neu laden (Revision im Skript)
pnpm generate
Icons, die nicht in allen Varianten vorhanden sind, überspringt der Generator mit einem Hinweis.
Aufbau
scripts/generate.ts Material-Daten erzeugen
scripts/sync-metadata.ts Metadaten-Schnappschuss aktualisieren
src/lib/ Icon-Datenbank (beide Quellen), Material-Pfad-Loader
src/state/ Zustand-Store, Suche, URL-Parameter
src/components/ Toolbar, Grid, Detail-Panel, Header
Der Seitenname steht in src/lib/types.ts (SITE_NAME) sowie in index.html
und public/manifest.json.
Eine weitere Icon-Quelle hinzufügen
- Lizenz prüfen – nur frei nutzbare Icons aufnehmen und den Lizenztext unter
public/licenses/ablegen. IconSourceundsourcesinsrc/lib/types.tserweitern.- Einträge in
src/lib/icons.tsergänzen und das Rendering insrc/components/IconView/anbinden. - Snippets in
src/utils/index.tsund die Auswahl insrc/components/SourceInput/ergänzen.
Lizenz
Der Code steht unter der MIT-Lizenz. Er ist ein Fork der
Phosphor-Homepage; deren
Copyright-Vermerk muss in LICENSE erhalten bleiben. Die Icons behalten ihre
jeweilige Lizenz. Dieses Projekt steht in keiner Verbindung zu den Urhebern
der Icon-Sets.
Was mit der Seite ausgeliefert wird (public/licenses/):
| Datei | Inhalt |
|---|---|
NOTICE.txt |
Quellen, Copyright-Vermerke, Änderungshinweis nach Apache 2.0 § 4 b |
phosphor-icons-MIT.txt |
Lizenz der Phosphor-Icons |
material-symbols-APACHE-2.0.txt |
Lizenz der Material Symbols |
noto-emoji-APACHE-2.0.txt |
Lizenz der Noto-Emoji-Grafiken |
noto-emoji-flags-LICENSE.txt |
Erklärung des Noto-Repositorys zu den Flaggen (gemeinfrei) |
emoji-data-LICENSES.txt |
Lizenzen der Emoji-Daten (emojibase: MIT, Unicode: Unicode License V3) |
THIRD-PARTY-LICENSES.txt |
Lizenzen der gebündelten Bibliotheken und Schriften, beim Build erzeugt |
Diese Dateien und der Link „Licenses“ im Kopfbereich sind die Pflichtangaben der Lizenzen und sollten nicht entfernt werden.
Offener Punkt: Die Schlagworte und Kategorien der Material Symbols
(data/material-symbols-metadata.json) stammen aus den Google-Fonts-Metadaten
und nicht aus dem Apache-lizenzierten Repository. Dafür gibt es keine
ausdrückliche Lizenz. Wer das ausschließen will, leert in der Datei die Felder
tags und categories; die Suche findet Material-Icons dann nur noch über
ihren Namen.