Skip to main content

🍜 Logo Soup

Real-world logos are messy. Some have padding, some don’t. Some are dense and blocky, others are thin and airy. Put them in a row and they look chaotic. Logo Soup fixes this automatically.

What it does

Logo Soup analyzes each logo image on a <canvas> and normalizes them so they appear visually balanced when displayed together. No server, no AI, fully deterministic.
  1. Content Detection — Finds the true boundaries of each logo, ignoring whitespace and padding baked into the image
  2. Aspect Ratio Normalization — Balances wide and tall logos so neither dominates
  3. Density Compensation — Measures visual weight so dense/bold logos don’t overpower light/thin ones
  4. Irradiation Compensation — Adjusts for the optical illusion where light content on dark backgrounds appears larger

Framework support

Logo Soup is a single npm package with subpath exports for every major framework:

Architecture

The library is built around a framework-agnostic core engine (createLogoSoup) that handles all image loading, measurement, normalization, caching, and cancellation. Each framework adapter is a thin wrapper (30–80 lines) that bridges the engine’s subscribe/getSnapshot interface into the framework’s reactivity model.
@sanity-labs/logo-soup          → Core engine, types, utilities
@sanity-labs/logo-soup/react    → useLogoSoup hook + LogoSoup component
@sanity-labs/logo-soup/vue      → useLogoSoup composable
@sanity-labs/logo-soup/svelte   → createLogoSoup (runes-compatible)
@sanity-labs/logo-soup/solid    → useLogoSoup primitive
@sanity-labs/logo-soup/angular  → LogoSoupService (Injectable)
@sanity-labs/logo-soup/node     → measureImage / measureImages (server-side)
Tree-shaking ensures a React consumer never pulls in Vue/Svelte/Solid/Angular code, and vice versa. The Node.js adapter lets you pre-compute measurements at build time or in API routes, so clients skip all canvas work. Need a framework we don’t support? Build your own adapter in 20–40 lines.