Tool Guides August 10, 2026 • 8 min read • By DevBuildTool Protocol Engineering Team

Understanding the AT Protocol: Grapheme Clusters, Rich Text Facets, and Bluesky Microblogging

A developer deep-dive into Bluesky AT Protocol (Authenticated Transfer Protocol) specifications, grapheme cluster character counting, rich text byte-slice facets, and decentralized microblogging APIs.

Advertisement

Bluesky operates on the Authenticated Transfer Protocol (AT Protocol)β€”an open, decentralized networking protocol designed for federated social applications. While traditional social networks measure post lengths using simple string length or UTF-16 code units, the AT Protocol uses strict Unicode Grapheme Clusters and UTF-8 Byte Slices for post character counts and rich text link facets.

1. What is the AT Protocol?

The AT Protocol enables federated social networking where user accounts (DIDs), posts, and follows are signed cryptographic records stored inside Personal Data Servers (PDS).

2. Bytes vs Code Points vs Grapheme Clusters

Counting text length accurately across international languages and emoji sequences requires distinguishing three concepts:

  • UTF-16 Length: JavaScript's "hello".length counts 16-bit code units. Complex emojis like πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ have a length of 11.
  • Unicode Code Points: The distinct numerical values assigned to characters. Emojis with Zero-Width Joiners (ZWJ) consist of multiple code points.
  • Grapheme Clusters: What a human perceives as a single visual character unit (e.g. πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ is 1 grapheme cluster).

Bluesky posts enforce a hard maximum limit of 300 Grapheme Clusters per post.

3. Rich Text Facets & Entity Indexing

Unlike HTML where links are embedded as <a href="...">text</a>, Bluesky post text is kept completely plain. Web URLs, user mentions (@handle), and hashtags (#topic) are attached as Facets containing UTF-8 byte start and end indices:

// Post Payload Object
{
  "text": "Check out DevBuildTool at https://devbuildtool.com today!",
  "facets": [
    {
      "index": { "byteStart": 24, "byteEnd": 48 },
      "features": [{
        "$type": "app.bsky.richtext.facet#link",
        "uri": "https://devbuildtool.com"
      }]
    }
  ]
}

4. Building an AT Protocol Post Counter

To accurately count Bluesky characters using modern JavaScript Intl APIs:

function countBlueskyGraphemes(text) {
  // Use Intl.Segmenter for true Unicode Grapheme Cluster counting
  const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
  const segments = Array.from(segmenter.segment(text));
  
  const count = segments.length;
  const remaining = 300 - count;
  const isOverLimit = count > 300;
  
  return { count, remaining, isOverLimit };
}
Sponsored Content