# @atcute/bluesky-richtext-segmenter

> segments Bluesky's rich text facets into tokens

Latest version **3.0.2** (published 2026-07-16) · 0BSD license · 0 weekly downloads

## Install

```sh
npm install @atcute/bluesky-richtext-segmenter
pnpm add @atcute/bluesky-richtext-segmenter
yarn add @atcute/bluesky-richtext-segmenter
bun add @atcute/bluesky-richtext-segmenter
```

## Health

**Score 60/100 (C)** — status: active.

Positive: esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 3.0.2 |
| Published | 2026-07-16 |
| First published | 2024-10-16 |
| Weekly downloads | 0 |
| License | 0BSD |
| TypeScript types | none |
| Module format | ESM |
| Dependencies | 0 |
| Unpacked size | 7.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 515 |
| Maintainers | externdefs |

## Links

- npm: https://www.npmjs.com/package/@atcute/bluesky-richtext-segmenter
- Repository: https://github.com/mary-ext/atcute
- npm.io page: https://npm.io/package/@atcute/bluesky-richtext-segmenter

## Recent versions

- 3.0.2 (latest) — 2026-07-16
- 3.0.1 — 2026-06-29
- 3.0.0 — 2026-01-15
- 2.0.4 — 2025-10-09
- 2.0.3 — 2025-05-20
- 2.0.2 — 2025-05-17
- 2.0.1 — 2025-05-14
- 2.0.0 — 2025-04-10
- 1.0.5 — 2024-11-15
- 1.0.4 — 2024-11-12
- 1.0.3 — 2024-11-06
- 1.0.2 — 2024-10-31
- 1.0.1 — 2024-10-26
- 1.0.0 — 2024-10-16

## README

# @atcute/bluesky-richtext-segmenter

segments Bluesky rich text into tokens for rendering.

```sh
npm install @atcute/bluesky-richtext-segmenter
```

Bluesky posts contain text and facets (byte-range annotations for mentions, links, etc). this
package splits the text into segments, each with its associated features, so you can render them
appropriately.

## usage

```ts
import { segmentize } from '@atcute/bluesky-richtext-segmenter';

// text and facets from a post record
const text = 'hello @bsky.app!';
const facets = [
	{
		index: { byteStart: 6, byteEnd: 15 },
		features: [
			{ $type: 'app.bsky.richtext.facet#mention', did: 'did:plc:z72i7hdynmk6r22z27h6tvur' },
		],
	},
];

const segments = segmentize(text, facets);
// -> [
//   { text: 'hello ', features: undefined },
//   { text: '@bsky.app', features: [{ $type: '...#mention', did: '...' }] },
//   { text: '!', features: undefined }
// ]
```

### rendering segments

each segment contains `text` and optionally `features`. render based on the feature type:

```tsx
import { segmentize, type RichtextSegment } from '@atcute/bluesky-richtext-segmenter';

const renderSegment = (segment: RichtextSegment, index: number) => {
	const { text, features } = segment;

	if (!features) {
		return <span key={index}>{text}</span>;
	}

	// segments can have multiple features, use the first one
	const feature = features[0];

	switch (feature.$type) {
		case 'app.bsky.richtext.facet#mention':
			return (
				<a key={index} href={`/profile/${feature.did}`}>
					{text}
				</a>
			);

		case 'app.bsky.richtext.facet#link':
			return (
				<a key={index} href={feature.uri} target="_blank" rel="noopener noreferrer">
					{text}
				</a>
			);

		case 'app.bsky.richtext.facet#tag':
			return (
				<a key={index} href={`/search?q=${encodeURIComponent('#' + feature.tag)}`}>
					{text}
				</a>
			);

		default:
			return <span key={index}>{text}</span>;
	}
};

const RichText = ({ text, facets }: { text: string; facets?: Facet[] }) => {
	const segments = segmentize(text, facets);
	return <>{segments.map(renderSegment)}</>;
};
```

---
_Source: https://npm.io/package/@atcute/bluesky-richtext-segmenter · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
