Self-hosted service
NicolasConstant/sengi avatar
NicolasConstant/sengi

Sengi: a multi-account Mastodon and Pleroma desktop client

Mastodon & Pleroma Multi-account Desktop Client

565 stars33 forksTypeScriptAGPL-3.0

At a glance

What is it?
Sengi is a desktop-shaped client for Mastodon and Pleroma that is built around several accounts and one column at a time, in the spirit of the old TweetDeck. It ships as a browser webapp, as a cross-platform desktop application built from a separate Electron repository, and as a Docker image you can self-host with a single command.
Who is it for?
Sengi suits a person who runs several Mastodon or Pleroma accounts and wants them in a single window of columns, or an operator who would rather self-host a read-oriented client than use the interface their server provides.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 133 days ago.
What is it written in?
Mainly TypeScript, 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

Columns for several accounts, the way TweetDeck used to work

Sengi is described in the repository as a Mastodon and Pleroma desktop focused client, and the README is explicit about where the idea comes from: it takes inspiration from the old TweetDeck client, the new TweetDeck webapp and the Mastodon interface.

Three design choices follow from that, and the README lists them as the points it is strongly focused on. It is heavily oriented on multi-account usage, it uses desktop based interactions such as right click and left click, and it displays one column at a time, with the README suggesting you leave it on the side of your screen and keep an eye on it while doing other things.

That third point is the one that makes it a client rather than a page. A single column that stays narrow and sits at the edge of the display is a different object from a responsive full width timeline, and the whole interaction model follows from that: columns rather than a scroll of posts, and mouse actions rather than hover states.

The audience is therefore a specific kind of user. It is somebody with two or more accounts on different instances who wants to read them side by side, and it is somebody who prefers the desktop conventions of a native application to the single account, single column view of a typical timeline. The topics on the repository carry the same message: client, desktop, mastodon, multi-account and pleroma.

The project also explains its own name. A sengi is an elephant shrew from Africa, which is a small animal with a long nose, and the project's mastodon account is at mastodon.social/@sengi_app.

Angular 7, NGXS and a service worker underneath

The dependency list in the package manifest tells you what kind of application this is, and it is a first generation Angular application that has been kept on an older framework line.

The core is Angular 7.2.7 across the usual packages, with the Angular CLI driving the build and the dev server, and Angular Material at 16.2.1 for the component set. State is handled with NGXS, the @ngxs/store package at 3.2.0 and the @ngxs/storage-plugin alongside it, which is the pattern where a Redux-style store keeps the application state and persists part of it.

Around that there are the libraries a social client needs. The emoji picker is @ctrl/ngx-emoji-mart, icons come from the FontAwesome packages for Angular, keyboard shortcuts from angular2-hotkeys, Bootstrap 4 provides utility classes, and the Angular PWA package with its service worker is present, which is what makes the browser build installable and cacheable rather than a plain web page.

Styling is SASS, listed in the README's dependency section, and the source layout follows the Angular convention with src/ for the application and assets/ for static files, plus e2e/ and the karma.conf.js and protractor.conf.js files for the two test layers.

One detail in the manifest is worth noting because it shows where the project has moved. The main field points at main-electron.js, but the README says the Electron code is not hosted here anymore and now lives in a separate sengi-electron repository. The webapp remains here, and the desktop shell has become its own project.

Self-hosting the webapp with one Docker command

The README offers a Docker image for auto-hosting your own Sengi webapp, and the command is short:

bash
docker run -d -p 80:80 nicolasconstant/sengi

That starts the container detached and publishes port 80 on the host, which is the entire install for a self-hosted deployment. More detail is in DOCKER.md in the repository.

The image itself is a static file server, and the Dockerfile shows it in full:

dockerfile
FROM alpine:latest

RUN apk add --update --no-cache lighttpd

ADD lighttpd.conf /etc/lighttpd/lighttpd.conf
COPY /dist /app
COPY /assets/docker_init /app/start

EXPOSE 80

ENTRYPOINT ["lighttpd", "-D"]
CMD ["-f", "/etc/lighttpd/lighttpd.conf"]

The mechanism is deliberately minimal. The build output is copied into the image as /app, lighttpd is installed from the Alpine package manager, and the repository's own lighttpd.conf is dropped in as the server configuration. There is no application server, no runtime configuration and no database, because the client is a static bundle that talks to the instances directly from the browser.

The image also provides a landing page so that you can open a pop-up easily, and the README gives its path as https://your-host/start/index.html, with the start directory coming from the copied /assets/docker_init folder.

For a reader, what you should see after the command is a page on port 80 that lets you start the client, and the client itself once you point it at your instance and sign in.

Building from source with the Angular CLI

The scripts in the package manifest are the developer entry points, and they are the standard Angular set:

json
        "start": "ng serve",
        "start-mem": "node --max_old_space_size=5048 ./node_modules/@angular/cli/bin/ng serve",
        "build": "ng build --prod",
        "test": "ng test",
        "test-nowatch": "ng test --watch=false",
        "lint": "ng lint",
        "e2e": "ng e2e",
        "dist": "npm run build"

A first real use is therefore an ordinary Node and Angular workflow: install the dependencies from the package-lock.json, run npm start to serve the application in development with live reload, and open the local address the CLI prints. npm run build produces the production bundle that the Docker image copies into /app, and npm run dist is the same thing under another name.

The start-mem script is the one worth explaining, because the reason for it is not obvious from the name. It launches the CLI with an increased old space size for the Node process, which is the standard remedy when the Angular compiler runs out of heap during a large build.

The tests come in two flavours and both are wired into the manifest. npm run test runs the unit tests through karma with the watch mode on, and npm run test-nowatch is the same run without it, which is the form you want in continuous integration. npm run e2e drives the Protractor suite in the e2e/ directory. Linting is separate, through ng lint, with the configuration in tslint.json and the editor setup in .vscode/.

Two configuration files sit at the root of the repository, angular.json for the workspace and the build targets, and tsconfig.json for the TypeScript compiler options.

The desktop shell is a separate repository now

The split between the two Sengi repositories is the most significant structural fact about the project, and the README states it in one sentence: the Electron code is not hosted here anymore, and you will find it at the sengi-electron repository.

What that means in practice is that the repository you are looking at is the webapp. It builds a static bundle, it is what the Docker image serves, and it is the part that a contributor can change without touching the desktop packaging. The desktop application for Mac, Windows and Linux is assembled in the other repository, and the two have to be kept in step for a release to be useful in both forms.

The leftover reference in the manifest shows the seam. The package still declares main-electron.js as its main entry, and the version field, 1.9.1, is the version of the client rather than of a wrapper. The version string and the main entry are the two places where the old single-repository layout is still visible, and they are the reason the README tells you where to go for the desktop build rather than describing a packaging step here.

For an adopter, the split is mostly good news, because it means the self-hosted webapp can be updated independently of the desktop release cycle. For a contributor, it means a change to the client has to be made here and then pulled into the Electron project, which is a two step process the README does not spell out.

The project page for Sengi is at nicolasconstant.github.io/sengi/, and the contribution guidelines are in CONTRIBUTING.md, with the credits listed separately in CREDITS.md.

Where Sengi is the wrong tool

There are honest reasons not to use this client, and they come from the dependency choices and the release state rather than from the feature list.

The first is the framework generation. The application is on Angular 7.2 dependencies while its component library is on Angular Material 16.2.1, and Angular 7 dates from 2018. Any developer who wants to contribute to the client today is working with a stack that is far behind current Angular releases, and the mismatch between the core version and the Material version is the kind of thing that produces friction rather than clarity.

The second is the gap between the last release and the last push. The recent releases are 1.9.0 on 2026-02-28, 1.9.1 on 2026-03-11 and 1.8.0 on 2026-02-18, while the last push to the repository was on 2026-06-12. So there is work on master that has not been tagged, and the self-hosted image tracks tagged releases. If you care about a specific account or instance behaviour that was fixed after 1.9.1, the image you run will not have it.

The third is the shape of the interface itself. One column at a time, on the side of the screen, is a deliberate constraint, and a user who wants a full width, feature dense timeline will find it cramped. The README describes the client as Mastodon and Pleroma focused, and the topics list does not mention any other server, so an account on a different implementation of the fediverse protocol is outside what is described here.

The fourth is the licence, and it deserves plain statement rather than interpretation. The project is licensed under the AGPLv3, with the package manifest giving AGPL-3.0-or-later, and the LICENSE file has the details. Running the unmodified image for your own use is one thing, and distributing a modified build is a different matter under those terms, so anyone planning to fork the client should read the licence text and take their own advice on it.

How it differs from letting the server serve the interface

The alternative approach to Sengi is the one most people use by default: the web interface that the instance itself serves, with the account, the timeline and the composing tools handled by the server and delivered as part of it.

The difference in approach is where the code runs and what it shares. A server-provided interface is delivered by the same software that stores your posts, so it tracks whatever that server version supports and it needs nothing installed on your side beyond a browser. Sengi is a client that runs entirely in your browser and talks to the instance through the account API, which means the instance and the client are two separate pieces that can be at different versions, and it means you can host the client yourself and point it at accounts on several instances at once.

That trade is the whole of it. You give up the guarantee that the interface matches the server, and you gain a client you can run on your own hardware, with a multi-account column layout that the server interface does not have to offer.

For the case the README is aimed at, several accounts and a narrow column parked at the edge of the screen, that trade is worth it. For a single account on one instance where you want everything the server offers, the server interface is the simpler path, and there is nothing in Sengi's design that changes that.

Editorial conclusion

Sengi suits a person who runs several Mastodon or Pleroma accounts and wants them in a single window of columns, or an operator who would rather self-host a read-oriented client than use the interface their server provides. It does not suit a developer who wants to build on a current frontend stack, because the application is pinned to Angular 7 dependencies, and it does not suit someone who needs the newest server features, because the newest tagged release is 1.9.1 from 2026-03-11 while the last push to the repository was on 2026-06-12. Check three things before you rely on it: whether the account API behaviour you need is covered by the client rather than the server interface, whether the self-hosted image is updated when the upstream releases are, and whether the AGPL-3.0 terms suit the way you intend to distribute any modified build.

Frequently asked questions

What is Sengi and who is it for?

Sengi is a Mastodon and Pleroma desktop focused client, built around multi-account usage, desktop mouse interactions and a one-column-at-a-time display you can leave at the edge of your screen. It is released as a browser webapp and as a cross-platform desktop application for Mac, Windows and Linux.

How do I run Sengi myself?

The README gives a Docker image for auto-hosting the webapp: docker run -d -p 80:80 nicolasconstant/sengi. The image serves the static build with lighttpd on Alpine and also provides a landing page at https://your-host/start/index.html, with more detail in DOCKER.md.

How do I build Sengi from source?

Install the dependencies from package-lock.json, then use the npm scripts: npm start serves the app with ng serve, npm run build produces the production bundle with ng build --prod, npm run test-nowatch runs the unit tests once, and npm run e2e drives the Protractor suite in the e2e directory.

Where is the Electron desktop version of Sengi?

The README says the Electron code is not hosted in this repository anymore and points to the sengi-electron repository for the cross-platform desktop application. The repository you are in holds the webapp, which is also what the Docker image serves.

What licence is Sengi released under?

The project is licensed under the AGPLv3, and the package manifest declares AGPL-3.0-or-later with the LICENSE file holding the details. The CREDITS.md file lists the contributors and assets.

Official sources

  1. License: AGPL-3.0
  2. NicolasConstant/sengi on GitHub
  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/nicolasconstant-sengi.svg)](https://hysenlabs.com/projects/nicolasconstant-sengi)

Was this useful?