Open-source project
grishka/Smithereen avatar
grishka/Smithereen

Smithereen: a self hosted ActivityPub server with friends, walls and groups

Federated, ActivityPub-compatible social network server with friends, walls, and groups.

548 stars37 forksJavaUnlicense

At a glance

What is it?
Smithereen is a Java server for a federated, ActivityPub compatible social network, and it runs as a small trio of processes: the application, MySQL and imgproxy. The trade is clear: real federation and a first account you create yourself, against a MySQL-only requirement and manual reverse proxy setup.
Who is it for?
Smithereen suits a small group that wants its own fediverse instance with groups and walls rather than a timeline only feed, and it does not suit someone who wants a zero infrastructure hobby server, because it needs MySQL, a reverse proxy and a Java runtime on the same host.
Can I use it commercially?
Yes. Unlicense is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 12 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A social graph with walls and groups, not a timeline

The project description calls Smithereen a federated, ActivityPub compatible social network with friends, walls and groups. Those three nouns define the scope. Friends model the social graph, a wall is per person rather than per post, and groups are containers with their own membership.

That is a different product shape from the microblog servers that dominate the fediverse conversation. A wall is closer to a profile page that accumulates posts, and a group is a room that can be federated with other instances. A person who installs Smithereen is making a statement about the kind of network they want to run rather than picking another frontend for the same protocol.

The repository root tells you the shape of the codebase before you read a line of it. There is FEDERATION.md, which is where the protocol details live, alongside SECURITY.md, an UNLICENSE file, a schema.sql, a pom.xml, a codegen directory, a ci directory and an examples directory holding deployment templates. The presence of a code generation directory and a separate federation document suggests a codebase with generated protocol types and a protocol spec that is documented separately from the user facing guide.

The project also points to an API and federation documentation site, a demo server, and a Telegram chat for questions. The localisation is handled through Crowdin, which tells you the interface is meant to be translated by a community rather than kept in one language by the maintainer.

Three processes have to be running together

Smithereen does not run as a single binary. The deployment templates in the examples directory make the three pieces explicit, and the compose file in the repository root names them.

The application is a Java server that serves the site and speaks ActivityPub. Next to it sits MySQL, which holds the data, with the schema applied from schema.sql at first start. The third piece is imgproxy, a separate image processing service that handles resizing and serving user uploaded pictures.

The split is a deliberate one. Keeping image processing out of the JVM means a separate process can be scaled, restarted and security isolated on its own, and the compose file gives imgproxy its own environment block, including a path prefix of /i and an allowed sources value of local:// so that it can only read from the uploads directory.

The network layout in the compose file reinforces the split. The application and imgproxy sit on an external network where a reverse proxy can reach them, while MySQL sits on an internal network marked internal: true, which means it is not routable from outside the compose project. Only the two public facing services publish ports, and both bind to the loopback interface rather than to all interfaces. The web service publishes 127.0.0.1:4567 and imgproxy publishes 127.0.0.1:4560, so traffic reaches them only through a proxy you control on the host.

The install script expects MySQL, and refuses MariaDB

The recommended path is a release bundle and an install script. The instructions list the prerequisites first: a JRE or JDK 21 or newer, and MySQL. The documentation is unusually firm about the database choice, noting that on Debian the obvious install command installs MariaDB instead, and that MariaDB is known to be incompatible with Smithereen.

That single warning is the most important operational fact in the guide. A Debian or Ubuntu operator who reaches for the default package manager command gets a database that the application is not built against, and the failure will surface later as schema or query behaviour rather than as a friendly startup error.

The installation flow then runs ./install.sh, which asks a few questions to configure the server and create the first account. After that the remaining work is outside the application: a web server has to proxy requests to Smithereen and imgproxy and serve user uploaded files. Example configurations for nginx and Caddy are included in the examples directory, so this is a matter of adapting a template rather than writing one.

The final step of the setup is the admin account. You log into it from a browser and configure the rest of the server settings through the admin interface, which means domain, federation and policy decisions are made after the service is already running.

The compose file exposes two ports and one health check

The Docker route exists and it is not a simplified version of the install. The instructions say to copy the Docker specific config example to the project root as config.properties and edit it to set your domain, then to edit docker-compose.yml to add your imgproxy secrets.

That last point matters more than it sounds. The compose file ships placeholder values for the image proxy key and salt, with a comment in the file itself warning that a mismatch with the application config means you will not be seeing any memes in the newsfeed. The two services agree on a shared secret, and the shipped value is not a secret.

The compose file also shows how the deployment is wired at the container level. The web service runs the published image, mounts the config file, mounts the uploads directory, and declares a dependency on MySQL with the condition that MySQL must be healthy first.

yaml
services:
 web:
  image: grishkaa/smithereen:latest
  ports:
   - '127.0.0.1:4567:4567'
  healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:4567/healthz"]
    start_interval: 1s
    start_period: 20s

The health check hits /healthz on the application port with a start period of twenty seconds, and the MySQL health check pings the server with a longer start period of sixty seconds. Both services declare restart always, and the MySQL data lives in a named volume. Even with containers, the guide still asks you to configure a web server in front, because the compose file binds to loopback on purpose.

Image handling depends on libvips being present

The native image library is the least obvious dependency in the project. The manual install instructions ask you to somehow cause libvips to exist on your system, with three routes: use the copy from a release bundle, download a prebuilt build, or compile it from source using the CI build script. The instructions also warn that not all libvips builds include all the features Smithereen needs.

The container image solves this by compiling libvips in a builder stage and copying the shared objects into the runtime stage.

dockerfile
FROM eclipse-temurin:21-jdk
RUN mkdir -p /opt/smithereen
WORKDIR /opt/smithereen
COPY --from=builder /usr/src/app/target/smithereen.jar /opt/smithereen/smithereen.jar
COPY --from=builder /usr/src/app/target/lib /opt/smithereen/lib
EXPOSE 4567

The runtime stage is a plain Java 21 JDK image rather than a JRE, and the entry point points the JVM at the jar and the lib directory as a module path, with the native library path set so the image library resolves at runtime. The image also writes a small smithereen-init-admin helper script that calls the jar with the init_admin argument, and that is exactly the command the compose instructions tell you to run to create the first account.

For a manual install the same jar and dependency layout is expected on disk, with the jar and a lib directory of dependency jars sitting side by side. The documentation states that the dependencies from target/lib have to be copied as well, which is what makes the build step necessary rather than optional.

Upgrades break if you merge the old and new lib directories

Updating is the part of the project with the sharpest warning. The supported route is to download the new release bundle, unpack it and run ./update.sh, passing the installation directory as an argument if it is not /opt/smithereen.

The manual alternative is spelled out as a sequence of service stops, file copies and service starts.

bash
service smithereen stop
service smithereen_imgproxy stop

The important instruction sits between the two service blocks: copy smithereen.jar, imgproxy, the libvips libraries with their symlinks, and the lib directory over the existing installation, and do not merge the contents of the lib directories from the old and new installs, because the JVM class loader will get angry. Merging is the natural instinct when you copy a directory over another one, and it is the one thing the guide forbids.

Then the services are started again, and the documentation warns that the first startup after an update might take a while because the new version performs database migrations. That is a real operational detail for anyone with an automated restart policy, because a health check that expects a fast response will fire during the migration window.

The release list shows versions 1.0.1, 1.0.2 and 1.0.3, and the last push was on 2026-10-11, so the project is still moving. The UNLICENSE file in the repository root means the code carries no conventional copyright restriction, and the SECURITY.md file indicates that the project expects vulnerability reports.

S3 storage covers uploads but not the media cache

User uploaded media can live in S3 compatible object storage instead of on the local disk, and the switch is a single configuration key.

The property upload.backend=s3 turns it on. The rest are provider specific: upload.s3.region defaults to us-east-1 and is required for AWS, upload.s3.endpoint defaults to s3.<region>.amazonaws.com and is required if you are not on AWS, upload.s3.key_id and upload.s3.secret_key carry the credentials, and upload.s3.bucket names the bucket. Two further settings handle unusual providers, with upload.s3.override_path_style used when a provider requires the bucket name in the hostname rather than in the path, and upload.s3.protocol defaulting to https but accepting http.

A separate group of properties controls the public URLs clients read from. The upload.s3.hostname property defaults to s3-<region>.amazonaws.com. These URLs are what imgproxy uses and what the server hands out when a user clicks Open original in the image viewer.

The limitation is stated plainly: S3 storage applies to user uploaded media files, and not to the media file cache for files downloaded from other servers. So the object store covers what your own users upload, while the cache of remote images remains a local concern.

This is also where the deployment story gets a wrinkle. The documentation says non image attachments such as video will use those public URLs in a future Smithereen version, which is a plan, not a present behaviour, and it means the hostname property needs to be right before that lands.

Where Smithereen is the wrong tool

The clearest case against it is infrastructure. Even the container deployment needs MySQL, needs imgproxy, needs a reverse proxy, and needs a domain with TLS somewhere in front of it. This is a self hosted social network, not a file you can run and forget.

The second case is the database constraint. The MySQL requirement is not a preference you can work around by substituting a compatible engine, because the project states outright that MariaDB is known to be incompatible. If your hosting only offers MariaDB, Smithereen is not a candidate.

The third is scope. The feature set described is friends, walls and groups with ActivityPub federation, and the repository root shows no client applications and no separate moderation tooling, only the web interface that ships with the server. If you want a polished reading experience, the web interface is what you get.

The fourth is the upgrade path. Migrations run on first startup after an update, the lib directory must not be merged between versions, and the release cadence is fast. An operator who wants three month release cycles with long support windows will find the opposite here.

On the other side of the ledger, the licence is the Unlicense, which is about as permissive as software licences get, and the project publishes federation and API documentation separately from the install guide. For a small instance wanting its own corner of the fediverse with groups and walls, that combination is unusual. Most alternatives in the space are single timeline servers.

Editorial conclusion

Smithereen suits a small group that wants its own fediverse instance with groups and walls rather than a timeline only feed, and it does not suit someone who wants a zero infrastructure hobby server, because it needs MySQL, a reverse proxy and a Java runtime on the same host. Before you start, confirm that your distribution gives you real MySQL rather than MariaDB, since the project states MariaDB is known to be incompatible, and read the MySQL and imgproxy notes in the release notes for the version you plan to pin.

Frequently asked questions

What is Smithereen?

It is a Java server for a federated, ActivityPub compatible social network with friends, walls and groups. It ships as a self hosted application with MySQL and imgproxy running alongside it.

How do I install Smithereen on a server?

Install a JRE or JDK 21 or newer plus MySQL, download the prebuilt bundle from the latest release, unpack it and run ./install.sh, then answer the questions to configure the server and create the first account. A web server still has to proxy to Smithereen and imgproxy afterwards.

Can Smithereen run on MariaDB?

No. The documentation states that MariaDB is known to be incompatible with Smithereen, and warns that on Debian the standard package manager command installs MariaDB instead of MySQL.

How do I update Smithereen to a newer version?

Download the new release bundle, unpack it and run ./update.sh, passing the installation directory as an argument if it is not /opt/smithereen. The first startup after an update may take a while because the new version performs database migrations.

Can I store user uploaded media in S3?

Yes, set upload.backend=s3 in config.properties and fill in the region, endpoint, credentials and bucket keys. The S3 backend does not cover the media file cache for files downloaded from other servers.

Official sources

  1. grishka/Smithereen on GitHub
  2. License: Unlicense
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/grishka-smithereen.svg)](https://hysenlabs.com/projects/grishka-smithereen)

Was this useful?