A small program to help build social media software on the Fediverse. It emulates known Fediverse software, helping solve the problem where developers have to manually test compatibility with dozens of other projects.
JavaScript
50
45 commits
updated Dec 2, 2025
The ActivityPub Fuzzer is a small program to help developers build social media software on the Fediverse with the ActivityPub protocol. It uses data collected by the Fediverse Schema Observatory to emulate known Fediverse software, solving the problem where developers have to manually test compatibility with dozens of other projects. The Fuzzer runs in a local development environment. You can tell it to locally emulate a public fire hose, or to send you messages formatted from every known version of a specific software project.
For more information on how this federates, see FEDERATION.md in this repository.
This codebase is AGPL 3.0 licensed (see LICENSE.txt). Dependencies distributed with this project (external and vendored) are AGPL compatible and should be consulted as needed.
You'll need to install the server, configure it, and run it. Before you do that, you'll need to install a tunneling service to make your local server accessible from the internet (no one needs to know its URL exists, this is just to provide an HTTPS connection to "federate" over).
To make your instance of the Fuzzer accessible from the internet, you can use a tunneling service like ngrok or fedify tunnel. Any tunneling service you want will work, but for this example we'll use fedify tunnel.
The Fedify project provides a free and open source CLI tool for fediverse developers with a lot of nice functionality including a tunnel command that takes a process running on a local port and exposes it via an HTTPS URL. You can install via npm:
npm install -g @fedify/cli
Then you can run it to expose your local Fuzzer server running on port 3000:
fedify tunnel 3000
git clone git@github.com:berkmancenter/activitypub-fuzzer.gitcd activitypub-fuzzernpm iobservatory.db.env.example to .env.env to set the following variables:| Variable name | Description | Example value |
|---|---|---|
DEFAULT_TARGET_ENDPOINT | the URL of an ActivityPub inbox you want the Fuzzer to send activities to | https://myserver.example/users/alice/inbox |
DEFAULT_TARGET_USER_ID | the ID of an ActivityPub account you want the Fuzzer to interact with in case of a follow | https://myserver.example/users/alice/ |
ACCOUNT | the account name of the main account on the Fuzzer | fuzzer |
DOMAIN | the domain name of the Fuzzer as exposed by the tunneling service, without https:// | fuzzer.example (if using a tunneling service like ngrok, this will be something like abcd1234.ngrok.io) |
PORT | the port number to run the Fuzzer on | 3000 |
ACTOR_DISPLAY_NAME | the display name of the main account on the Fuzzer | Fuzzer |
ACTOR_DESCRIPTION | a short description of the main account on the Fuzzer, which will appear in the main fuzzer account profile if you fetch it | A fuzzer for ActivityPub |
ACTOR_AVATAR | a URL to an image to use as the avatar for the main account on the Fuzzer | https://example.com/avatar.png |
fedify tunnel 3000 (or start your tunneling service of choice, use PORT defined above)npm startYou should see a message like:
Server is running on http://localhost:3000
Connected to the SQLite database.
Connected to the SQLite database.
Messages table created successfully.
Accounts table created successfully.
Record created for primary Fuzzer ActivityPub Actor and webfinger
Actor ID: https://fuzzer.example/u/fuzz
Webfinger uri: https://fuzzer.example/.well-known/webfinger?resource=acct:fuzz@fuzzer.example
If you go to whatever URL your tunneling service provided (e.g. https://abcd1234.ngrok.io), you should see the Fuzzer website, and if you go to the two URLs printed in the "Actor ID" and "Webfinger uri" log messages, you should see the ActivityPub actor JSON and the webfinger JSON.
At this point, the Fuzzer is running and you can:
@fuzz@fuzzer.example in the user search for most Fediverse software and discover the Fuzzer's main actor accountThere is a checkbox in the Fuzzer called "Rewrite Announce to Create". This is because the Fuzzer only currently supports Create activities, but there are lots of good Objects in the Observatory data set that are wrapped in Announce due to the Observatory collecting data from relays. If you check this box, any Announce activities sent by the Fuzzer will be rewritten as Create activities with the same object and should be similar to directly following an account from a service and getting the Create instead of the Announce.
There is a Github Project to track future work on the Fuzzer.
If there's a feature you'd like this to have, please open an issue or a pull request! Right now I mostly want to prioritize issues from users, but am also planning to add:
JavaScript
75.3%
Handlebars
24.7%
A small program to help build social media software on the Fediverse. It emulates known Fediverse software, helping solve the problem where developers have to manually test compatibility with dozens of other projects.
JavaScript
50
45 commits
updated Dec 2, 2025
The ActivityPub Fuzzer is a small program to help developers build social media software on the Fediverse with the ActivityPub protocol. It uses data collected by the Fediverse Schema Observatory to emulate known Fediverse software, solving the problem where developers have to manually test compatibility with dozens of other projects. The Fuzzer runs in a local development environment. You can tell it to locally emulate a public fire hose, or to send you messages formatted from every known version of a specific software project.
For more information on how this federates, see FEDERATION.md in this repository.
This codebase is AGPL 3.0 licensed (see LICENSE.txt). Dependencies distributed with this project (external and vendored) are AGPL compatible and should be consulted as needed.
You'll need to install the server, configure it, and run it. Before you do that, you'll need to install a tunneling service to make your local server accessible from the internet (no one needs to know its URL exists, this is just to provide an HTTPS connection to "federate" over).
To make your instance of the Fuzzer accessible from the internet, you can use a tunneling service like ngrok or fedify tunnel. Any tunneling service you want will work, but for this example we'll use fedify tunnel.
The Fedify project provides a free and open source CLI tool for fediverse developers with a lot of nice functionality including a tunnel command that takes a process running on a local port and exposes it via an HTTPS URL. You can install via npm:
npm install -g @fedify/cli
Then you can run it to expose your local Fuzzer server running on port 3000:
fedify tunnel 3000
git clone git@github.com:berkmancenter/activitypub-fuzzer.gitcd activitypub-fuzzernpm iobservatory.db.env.example to .env.env to set the following variables:| Variable name | Description | Example value |
|---|---|---|
DEFAULT_TARGET_ENDPOINT | the URL of an ActivityPub inbox you want the Fuzzer to send activities to | https://myserver.example/users/alice/inbox |
DEFAULT_TARGET_USER_ID | the ID of an ActivityPub account you want the Fuzzer to interact with in case of a follow | https://myserver.example/users/alice/ |
ACCOUNT | the account name of the main account on the Fuzzer | fuzzer |
DOMAIN | the domain name of the Fuzzer as exposed by the tunneling service, without https:// | fuzzer.example (if using a tunneling service like ngrok, this will be something like abcd1234.ngrok.io) |
PORT | the port number to run the Fuzzer on | 3000 |
ACTOR_DISPLAY_NAME | the display name of the main account on the Fuzzer | Fuzzer |
ACTOR_DESCRIPTION | a short description of the main account on the Fuzzer, which will appear in the main fuzzer account profile if you fetch it | A fuzzer for ActivityPub |
ACTOR_AVATAR | a URL to an image to use as the avatar for the main account on the Fuzzer | https://example.com/avatar.png |
fedify tunnel 3000 (or start your tunneling service of choice, use PORT defined above)npm startYou should see a message like:
Server is running on http://localhost:3000
Connected to the SQLite database.
Connected to the SQLite database.
Messages table created successfully.
Accounts table created successfully.
Record created for primary Fuzzer ActivityPub Actor and webfinger
Actor ID: https://fuzzer.example/u/fuzz
Webfinger uri: https://fuzzer.example/.well-known/webfinger?resource=acct:fuzz@fuzzer.example
If you go to whatever URL your tunneling service provided (e.g. https://abcd1234.ngrok.io), you should see the Fuzzer website, and if you go to the two URLs printed in the "Actor ID" and "Webfinger uri" log messages, you should see the ActivityPub actor JSON and the webfinger JSON.
At this point, the Fuzzer is running and you can:
@fuzz@fuzzer.example in the user search for most Fediverse software and discover the Fuzzer's main actor accountThere is a checkbox in the Fuzzer called "Rewrite Announce to Create". This is because the Fuzzer only currently supports Create activities, but there are lots of good Objects in the Observatory data set that are wrapped in Announce due to the Observatory collecting data from relays. If you check this box, any Announce activities sent by the Fuzzer will be rewritten as Create activities with the same object and should be similar to directly following an account from a service and getting the Create instead of the Announce.
There is a Github Project to track future work on the Fuzzer.
If there's a feature you'd like this to have, please open an issue or a pull request! Right now I mostly want to prioritize issues from users, but am also planning to add:
JavaScript
75.3%
Handlebars
24.7%