npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@activityplug/mastodon

v1.0.2

Published

Mastodon adapter for ActivityPlug.

Readme

@activityplug/mastodon

@activityplug/mastodon adapts Mastodon's client API to the ActivityPlug service contracts. Use it with @activityplug/core for direct TypeScript access, or register it with @activityplug/server.

Installation

pnpm add @activityplug/mastodon
pnpm add @activityplug/core

@activityplug/core is a peer dependency. Install a compatible version chosen by your application. Node.js 26 or newer is required, and the package uses ECMAScript modules.

The package root is the public module:

import * as activityplug from "@activityplug/mastodon";

Direct client

Create the adapter, supply a vetted remote transport, and detect the instance before constructing the operational client. Detection supplies version-dependent capabilities to the second client.

import {
  createActivityPlugClient,
  createRemoteAuthority,
  type RemoteAuthority,
} from "@activityplug/core";
import { createMastodonAdapter } from "@activityplug/mastodon";

export async function connectMastodon(
  origin: string,
  vettedTransport: typeof fetch,
) {
  const adapter = createMastodonAdapter();
  const remoteAuthority: RemoteAuthority = createRemoteAuthority({
    transport: vettedTransport,
  });
  const bootstrap = createActivityPlugClient({
    adapter,
    origin,
    remoteAuthority,
  });
  const profile = await bootstrap.instances.detect();

  return createActivityPlugClient({
    adapter,
    origin,
    remoteAuthority,
    capabilities: profile.capabilities,
    detectedSoftware: profile.software,
  });
}

vettedTransport must enforce the application's origin, DNS, private-network, redirect, timeout, and response-size policy. createRemoteAuthority() rejects the raw global fetch; omitting remoteAuthority causes remote operations to fail with ORIGIN_NOT_ALLOWED.

The client groups operations by service. For example:

const timeline = await client.timelines.public({
  page: { limit: 20 },
});

const session = await client.auth.token.importToken({
  accessToken: process.env.MASTODON_TOKEN!,
  scopes: ["read", "write"],
});

const post = await client.posts.create({
  session,
  content: "Posted through ActivityPlug.",
  visibility: "public",
});

Auth sessions do not expose stored access tokens. The default session store is in-memory; applications that need sessions to survive a process restart must inject a durable AuthSessionStore.

Supported behavior

The adapter covers Mastodon account lookup and profile updates, posts, timelines, search, media upload and update, polls, notifications, lists, follow requests, filters, scheduled posts, social actions, OAuth, token import, and timeline and notification streams. Read the detected capability set before offering an operation to a user.

Several operations depend on the detected Mastodon version:

  • Status editing and edit history require Mastodon 3.5.0 or newer.
  • Asynchronous media upload requires Mastodon 3.1.3 or newer.
  • Notification unread counts require Mastodon 4.3.0 or newer.
  • Media deletion requires Mastodon 4.4.0 or newer.
  • Filter v2 read, create, and delete operations require Mastodon 4.0.0 or newer. Filter updates are not mapped.

An absent, unstable, or unrecognized version leaves version-gated capabilities unknown instead of assuming support.

This adapter does not map post context, quote creation or listing, post translation, media lookup, URL media ingestion, grouped notifications, emoji reactions, bookmark folders, peer listing, or conversation streams. Calling an unsupported operation produces an ActivityPlugError with code UNSUPPORTED_OPERATION.

Streaming

Pass a webSocket factory to createMastodonAdapter() to enable timeline and notification streams. The adapter never creates a socket from a global WebSocket implementation.

The instance can advertise a streaming endpoint on a different host. The factory and remote authority must allow that destination. Authenticated streams require wss:. Mastodon authentication is passed through WebSocketFactoryCallOptions.authorization; the factory must send it as the WebSocket Authorization header. The token is never added to the URL.

A cross-origin authenticated stream also needs an exact directional remote credential grant. Its credential class is oauth-access-token, its representation is authorization-header, and its operation is stream.timeline or stream.notifications. Anonymous streams carry no credential, but the factory must still enforce its egress policy.

Streams are async iterables. Abort them with the signal supplied in the stream input and implement reconnection in the consuming application.

Errors

Adapter failures use ActivityPlugError. Check error.code and the adapter, origin, operation, and capability fields in error.context. Do not branch on message text. Common codes include AUTH_REQUIRED, UNSUPPORTED_OPERATION, VALIDATION_FAILED, REMOTE_PROTOCOL_ERROR, RATE_LIMITED, ORIGIN_NOT_ALLOWED, and REQUEST_LIMIT_EXCEEDED.

Related documentation

License

Licensed under Apache-2.0 OR MIT. See LICENSE-APACHE and LICENSE-MIT.