Framework guides

Core (vanilla TypeScript)

@scribe-atp/core is pure TypeScript with no runtime dependencies. It works in any environment: Node.js, Deno, Bun, browsers, edge functions, or any JavaScript runtime.

All framework adapters are thin wrappers around this package. If your framework isn't listed, or you prefer to manage state yourself, use @scribe-atp/core directly.

Install

npm install @scribe-atp/core

Fetch a site

import { fetchSite } from '@scribe-atp/core';

const site = await fetchSite('alice.bsky.social', 'https://alice.bsky.social');

console.log(site.title);
console.log(site.description);
console.log(site.url);        // e.g. "alice.bsky.social"
console.log(site.urlPrefix);  // e.g. "blog" or ""

for (const group of site.groups) {
  for (const article of group.articles) {
    console.log(article.title, article.slug, article.description);
  }
}

// Legacy field, always empty for current content — see Core Concepts
console.log(site.ungroupedArticles);

Fetch an article

import { fetchArticle } from '@scribe-atp/core';

const article = await fetchArticle('alice.bsky.social', 'my-first-post');

console.log(article.title);
console.log(article.description);
console.log(article.content);  // Full HTML — safe to render directly
console.log(article.createdAt);

Utilities

import { slugFromUri, flattenArticles } from '@scribe-atp/core';

slugFromUri('at://did:plc:abc/site.standard.document/my-post') // → "my-post"

// All published articles across all groups, in order
const allArticles = flattenArticles(site.groups);

Cancelling requests

Both functions accept an optional AbortSignal as a third argument:

// Server context — cancel if the user navigates away
const site = await fetchSite(author, 'https://alice.bsky.social', request.signal);

// Client context — cancel on unmount or parameter change
const controller = new AbortController();
const site = await fetchSite(author, 'https://alice.bsky.social', controller.signal);
controller.abort(); // cancel

Tip

Framework adapters wire up cancellation automatically. You only need to manage signals manually when using @scribe-atp/core directly.

TypeScript types

import type { Site, Article, ArticleRef, SiteGroup } from '@scribe-atp/core';

See the API reference for full type definitions.

Settings

Appearance