No description
  • Ruby 60.9%
  • TypeScript 20.4%
  • JavaScript 9.9%
  • SCSS 4.5%
  • Haml 3.9%
  • Other 0.3%
Find a file
jops 48d0e04946
All checks were successful
Create and publish streaming container image / build-and-push-image (push) Successful in 1m21s
Create and publish container image / build-and-push-image (push) Successful in 36m9s
bastodon: expose full feature config in /api/v2/instance for native apps
Add the fields that were only in the web initial_state so third-party/native
  clients (Busky) can detect every feature: auto_thread.warning, gancio.description,
  radio.link, peertube.description, and the new neighborhood { enabled, instances }.

  Also fix peertube being missing from the serializer attributes list on bida, so
  it was never actually exposed in /api/v2/instance.
2026-06-19 00:54:11 +02:00
.devcontainer Add devcontainer-lock.json with Renovate update support (#39046) 2026-06-15 11:49:12 +00:00
.forgejo/workflows bastodon: align bida to upstream main (4.6) + all bastodon features 2026-06-17 01:38:15 +02:00
.github Update crowdin/github-action digest to 52aa776 (#39424) 2026-06-16 09:08:01 +00:00
.husky Update husky and remove deprecated features (#29338) 2024-02-22 09:02:15 +00:00
.rubocop Update rubocop to version 1.86.2 (#39136) 2026-05-27 09:11:31 +00:00
.storybook Render FormattedMessage translations into React.Fragment by default (#38398) 2026-03-25 15:01:40 +00:00
.yarn Remove yarn patch for babel-plugin-lodash, removed during Vite upgrade (#37161) 2025-12-09 09:30:57 +00:00
app bastodon: expose full feature config in /api/v2/instance for native apps 2026-06-19 00:54:11 +02:00
bin Remove deprecated bin/update script (#39443) 2026-06-16 08:32:19 +00:00
chart helm: cleanup helm chart, now in mastodon/chart (#21801) 2022-12-09 06:36:29 +01:00
config Merge upstream/main (Mastodon 4.6-dev) into bida 2026-06-17 15:20:00 +02:00
db Merge upstream/main (Mastodon 4.6-dev) into bida 2026-06-17 15:20:00 +02:00
dist Add try_files directive comments to nginx.conf (#37866) 2026-02-17 08:55:11 +00:00
docs Fix hero image radius, bring into repo (#38679) 2026-04-15 11:32:51 +00:00
lib Handle missing sw.js in test environment assets (#39459) 2026-06-17 09:01:45 +00:00
log Initial commit 2016-02-20 22:53:20 +01:00
public Refactor emoji search (#39008) 2026-05-19 10:47:45 +00:00
spec Handle missing sw.js in test environment assets (#39459) 2026-06-17 09:01:45 +00:00
streaming Merge upstream/main (Mastodon 4.6-dev) into bida 2026-06-17 15:20:00 +02:00
vendor Increase files checked by ESLint (#9705) 2019-01-04 11:28:38 +01:00
.annotaterb.yml Change dependency from annotate to annotaterb (#30232) 2024-11-18 14:40:02 +00:00
.browserslistrc Update browserslists target (#39076) 2026-05-19 16:21:18 +00:00
.buildpacks Remove nodejs buildpack from buildpacks (#14364) 2020-07-20 09:48:10 +02:00
.dockerignore Performance regression fixes (#35664) 2025-08-04 17:16:12 +00:00
.editorconfig Enable EditorConfig trailing whitespace trimming (#23543) 2023-02-12 08:34:17 +01:00
.env.development Enable AR Encryption (#29831) 2024-04-17 09:19:02 +00:00
.env.production.sample Remove environment variables to config Fetch All Replies behaviour (#36627) 2025-10-28 15:58:18 +00:00
.env.test Add emphasis on ActiveRecord Encryption configuration values being secret (#30340) 2024-05-17 09:28:40 +00:00
.env.vagrant Add elastic search installation into Vagrantfile (#26512) 2023-08-23 15:46:14 +02:00
.foreman Replace sprockets/browserify with Webpack (#2617) 2017-05-03 02:04:16 +02:00
.gitattributes Add .gitattributes file to avoid unwanted CRLF (#3954) 2017-06-26 13:15:24 +02:00
.gitignore Emoji: Remove final flag (#36409) 2025-10-28 11:33:27 +00:00
.haml-lint.yml Reduce haml-lint LineLength configuration to 240 (#37287) 2026-03-02 14:43:57 +00:00
.nvmrc Update Node.js to 24.16 (#39130) 2026-05-28 11:46:57 +00:00
.oxfmtrc.json Replace prettier with oxfmt (#37893) 2026-02-19 18:04:25 +00:00
.rspec Remove fuubar gem and custom rspec --format setting (#30594) 2024-09-03 15:24:31 +00:00
.rubocop.yml Drop support for ruby 3.2 (#37476) 2026-03-25 13:18:34 +00:00
.rubocop_todo.yml Update rubocop to version 1.80.2 (#36007) 2025-09-04 08:14:01 +00:00
.ruby-gemset Make Mastodon use its own gemset (#17858) 2022-08-13 15:44:34 +02:00
.ruby-version Update to ruby 4.0.5 (#39099) 2026-05-21 11:45:36 +00:00
.simplecov Move simplecov start to config and require to spec_helper (#39236) 2026-06-01 13:37:17 +00:00
.slugignore Remove Storybook (#4397) 2017-07-27 22:30:27 +02:00
.watchmanconfig Fix Jest config (#27834) 2023-11-13 12:19:41 +00:00
.yarnrc.yml Upgrade to Yarn 4, remove support for Node 16 (#27073) 2023-11-08 10:57:21 +00:00
app.json Remove OTP_SECRET env configuration from setup (#34757) 2025-05-21 15:08:46 +00:00
Aptfile Refresh Heroku related thingy for heroku-24 stack (#31135) 2024-09-03 16:03:00 +00:00
AUTHORS.md Make tootctl aware of 'require approval' for email domains (#34579) 2025-11-27 15:52:59 +00:00
CHANGELOG.md Trim stable-4.3 from changelog and update SECURITY.md (#39395) 2026-06-12 09:33:03 +00:00
CODE_OF_CONDUCT.md Update to Contributor Covenant v3.0 (#36323) 2026-03-30 16:36:07 +00:00
config.ru Match dependency-generator output for require_relative usage (#32800) 2024-11-08 09:55:15 +00:00
CONTRIBUTING.md Update contributing docs (#38125) 2026-03-10 12:53:20 +00:00
crowdin.yml Case correction Github -> GitHub (#30446) 2024-06-08 10:32:39 +00:00
docker-compose.yml Merge upstream/main (Mastodon 4.6-dev) into bida 2026-06-17 15:20:00 +02:00
Dockerfile Update dependency libvips to v8.18.3 (#39344) 2026-06-10 09:04:23 +00:00
eslint.config.mjs Emoji text input and character counter components (#38052) 2026-03-04 16:13:45 +00:00
FEDERATION.md Change media description length limit for remote media attachments from 1500 to 10000 characters (#37921) 2026-03-23 10:32:41 +00:00
Gemfile Update vite_rails to version 3.11.0 (#39218) 2026-06-01 14:51:01 +00:00
Gemfile.lock Update dependency rubyzip to v3.4.0 (#39423) 2026-06-16 08:22:08 +00:00
jsconfig.json Update devDependencies (non-major) (#29089) 2024-02-27 16:07:43 +00:00
LICENSE Fix #49 - License changed from GPL-2.0 to AGPL-3.0 2016-09-21 23:04:34 +02:00
lint-staged.config.js Replace prettier with oxfmt (#37893) 2026-02-19 18:04:25 +00:00
package.json Update dependency react-easy-crop to v6 (#39371) 2026-06-15 14:07:41 +00:00
priv-config TOR federation (#7875) 2018-06-26 20:34:12 +02:00
Procfile Refresh Heroku related thingy for heroku-24 stack (#31135) 2024-09-03 16:03:00 +00:00
Procfile.dev Convert from Webpack to Vite (#34450) 2025-05-16 13:26:12 +00:00
publiccode.yml Add publiccode.yml (#38659) 2026-04-14 11:28:15 +00:00
Rakefile Match dependency-generator output for require_relative usage (#32800) 2024-11-08 09:55:15 +00:00
README.md Merge upstream/main (Mastodon 4.6-dev) into bida 2026-06-17 15:20:00 +02:00
scalingo.json Remove OTP_SECRET env configuration from setup (#34757) 2025-05-21 15:08:46 +00:00
SECURITY.md Trim stable-4.3 from changelog and update SECURITY.md (#39395) 2026-06-12 09:33:03 +00:00
stylelint.config.js Stylelint: Allow leading underscore in CSS variable names (#38966) 2026-05-08 14:24:02 +00:00
tsconfig.json Update dependency typescript to v6 (#38344) 2026-03-25 13:43:41 +00:00
Vagrantfile Updates vagrant to Node v24 (#39124) 2026-05-21 12:09:08 +00:00
vite.config.mts Fix service worker failing to load due to 404 on chunk dependencies (#39433) 2026-06-15 13:21:10 +00:00
vitest.config.mts Update dependency vite to v8 (#38174) 2026-03-23 11:47:03 +00:00
vitest.shims.d.ts feat: Add Storybook for component documentation, testing, and development (#34907) 2025-06-06 09:27:29 +00:00
yarn.lock Update dependency @vitest/browser to v4.1.8 [SECURITY] (#39451) 2026-06-16 09:45:16 +00:00

Bastodon

Bastodon is a fork of Mastodon that is fully compatible with upstream. It does not change the default behavior: it adds optional features that can be enabled through environment variables. If no variables are set, Bastodon behaves exactly like vanilla Mastodon.

Why Bastodon

Bastodon was born out of a critique of how Mastodon is developed: a roadmap driven from the top down, where the priorities and choices of the upstream project do not always reflect the needs of the communities that actually inhabit the network.

Against that model, every feature in this fork was discussed and decided collectively by the instance assemblies of mastodon.bida.im. The software follows the choices of the community that uses it, not the other way around. The features below are the concrete result of those assemblies — which is also why they are all optional and disabled by default: each instance stays free to enable only what it has collectively chosen.

Bastodon Features

Neighborhood Timeline

A dedicated timeline that aggregates public posts from configured friendly instances. Allows following the activity of nearby communities without having to search through the federated timeline.

  • NEIGHBORHOOD_TIMELINE_ENABLED=true - enables the "Neighborhood" tab in live feeds
  • NEIGHBORHOOD_INSTANCES=instance1.org,instance2.net - comma-separated list of friendly instance domains
  • NEIGHBORHOOD_DEBUG=true - debug logging

Configurable Max Characters

Allows setting a character limit different from the default 500.

  • MAX_CHARS=840 - maximum number of characters per post

Auto-thread for Long Posts

When enabled, posts exceeding the character limit are automatically split into a thread. The first post keeps the visibility chosen by the user, subsequent ones are unlisted to avoid flooding the public timeline. Also works for third-party apps via API.

  • AUTO_THREAD_ENABLED=true - enables automatic splitting
  • AUTO_THREAD_WARNING=message - warning message shown below the Post button when composing a post that will be split. Useful to discourage excessive use of the feature

Events Agenda (Gancio Integration)

Integration with Gancio, the federated platform for event management. Allows browsing events from configured Gancio instances and saving them to a personal agenda.

  • GANCIO_ENABLED=true - enables the integration
  • GANCIO_INSTANCES=balotta.org,agenda.reteappenninica.it - Gancio instances to fetch events from
  • GANCIO_DESCRIPTION=text - description shown at the top of the events page

Features:

  • /events page to browse all events from Gancio instances with interactive calendar
  • Personal agenda: save events you're interested in with "Add to agenda" button
  • /events-personal page with your personal calendar and saved events
  • Mini-calendar in the sidebar (desktop) with dots on days that have events
  • Click on a day in the mini-calendar opens your personal agenda for that day
  • Remove events from your agenda
  • Background fetch via Sidekiq worker (every 15 minutes) + manual refresh button
  • Events and Radio links visible to non-logged-in users; My Agenda only for logged-in users
  • Data exposed via API for third-party apps
  • Event thumbnails are cached locally and served from our own domain through a proxy (/gancio_media) instead of being hotlinked from the Gancio instances. This fixes images that often failed to load (slow/down remote instance, hotlink protection, mixed content) and keeps them working even if the Gancio instance goes down. The Sidekiq worker pre-downloads images into the cache (Redis, 1 day TTL) so they are ready before anyone opens the page; the proxy downloads on demand as a fallback. Only the hosts listed in GANCIO_INSTANCES can be proxied, so it cannot be turned into an open proxy.

After deploying changes to the events feature, the Gancio events already cached in Redis (30 min TTL) may still hold the old image URLs. Force a refresh so they are regenerated with the proxied URLs and their images get pre-downloaded:

# Docker (sidekiq or web service)
docker compose exec sidekiq bin/rails runner "Rails.cache.delete('gancio:events'); GancioFetchWorker.new.perform"

# Non-Docker
bin/rails runner "Rails.cache.delete('gancio:events'); GancioFetchWorker.new.perform"

Radio Player

Audio player integrated in the sidebar (desktop) and as a dedicated page (mobile) for listening to a community web radio.

  • RADIO_ENABLED=true - enables the player
  • RADIO_URL=https://stream.example.org/stream.ogg - audio stream URL
  • RADIO_NAME=Radio Spore - radio name shown in the player
  • RADIO_DESCRIPTION=Community radio - description (visible on mouseover on desktop, shown on radio page)
  • RADIO_LINK=https://radiospore.oziosi.org - URL opened when clicking the radio name

Features:

  • Persistent playback: audio continues playing when navigating between pages
  • On mobile, a mini bar appears at the bottom while radio is playing
  • Supports OGG, MP3, and other formats handled by the HTML5 <audio> tag
  • Dedicated /radio page with large player, description, and link

PeerTube Videos

Integration with PeerTube, the federated video platform. Reads the latest videos from configured PeerTube instances and shows them in a single chronological list, with a live-stream alert.

  • PEERTUBE_ENABLED=true - enables the integration
  • PEERTUBE_INSTANCES=tube1.org,tube2.net - PeerTube instances to fetch videos from
  • PEERTUBE_DESCRIPTION=text - description shown at the top of the videos page

Features:

  • /peertube page listing the most recent videos from all configured instances, merged and sorted chronologically server-side (via each instance's public API /api/v1/videos?sort=-publishedAt)
  • Clicking a video opens it on its origin instance in a new tab
  • "Live now" section for currently active live streams, plus a fixed in-app red bar "● N live" (60s polling) that links to the videos page
  • PeertubeFetchWorker (Sidekiq, every 5 minutes) + Redis cache + manual refresh button
  • "Video" nav link below Radio, visible to non-logged-in users too
  • Thumbnails are cached locally and served from our own domain through a proxy (/peertube_media), like the Gancio events — avoids hotlink/CSP/mixed-content issues and keeps them working even if the remote instance is slow or down. Only the hosts listed in PEERTUBE_INSTANCES can be proxied, so it cannot be turned into an open proxy.
  • Data exposed via API (/api/v2/instance) for third-party apps

After deploying changes to the PeerTube feature, force a cache refresh so the videos are regenerated with the proxied image URLs:

# Docker (sidekiq or web service)
docker compose exec sidekiq bin/rails runner "Rails.cache.delete('peertube:data'); PeertubeFetchWorker.new.perform"

# Non-Docker
bin/rails runner "Rails.cache.delete('peertube:data'); PeertubeFetchWorker.new.perform"

All Environment Variables

Variable Default Description
NEIGHBORHOOD_TIMELINE_ENABLED false Enable the friendly instances timeline
NEIGHBORHOOD_INSTANCES '' Friendly instance domains, comma-separated
NEIGHBORHOOD_DEBUG false Debug logging for neighborhood
MAX_CHARS 500 Maximum characters per post
AUTO_THREAD_ENABLED false Automatic splitting of long posts into threads
AUTO_THREAD_WARNING '' Warning message shown below Post button during auto-thread
GANCIO_ENABLED false Gancio integration
GANCIO_INSTANCES '' Gancio instances, comma-separated
GANCIO_DESCRIPTION '' Description shown on events page
RADIO_ENABLED false Radio player
RADIO_URL '' Audio stream URL
RADIO_NAME '' Radio name
RADIO_DESCRIPTION '' Description (mouseover / radio page)
RADIO_LINK '' URL opened when clicking radio name
PEERTUBE_ENABLED false PeerTube videos integration
PEERTUBE_INSTANCES '' PeerTube instances, comma-separated
PEERTUBE_DESCRIPTION '' Description shown on the videos page

Compatibility

Bastodon is 100% compatible with Mastodon. All additional features are optional and controlled by environment variables. Without any variables set, the behavior is identical to vanilla Mastodon. Information about active features is exposed in the REST API (/api/v2/instance) to allow third-party apps to adapt.

For the technical guide on porting to new Mastodon branches, see PORTING_GUIDE.md.


What follows is the original Mastodon README.


Features

No vendor lock-in: Fully interoperable with any conforming platform - It doesn't have to be Mastodon; whatever implements ActivityPub is part of the social network! Learn more

Real-time, chronological timeline updates - updates of people you're following appear in real-time in the UI via WebSockets. There's a firehose view as well!

Media attachments like images and short videos - upload and view images and WebM/MP4 videos attached to the updates. Videos with no audio track are treated like GIFs; normal videos loop continuously!

Safety and moderation tools - Mastodon includes private posts, locked accounts, phrase filtering, muting, blocking, and all sorts of other features, along with a reporting and moderation system. Learn more

OAuth2 and a straightforward REST API - Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Streaming APIs. This results in a rich app ecosystem with a lot of choices!

Deployment

Tech stack

  • Ruby on Rails powers the REST API and other web pages
  • React.js and Redux are used for the dynamic parts of the interface
  • Node.js powers the streaming API

Requirements

  • Ruby 3.3+
  • PostgreSQL 14+
  • Redis 7.0+
  • Node.js 22+
  • FFmpeg 5.1+

The repository includes deployment configurations for Docker and docker-compose as well as specific platforms like Heroku, and Scalingo. For Helm charts, reference the mastodon/chart repository. The standalone installation guide is available in the documentation.

Contributing

Mastodon is free, open-source software licensed under AGPLv3.

You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository or translations via Crowdin. To get started, look at the CONTRIBUTING and DEVELOPMENT guides. For changes accepted into Mastodon, you can request to be paid through our OpenCollective.

IRC channel: #mastodon on irc.libera.chat

License

Copyright (c) 2016-2025 Eugen Rochko (+ mastodon authors)

Licensed under GNU Affero General Public License as stated in the LICENSE:

Copyright (c) 2016-2025 Eugen Rochko & other Mastodon contributors

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option) any
later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details.

You should have received a copy of the GNU Affero General Public License along
with this program. If not, see https://www.gnu.org/licenses/