atoms

Atomic primitives

The high-level components (atproto-post, atproto-profile, etc.) are convenient defaults. The atomic primitives are the smaller building blocks underneath — pull them out individually when you need a custom layout that the high-level components don't fit.

All atomics share the same token system, ::part() hooks, and abort-on-disconnect lifecycle as the high-level components. They cache through the same dedup layer, so an avatar and a display-name pointing at the same subject share a single profile fetch.

Below is a custom author block composed entirely from atomics — no atproto-post needed. Each atomic resolves independently but shares the same in-memory cache, so the avatar / display-name / handle for pfrazee.com all hit the wire once.

Custom layout. Same data, your structure. The atproto-engagement-row below shows just likes + replies via the show attribute.

<!-- A bare-bones author line, composed from atomics -->
<style>
  .post { display: grid; grid-template-columns: auto 1fr; gap: 0.75rem; }
  .post .author { display: flex; gap: 0.35rem; align-items: baseline; }
</style>

<article class="post">
  <atproto-avatar src="pfrazee.com" linked></atproto-avatar>
  <div>
    <header class="author">
      <atproto-display-name src="pfrazee.com" linked></atproto-display-name>
      <atproto-handle src="pfrazee.com"></atproto-handle>
      <atproto-time datetime="2026-04-19T10:30:00Z"></atproto-time>
    </header>
    <p>Whatever text you want here.</p>
    <atproto-engagement-row src="at://..." show="likes,replies"></atproto-engagement-row>
  </div>
</article>