Skip to content

← all comparisons

Read-only global state

Cart badge

The smallest possible store consumer. Subscribes to a computed total and renders it.

Each panel header shows the source size of that component file (raw, gzipped, line count). Source-only — framework runtime (React ~45 KB, Vue ~35 KB, Svelte ~5 KB gzipped) is shared across every island and isn't included in these numbers.

React 310 B gzip · 13 lines
CartBadgeReact.tsx
How this works

useStore on the computed total. The component re-renders only when cartCount changes, not on every cart mutation that doesn't affect the sum.

import { useStore } from '@nanostores/react';
import { cartCount } from '../stores/cart';

export default function CartBadgeReact() {
  const count = useStore(cartCount);
  return (
    <span className="inline-flex items-center gap-1.5 rounded-full bg-sky-100 dark:bg-sky-900/40 px-3 py-1 text-sm font-medium text-sky-900 dark:text-sky-100">
      <span className="text-xs uppercase tracking-wider text-sky-700 dark:text-sky-300">React</span>
      <span className="tabular-nums">{count}</span>
    </span>
  );
}
Vue 301 B gzip · 14 lines
CartBadgeVue.vue
How this works

useStore returns a ref. Templates auto-unwrap refs, so {{ count }} just works without .value.

<script setup lang="ts">
import { useStore } from '@nanostores/vue';
import { cartCount } from '../stores/cart';

const count = useStore(cartCount);
</script>

<template>
  <span class="inline-flex items-center gap-1.5 rounded-full bg-emerald-100 dark:bg-emerald-900/40 px-3 py-1 text-sm font-medium text-emerald-900 dark:text-emerald-100">
    <span class="text-xs uppercase tracking-wider text-emerald-700 dark:text-emerald-300">Vue</span>
    <span class="tabular-nums">{{ count }}</span>
  </span>
</template>
Svelte 253 B gzip · 9 lines
CartBadgeSvelte.svelte
How this works

$cartCount auto-subscription. Three lines of script, zero subscription boilerplate.

<script lang="ts">
  import { cartCount } from '../stores/cart';
</script>

<span class="inline-flex items-center gap-1.5 rounded-full bg-orange-100 dark:bg-orange-900/40 px-3 py-1 text-sm font-medium text-orange-900 dark:text-orange-100">
  <span class="text-xs uppercase tracking-wider text-orange-700 dark:text-orange-300">Svelte</span>
  <span class="tabular-nums">{$cartCount}</span>
</span>