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/pleroma

v1.0.2

Published

Pleroma adapter for ActivityPlug.

Readme

@activityplug/pleroma

@activityplug/pleroma adapts Pleroma and Akkoma client APIs to the ActivityPlug service contracts. It reuses Mastodon-compatible operations and adds family-specific capability detection, emoji reactions, filters, quote parameters, notification types, and streaming authentication.

Installation

pnpm add @activityplug/pleroma
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/pleroma";

Direct client

Create the adapter, supply a vetted remote transport, and detect the instance before constructing the operational client. Detection distinguishes Pleroma from Akkoma and supplies the resulting capabilities to the second client.

import {
  createActivityPlugClient,
  createRemoteAuthority,
  type RemoteAuthority,
} from "@activityplug/core";
import { createPleromaAdapter } from "@activityplug/pleroma";

export async function connectPleroma(
  origin: string,
  vettedTransport: typeof fetch,
) {
  const adapter = createPleromaAdapter();
  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.local({
  page: { limit: 20 },
});

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

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

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 Pleroma-compatible 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. It also maps local post visibility, quote_id post creation, emoji reactions, filter v1 operations, refresh tokens, and Pleroma emoji-reaction, chat-mention, and report notifications.

Detection treats Pleroma and Akkoma as distinct software families:

  • Pleroma status editing and edit history are unsupported.
  • Akkoma status editing and edit history remain unknown; the adapter does not infer them from a Pleroma-style version number.
  • Media upload and Pleroma-compatible filter v1 operations are supported.
  • Media lookup, media deletion, URL media ingestion, notification unread counts, post context, quote listing, grouped notifications, bookmark folders, peer listing, and conversation streams are unsupported.

Read client.capabilities before offering an operation. Calling an unsupported operation produces an ActivityPlugError with code UNSUPPORTED_OPERATION; an unknown capability is not permission to attempt the operation.

Streaming

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

Authenticated streams use a token-only WebSocket subprotocol. The adapter passes the token as the factory's protocols argument and never puts it in the URL. This mode is enabled for Akkoma and for a detected Pleroma version of 2.7.1 or newer. An older or unverified Pleroma version fails with UNSUPPORTED_OPERATION before opening the socket. Anonymous public streaming can still be used when the version is unknown.

The instance can advertise a streaming endpoint on a different host. Authenticated streams require wss: and an exact directional remote credential grant when that host differs from the instance origin. The grant's credential class is oauth-access-token, its representation is websocket-subprotocol, 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.