Planet Jabber

February 12, 2026

ProcessOne

Fluux Messenger 0.13.0 - Native TCP Connection & Complete EU Language Coverage

Fluux Messenger 0.13.0 - Native TCP Connection & Complete EU Language Coverage

We&aposre excited to announce Fluux Messenger 0.13.0, featuring native TCP connections, complete European language coverage, and significant performance improvements.

Also, we recently passed the first 100 stars on GitHub. Thank you for your support and for believing in open, sovereign messaging !

Fluux Messenger 0.13.0 - Native TCP Connection & Complete EU Language Coverage

What&aposs New

Native TCP Connection Support on Desktop

Desktop users can now connect directly to XMPP servers via native TCP through our WebSocket proxy implementation. This means lower latency, better reliability, and native protocol handling. No more browser limitations.

We believe that&aposs a nice milestone worth a blog post. Until now, desktop users needed their XMPP server to support WebSocket connections. With v0.13.0, you can connect to any standard XMPP server. We estimate this will enable 80% of users who couldn&apost connect before to finally use Fluux Messenger with their existing servers.

Complete European Union Language Coverage

Fluux Messenger now supports all 26 EU languages, making it truly pan-European. From Bulgarian to Swedish, Croatian to Maltese, we&aposve got you covered. Languages include:

  • Bulgarian, Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, German, Greek, Hungarian, Icelandic, Irish, Italian, Latvian, Lithuanian, Maltese, Norwegian, Polish, Portuguese, Romanian, Slovak, Slovenian, Spanish, Swedish.

Dynamic locale loading means faster initial startup while maintaining comprehensive language support.

If you spot any translation issues, feel free to contribute on our GitHub repository.

Clipboard Image Paste

Paste images directly from your clipboard with Cmd+V (macOS) or Ctrl+V (Windows/Linux). Copy from anywhere, paste into Fluux. It (should) just work ;). Tested and confirmed with Safari&aposs "Copy Image" feature and system clipboard operations so far.

Clear Local Data on Logout

New privacy option to completely clear local data when logging out. Perfect for shared devices or when you need a fresh start.

Performance & Reliability Improvements

  • Smarter Message History Loading - We&aposve completely redesigned our Message Archive Management (MAM) strategy. Message history now loads intelligently based on your scrolling behavior and available data, reducing unnecessary server requests.

  • Better Resource Management - Fixed duplicate avatar fetches when hashes haven&apost changed, reducing bandwidth usage and improving profile picture loading times.

  • Rock-Solid Scroll Behavior - Media loading no longer disrupts your scroll position. The scroll-to-bottom feature now works reliably, even when images and files are loading.

  • Better Windows Tray - Improved tray behavior on Windows for a more native experience.

macOS Sleep Recovery - Fixed layout corruption that could occur after your Mac woke from sleep.

UI & UX Polish

  • Consistent attachment styling across light and dark themes
  • Fixed sidebar switching with Cmd+U keyboard shortcut
  • Improved new message markers - position correctly maintained when switching conversations
  • Better context menus - always stay within viewport bounds, no more cut-off menus
  • Markdown preview accuracy - bold and strikethrough now properly shown in message previews

Linux Packaging

Improved Linux packaging using native distribution tools for better integration with your system package manager.

Developer Experience

Centralized notification state with viewport observer provides better performance and more reliable notification handling across the application.


Get Fluux Messenger

Download for Windows, macOS, or Linux in the latest Release page.

Source code is available at: GitHub


Your messages, your infrastructure : no vendor lock-in.
Sovereign by design. Built in Europe, for everyone.

by Adrien at February 12, 2026 17:39

February 11, 2026

ProcessOne

🚀 ejabberd 26.02

🚀 ejabberd 26.02

Contents:

ChangeLog

  • Fixes issue with adding hats data in presences send by group chats (#4516)
  • Removes mod_muc_occupantid modules, and integrates its functionality directly into mod_muc (#4521)
  • Fixes issue with reset occupant-id values after restart of ejabberd (#4521)
  • Improves handling of mediated group chat invitations in mod_block_stranger (#4523)
  • Properly install mod_invites templates in make install call (#4514)
  • Better errors in mod_invites (#4515)
  • Accessibility improvements in mod_invites (#4524)
  • Improves handling of request with invalid url encoded values in request handled by ejabberd_http
  • Improves handling of invalid responses to disco queries in mod_pubsub_serverinfo
  • Fixes conversion of MUC room configs from ejabberd older than 21.12
  • Fixes to autologin in WebAdmin

If you are upgrading from a previous version, there are no changes in SQL schemas, configuration, API commands or hooks.

Notice that mod_muc now incorporates the feature from mod_muc_occupantid, and that module has been removed. You can remove mod_muc_occupantid in your configuration file as it is unnecessary now, and ejabberd simply ignores it.

Check also the commit log: https://github.com/processone/ejabberd/compare/26.01...26.02

Acknowledgments

We would like to thank the contributions to the source code and translations provided by:

And also to all the people contributing in the ejabberd chatroom, issue tracker...

Improvements in ejabberd Business Edition

Customers of the ejabberd Business Edition, in addition to all those improvements and bugfixes, also get the following change:

  • Change default_ram_db from mnesia to p1db when using p1db cluster_backend

ejabberd 26.02 download & feedback

As usual, the release is tagged in the Git source code repository on GitHub.

The source package and installers are available in ejabberd Downloads page. To check the *.asc signature files, see How to verify ProcessOne downloads integrity.

For convenience, there are alternative download locations like the ejabberd DEB/RPM Packages Repository and the GitHub Release / Tags.

The ecs container image is available in docker.io/ejabberd/ecs and ghcr.io/processone/ecs. The alternative ejabberd container image is available in ghcr.io/processone/ejabberd.

If you consider that you&aposve found a bug, please search or fill a bug report on GitHub Issues.

by JérÎme Sautret at February 11, 2026 10:01

February 08, 2026

Mathieu Pasquet

slixmpp v1.13.2 (and .1)

Version 1.13.0 has shipped with a packaging bug that affects people trying to build wheels using setuptools. 1.13.1 is an attempt to fix that (made packaging from git work somehow), and 1.13.2 is the correct fix thanks to one single additional character.

There are no other changes, and pypi wheels are not affected because they are built in CI with uv.

by mathieui at February 08, 2026 19:02

Sam Whited

DJing for Contra and Lindy

Last month a friend invited me to trade songs with him DJing at an Atlanta Lindy Hop social dance. This was my first time DJing for a social dance other than Contra, and I was surprised by what a different experience it was. To that end, this post will be a mix of post-mortem as I’ve done for contra dances, but also a reflection on the differences between DJing for called and non-called social dances.

Prep

Preparation was the first, and perhaps most obvious, place where the two types of DJing vastly differed.

Preparing for Contra requires hours of sorting new tracks, creating mixes, adding hot cues, fixing beat grids, and analyzing song structure. Once the tracks are all analyzed and annotated, I can then create a playlist of mixes and start practicing them.

For Lindy, on the other hand, I can sit down and prepare a basic set in a few hours right before the dance. Sorting any new tracks still needs to be done, but otherwise I mostly don’t have to do any work other than possibly adding a cue point to let me know where to start a track on the rare version where the beginning doesn’t work (ie. live recordings with lots of chatter or applause before and after), and even that isn’t really necessary.

For Contra I normally make a play list with all my mixes in an order that I think will work well, then shuffle that around on the day of the event depending on the dance picked by the caller. For Lindy I chose to make a crate (which differs from a playlist in that there can’t be duplicate tracks and there is no order to the tracks) instead, pull in about 50 tracks (far more than I’d need, especially when trading songs with another DJ) and largely pull from those just to make selection quicker, while still dipping into the rest of my library on occasion when nothing I’d pre-selected fits the current vibe.

Nerves

When a dancer asks if I get nervous before DJing for contra I confidently say “no”. Not out of some toxic sense of bravado or machismo (I hope), or because I think I’m particularly good at it and don’t need to worry (I’m not, and I do), but because I know I’m going to make mistakes and I’m okay with that.

Instead of being nervous I tend to go into problem solving mode:

  • “How did I get the dancers 8 beats off the phrase?”
  • “Can I jump back to an earlier point in the song to give us more time without it sounding bad?”
  • “I haven’t practiced this mix enough, focus on the cue out point coming up.”
  • etc.

This apparently isn’t the case when I DJ Lindy. The first time, I was immediately a nervous wreck. This is likely particular to me, of course, but it was still an interesting difference that I wasn’t expecting given how much more technically difficult Contra DJing is. I knew intellectually that the technical side of doing a mix (ie. beat matching, harmonic mixing, transitioning between tunes, etc.) isn’t the important part of DJing, the finesse of picking tracks that the crowd will like is what matters. A DJ who just plays a few contra songs, but chooses them well is a much better crowd pleaser than one who does impressive mixing but picks bad songs. However, when it came right down to it I was still surprised by how much more nerve wracking it was when that’s the only thing you’re being judged on.

At some point I remembered that it’s just a dance and if one of them is bad or doesn’t work, we’ll move on and play another song. If I can’t find something, playing something at random is fine too (not ideal, but fine). Once I accepted this I almost immediately started picking songs quicker and not having to rely on picking something random at the last minute after all. It’s much easier to focus on what will be good when you’re not worried about whether it will be perfect. After that we were able to cover for each other and play off each other, and it made the evening much more enjoyable. If one of us killed the floor, the other would try a different style and bring it back. Doug covered for me, and I was even able to cover for Doug once or twice and revive a somewhat empty floor! None of this is something I’d have to deal with in Contra where my mixes are pre-selected, practiced, and where I’m picking from a much smaller selection of tunes.

Playing to the Dancers

While Lindy may not require the technical skills used when mixing tunes in the same way that Contra does, the dancers also aren’t pre-lined-up as they would be with a Contra or Square dance. If you play a tune no one likes at Contra most everyone is stuck with it for 7 minutes or so until the caller wraps up the dance. The dance may fall a part entirely if the tune is too fast or doesn’t have clear enough phrasing for the dancers or caller to follow along, but generally speaking as long as the track sort of works the dancers will dance to it—and they’ll probably enjoy themselves. There are also fewer dances in an evening, so I suspect dancers feel more compelled to dance every single dance.

With Lindy that’s not the case. Many dancers will wait to hear if your track selection is one that they like before venturing out onto the dance floor, and even those that aren’t deliberately checking the music may not be as inclined to break off their conversations with a friend to go ask someone to dance if the track doesn’t immediately catch their interest.

There is also a several minute break between each tune in a contra dance where the caller teaches the next pre-choreographed dance. This means that if two back-to-back mixes have nothing to do with each other, or sound completely different, no one notices as long as you’ve picked a mix that goes well with the dance. Whereas with Lindy only a few seconds elapse between songs, just enough time for someone to thank their partner and go ask the next person to dance. This means that you have to consider the previous track when selecting the next one: a leap from fast balboa to slow blues is going to be jarring for the dancers and they may choose not to dance. Changing the style requires either gradually shifting between the two over several tracks, or maybe giving a slightly longer pause between songs to let the dancers get the previous style out of their ears and bodies.

Similarly there is a big difference in what music really gets the dancers blood pumping, though I suspect this is specific to these two venues and not to the type of social dancing as a whole.

With the contra venue I DJ for it’s mostly a younger crowd and they’re mostly used to hearing a hand full of local old-time string bands and the occasional high energy (but still traditional) New England style dance band. The contra chestnuts are an important part of the dances history, and sometimes you play them, but they don’t get many people excited.

This means that I can do two things if the energy is feeling low: I can play a track by a band they normally wouldn’t be able to hear that’s a bit more modern sounding, or otherwise has something different and interesting about it, or I can mix in a pop tune they’re familiar with. This is almost like a cheat code: if the energy is low, play a song they know and they’ll get excited and raise the energy of the floor.

With Lindy it’s not quite as simple as that. The reliable floor savers for Lindy are mostly old chestnuts by some of the jazz greats. Modern swing is sometimes played, but sparingly, and pop songs are a definite “no”. People come to the dance expecting a certain style, and they’re unhappy if you don’t stick to it. You have to work within the constraints of the genre, and picking floor savers is much more subtle work that requires carefully watching the dancers and seeing what will make them take to the dance floor on any particular night.

The act of watching the floor and adjusting the set as necessary may be obvious to club DJs and other social dance DJs, but to me it was a new experience, and one that I initially found somewhat paralyzing. For the first few tracks, my friend Doug had to cover for me and play as if he were the solo DJ while I flailed trying to find a track that I thought would work. I hadn’t fully internalized until that moment that in a Contra dance the DJ is picking the music to match the dance, but in Lindy Hop the dancers are picking the dance to match the music, and this may include not dancing entirely! I let the perfect become the enemy of the good and Doug had to pick several tracks in a row even though in theory we were trading songs 1 for 1.

Genre and Form

Sometime after the half I had mostly gotten over my nerves, and most of the newbies had drifted off home. I felt more comfortable trying a few experimental tracks that targeted primarily the more experienced late-night crowd: one a fast blues dance recorded at a legendary local Blues club, and the other two folksy tracks by bands that mostly play contra dances.

I was a bit nervous about these tracks as I didn’t know how they’d be received at this particular dance where the DJs play almost exclusively 30s and 40s jazz and the most modern bands that get any air time tend to be emulating the style of the jazz greats. Luckily they all went over well and filled the dance floor! A few people switched to blues dancing for “Sweet Betty”, while others continued with Lindy. Even better, for “Rhinoceros for Sue” the head DJ for the organization (who schedules everyone else, and therefore was the person to try and impress during the evening) went out on the floor to do some Balboa and came over afterwards and asked me what the track was!

I mention this because this is both a similarity and a difference from Contra. Techno-contra1 excluded, I largely can’t play anything for a contra dance that’s not in strict 32-bar “AABB” form. I can layer a modern beat or a pop song over a traditional contra tune, or maybe even find pop tunes that more or less stick to contra form and play it alone, but the form has to be there for the dancers (and some callers) to be comfortable.

With Lindy the freedom to play tracks with a wider variety of forms, so long as they respect the history of the dance, was a nice change of pace. That said, mostly it still needs to have a swung beat and I’m more at the mercy of what the dancers like (which is a narrower subset of music in the Lindy scene in my experience, as previously mentioned), so maybe this is more of a similarity than a difference.

Conclusion

Like learning to dance both lead and follow roles (in Lindy), or from either side of the minor set (in Contra): having done two different forms of DJing will, I suspect, make me a better DJ for either type of dance. I really enjoyed DJing for Lindy and was delighted when the head DJ asked if I’d like to start doing it regularly, hopefully I’ll be able to do it more often going forward!

If you’re curious about the set Doug and I ended up playing, the final set list for the evening can be found on Musicbrainz.


  1. contra set to pop music, often with glow sticks and blacklights. Mostly it has no relation to techno music though some techno may be used. Here the dancers and callers often aren’t expecting strict contra form. ↩

February 08, 2026 12:00

The XMPP Standards Foundation

The XMPP Newsletter January 2026

XMPP Newsletter Banner

XMPP Newsletter Banner

Welcome to the XMPP Newsletter, great to have you here again! This issue covers the month of January 2026.

The XMPP Newsletter is brought to you by the XSF Communication Team.

Just like any other product or project by the XSF, the Newsletter is the result of the voluntary work of its members and contributors. If you are happy with the services and software you may be using, please consider saying thanks or help these projects!

Interested in contributing to the XSF Communication Team? Read more at the bottom.

XSF Announcements

Call for XSF Membership

If you are interested in joining the XMPP Standards Foundation as a member, please apply before February 15th, 2026, 00:00 UTC. Being a member signals a commitment to open standards and professional engagement in / with the XMPP community. Here, your membership helps position the XSF as a healthy organization, which in itself is valuable. It also grants voting rights on technical and administrative matters within the XSF. The application is a light-weight and free of cost process and you can use membership to get more involved more easily, too.

XMPP Summit 28

The XSF held its 28th XMPP Summit during January 29th and 30th 2026 in Brussels (Belgium, Europe). During this two-day gathering, we discussed XMPP protocol development topics and kept making progress on current issues within the protocol and ecosystem. We would like to thank everyone that took part in the Summit for their continuous commitment and contribution to the XSF and all the XMPP related projects!

The XSF would like to extend a special thank you to those who made this XMPP Summit possible:

  • Edward Maurer from the XSF Communication Team as well as Daniel Gultsch and Guus der Kinderen from the XSF Summits, Conferences, and Meetups Team for their time, resources, strong commitment, thorough contribution and attention to detail in the organization and moderation of the event.
  • Ralph Meijer, Dan Caseley and Edwin Mons for their time and dedicated work on streaming the Summit.
  • Ralph Meijer for organising the XSF dinner and Alexander Gnauck’s noted sponsor contribution.
  • Additional thanks to mathieui, RĂ©mi and other unknown people helping to keep track of the notes during the event.
Welcome to the 28th XMPP Summit!

Welcome to the 28th XMPP Summit!

A summary of the main topics discussed is planned to be published soon at xmpp.org.

XMPP at FOSDEM 2026

During January 31st and February 1st, the XSF was present at FOSDEM 26 in Brussels, Belgium. The XMPP community took part in the Realtime Lounge, a room located in Level 1, AW building, together with the Prosody IM and the Snikket projects, where several open source projects around the Decentralised Communication Devroom can present themselves.

We are pleased to say that there was a lot of interaction at the XMPP booth! A rather large number of FOSDEM visitors had the opportunity to come say “Hi!”, meet, interact, talk and have interesting conversations with many of the developers of the most popular clients, servers, tools and libraries that power the whole XMPP ecosystem and bring it to life.

In addition to the activities that took place on the XMPP booth, Daniel Gultsch and S1m, JĂ©rĂŽme Sautret, TimothĂ©e Jaussoin, and Özcan Oğuz hosted four different XMPP related presentations from the Decentralised Communication Developer Room and the FOSS on Mobile track.

You can watch the presentations from the following list of links:

And, of course .. we had plenty of leaflets, informational material, and as always: the coolest stickers! ;)

We found Wally. Now, can you find the XMPP booth in the picture?

We found Wally. Now, can you find the XMPP booth in the picture?

XSF Bluesky account is verified now (New handle!)

The XSF Bluesky account is verified now. This means that the profile handle is different now (@xmpp.org) You can find the profile with its new handle via https://bsky.app/profile/xmpp.org. Many thanks to cal0pteryx from the XSF Communication Team as well as singpolyma and Zash from Infrastructure Team.

Events

XMPP listed as Alternative Chat at DI.DAY Initiative

The German initiative ‘Digital Independence Day’ (DI.DAY) has been kicked off this year to enable users to migrate to open-source software alternatives in various contexts. Besides other services, XMPP is listed as an alternative chat option and XMPP Community members have created so-called switch recipes: Digital Independence Day. Find the related blogpost at xmpp.org

There are more related activities and resources available from the XMPP Community:

XMPP Articles

XMPP Software News

XMPP Clients and Applications

  • Conversations has released versions 2.19.8 and 2.19.9 for Android. These versions introduce a fix for calls getting stuck at connecting when ‘Use Relays’ is enabled but server doesn’t have any. They also come with bandwidth optimizations and they combine QR code related actions (show, scan, invite) into one central menu. You can take a look at the changelog for all the details.
  • Gajim has released versions 2.4.2 and 2.4.3 of its free and fully featured chat app for XMPP. Installing Gajim on macOS is now only a single click away. Gajim 2.4.2 release brings a simplified macOS setup, easier sharing for files and support for link previews, along many other improvements, changes and some important bug fixes. You can take a look at the changelog for all the details.
  • Kaidan has released versions 0.14.0 and 0.15.0 of its user-friendly and modern chat app for XMPP. The former release brings support for advanced media sharing and registration provider filtering, while the latter implements an integrated search field and experimental support for Audio/Video Calls (with most of the work being funded by NLnet via NGI Zero Entrust and NGI Zero Commons Fund with public money provided by the European Commission) in addition to some very useful improvements and lots of fixes! You can find a detailed list of new features, bugfixes and notes in their respective release announcements, or the changelog.
Kaidan 0.15.0: Experimental Audio/Video support on Linux.

Kaidan 0.15.0: Experimental Audio/Video support on Linux.

  • Monal has released versions 6.4.17 for iOS and macOS.
  • Monocles has released version 2.1 of its chat app for Android. This a huge update with three fundamental new features: Stories, Feeds, and Phone log. In addition to many other improvements and features such as account sorting and improved message deletion, this update also brings new support for multiple XEPs. Thanks to the standardization of XMPP, it is now possible to have social interaction across different XMPP platforms and messengers. These new features bring more functions that are fully compatible with the XMPP web platform Movim.
Create your stories today and make a post for your contacts in Monocles Chat or Movim!

Create your stories today and make a post for your contacts in Monocles Chat or Movim!

XMPP Servers

  • Prosody IM is pleased to announce versions 13.0.3 and 13.0.4, both minor releases of the stable branch. The former comes with a range of tweaks, bug fixes and minor improvements, and the latter being the encouraged upgrade, partly due to a bug that was introduced into UUID generation in the previous release. Although not strictly bug fixes, some configuration-related improvements that help make configuring Prosody a little easier and more reliable also made their way into the latest release. Read all the details on the changelog, and as always, detailed download and install instructions are available on the download page for your convenience.
  • MongooseIM has released MongooseIM 6.5: Open for Integration. This release focuses on easier integration with your applications while continuing to deliver a scalable and reliable XMPP-based messaging server. The most important improvement in MongooseIM 6.5.0 is the production-ready integration with RabbitMQ, allowing external services to process the events from the server. It is worth noting that the mechanism is highly extensible – you can craft such extensions yourself.
  • ProcessOne is pleased to announce the release of ejabberd 26.01. This release addresses real operational pain points: export your data from one database backend and import it into another, and roster invites and invite-based account registration to let your users invite others without opening the gates to spam! Make sure to read the changelog for all the details and a complete list of changes, new features, fixes and improvements on this release.

XMPP Libraries & Tools

Extensions and specifications

The XMPP Standards Foundation develops extensions to XMPP in its XEP series in addition to XMPP RFCs. Developers and other standards experts from around the world collaborate on these extensions, developing new specifications for emerging practices, and refining existing ways of doing things. Proposed by anybody, the particularly successful ones end up as Final or Active - depending on their type - while others are carefully archived as Deferred. This life cycle is described in XEP-0001, which contains the formal and canonical definitions for the types, states, and processes. Read more about the standards process. Communication around Standards and Extensions happens in the Standards Mailing List (online archive).

Proposed

The XEP development process starts by writing up an idea and submitting it to the XMPP Editor. Within two weeks, the Council decides whether to accept this proposal as an Experimental XEP.

New

  • No new XEPs this month.

Deferred

If an experimental XEP is not updated for more than twelve months, it will be moved off Experimental to Deferred. If there is another update, it will put the XEP back onto Experimental.

  • No XEPs deferred this month.

Updated

  • Version 1.1.0 of XEP-0386 (Bind 2)
    • It’s authorization-identifier not authorization-identity (dg)

Last Call

Last calls are issued once everyone seems satisfied with the current XEP status. After the Council decides whether the XEP seems ready, the XMPP Editor issues a Last Call for comments. The feedback gathered during the Last Call can help improve the XEP before returning it to the Council for advancement to Stable.

  • No XEPs last calls this month.

Stable

  • No stable XEPs this month.

Deprecated

  • No XEPs deprecated this month.

Rejected

  • No XEPs rejected this month.

Spread the news

Please share the news on other networks:

Subscribe to the monthly XMPP newsletter
Subscribe

Also check out our RSS Feed!

Looking for job offers or want to hire a professional consultant for your XMPP project? Visit our XMPP job board.

Newsletter Contributors & Translations

This is a community effort, and we would like to thank translators for their contributions. Volunteers and more languages are welcome! Translations of the XMPP Newsletter will be released here (with some delay):

  • Contributors:

    • To this issue: emus, cal0pteryx, Gonzalo RaĂșl Nemmi, Ludovic Bocquet, XSF iTeam
  • Translations:

    • French: Adrien Bourmault (neox), alkino, anubis, Arkem, BenoĂźt Sibaud, mathieui, nyco, Pierre Jarillon, Ppjet6, Ysabeau
    • Italian: Mario Sabatino, Roberto Resoli
    • Portuguese: Paulo

Help us to build the newsletter

This XMPP Newsletter is produced collaboratively by the XMPP community. Each month’s newsletter issue is drafted in this simple pad. At the end of each month, the pad’s content is merged into the XSF GitHub repository. We are always happy to welcome contributors. Do not hesitate to join the discussion in our Comm-Team group chat (MUC) and thereby help us sustain this as a community effort. You have a project and want to spread the news? Please consider sharing your news or events here, and promote it to a large audience.

Tasks we do on a regular basis:

  • gathering news in the XMPP universe
  • short summaries of news and events
  • summary of the monthly communication on extensions (XEPs)
  • review of the newsletter draft
  • preparation of media images
  • translations
  • communication via media accounts

Unsubscribe from the XMPP Newsletter

For this newsletter either log in here and unsubscribe or simply send an email to newsletter-leave@xmpp.org. (If you have not previously logged in, you may need to set up an account with the appropriate email address.)

License

This newsletter is published under CC BY-SA license.

February 08, 2026 00:00

The XMPP Newsletter January 2025

XMPP Newsletter Banner

XMPP Newsletter Banner

Welcome to the XMPP Newsletter, great to have you here again! This issue covers the month of January 2025.

The XMPP Newsletter is brought to you by the XSF Communication Team.

Just like any other product or project by the XSF, the Newsletter is the result of the voluntary work of its members and contributors. If you are happy with the services and software you may be using, please consider saying thanks or help these projects!

Interested in contributing to the XSF Communication Team? Read more at the bottom.

XSF Announcements

Call for XSF Membership

If you are interested in joining the XMPP Standards Foundation as a member, please apply before February 15th, 2026, 00:00 UTC. Being a member signals a commitment to open standards and professional engagement in / with the XMPP community. Here, your membership helps position the XSF as a healthy organization, which in itself is valuable. It also grants voting rights on technical and administrative matters within the XSF. The application is a light-weight and free of cost process and you can use membership to get more involved more easily, too.

XMPP Summit 28

The XSF held its 28th XMPP Summit during January 29th and 30th 2026 in Brussels (Belgium, Europe). During this two-day gathering, we discussed XMPP protocol development topics and kept making progress on current issues within the protocol and ecosystem. We would like to thank everyone that took part in the Summit for their continuous commitment and contribution to the XSF and all the XMPP related projects!

The XSF would like to extend a special thank you to those who made this XMPP Summit possible:

  • Edward Maurer from the XSF Communication Team as well as Daniel Gultsch and Guus der Kinderen from the XSF Summits, Conferences, and Meetups Team for their time, resources, strong commitment, thorough contribution and attention to detail in the organization and moderation of the event.
  • Ralph Meijer, Dan Caseley and Edwin Mons for their time and dedicated work on streaming the Summit.
  • Ralph Meijer for organising the XSF dinner and Alexander Gnauck’s noted sponsor contribution.
  • Additional thanks to mathieui, RĂ©mi and other unknown people helping to keep track of the notes during the event.
Welcome to the 28th XMPP Summit!

Welcome to the 28th XMPP Summit!

A summary of the main topics discussed is planned to be published soon at xmpp.org.

XMPP at FOSDEM 2026

During January 31st and February 1st, the XSF was present at FOSDEM 26 in Brussels, Belgium. The XMPP community took part in the Realtime Lounge, a room located in Level 1, AW building, together with the Prosody IM and the Snikket projects, where several open source projects around the Decentralised Communication Devroom can present themselves.

We are pleased to say that there was a lot of interaction at the XMPP booth! A rather large number of FOSDEM visitors had the opportunity to come say “Hi!”, meet, interact, talk and have interesting conversations with many of the developers of the most popular clients, servers, tools and libraries that power the whole XMPP ecosystem and bring it to life.

In addition to the activities that took place on the XMPP booth, Daniel Gultsch and S1m, JĂ©rĂŽme Sautret, TimothĂ©e Jaussoin, and Özcan Oğuz hosted four different XMPP related presentations from the Decentralised Communication Developer Room and the FOSS on Mobile track.

You can watch the presentations from the following list of links:

And, of course .. we had plenty of leaflets, informational material, and as always: the coolest stickers! ;)

We found Wally. Now, can you find the XMPP booth in the picture?

We found Wally. Now, can you find the XMPP booth in the picture?

XSF Bluesky account is verified now (New handle!)

The XSF Bluesky account is verified now. This means that the profile handle is different now (@xmpp.org) You can find the profile with its new handle via https://bsky.app/profile/xmpp.org. Many thanks to cal0pteryx from the XSF Communication Team as well as singpolyma and Zash from Infrastructure Team.

Events

XMPP listed as Alternative Chat at DI.DAY Initiative

The German initiative ‘Digital Independence Day’ (DI.DAY) has been kicked off this year to enable users to migrate to open-source software alternatives in various contexts. Besides other services, XMPP is listed as an alternative chat option and XMPP Community members have created so-called switch recipes: Digital Independence Day. Find the related blogpost at xmpp.org

There are more related activities and resources available from the XMPP Community:

XMPP Articles

XMPP Software News

XMPP Clients and Applications

  • Conversations has released versions 2.19.8 and 2.19.9 for Android. These versions introduce a fix for calls getting stuck at connecting when ‘Use Relays’ is enabled but server doesn’t have any. They also come with bandwidth optimizations and they combine QR code related actions (show, scan, invite) into one central menu. You can take a look at the changelog for all the details.
  • Gajim has released versions 2.4.2 and 2.4.3 of its free and fully featured chat app for XMPP. Installing Gajim on macOS is now only a single click away. Gajim 2.4.2 release brings a simplified macOS setup, easier sharing for files and support for link previews, along many other improvements, changes and some important bug fixes. You can take a look at the changelog for all the details.
  • Kaidan has released versions 0.14.0 and 0.15.0 of its user-friendly and modern chat app for XMPP. The former release brings support for advanced media sharing and registration provider filtering, while the latter implements an integrated search field and experimental support for Audio/Video Calls (with most of the work being funded by NLnet via NGI Zero Entrust and NGI Zero Commons Fund with public money provided by the European Commission) in addition to some very useful improvements and lots of fixes! You can find a detailed list of new features, bugfixes and notes in their respective release announcements, or the changelog.
Kaidan 0.15.0: Experimental Audio/Video support on Linux.

Kaidan 0.15.0: Experimental Audio/Video support on Linux.

  • Monal has released versions 6.4.17 for iOS and macOS.
  • Monocles has released version 2.1 of its chat app for Android. This a huge update with three fundamental new features: Stories, Feeds, and Phone log. In addition to many other improvements and features such as account sorting and improved message deletion, this update also brings new support for multiple XEPs. Thanks to the standardization of XMPP, it is now possible to have social interaction across different XMPP platforms and messengers. These new features bring more functions that are fully compatible with the XMPP web platform Movim.
Create your stories today and make a post for your contacts in Monocles Chat or Movim!

Create your stories today and make a post for your contacts in Monocles Chat or Movim!

XMPP Servers

  • Prosody IM is pleased to announce versions 13.0.3 and 13.0.4, both minor releases of the stable branch. The former comes with a range of tweaks, bug fixes and minor improvements, and the latter being the encouraged upgrade, partly due to a bug that was introduced into UUID generation in the previous release. Although not strictly bug fixes, some configuration-related improvements that help make configuring Prosody a little easier and more reliable also made their way into the latest release. Read all the details on the changelog, and as always, detailed download and install instructions are available on the download page for your convenience.
  • MongooseIM has released MongooseIM 6.5: Open for Integration. This release focuses on easier integration with your applications while continuing to deliver a scalable and reliable XMPP-based messaging server. The most important improvement in MongooseIM 6.5.0 is the production-ready integration with RabbitMQ, allowing external services to process the events from the server. It is worth noting that the mechanism is highly extensible – you can craft such extensions yourself.
  • ProcessOne is pleased to announce the release of ejabberd 26.01. This release addresses real operational pain points: export your data from one database backend and import it into another, and roster invites and invite-based account registration to let your users invite others without opening the gates to spam! Make sure to read the changelog for all the details and a complete list of changes, new features, fixes and improvements on this release.

XMPP Libraries & Tools

Extensions and specifications

The XMPP Standards Foundation develops extensions to XMPP in its XEP series in addition to XMPP RFCs. Developers and other standards experts from around the world collaborate on these extensions, developing new specifications for emerging practices, and refining existing ways of doing things. Proposed by anybody, the particularly successful ones end up as Final or Active - depending on their type - while others are carefully archived as Deferred. This life cycle is described in XEP-0001, which contains the formal and canonical definitions for the types, states, and processes. Read more about the standards process. Communication around Standards and Extensions happens in the Standards Mailing List (online archive).

Proposed

The XEP development process starts by writing up an idea and submitting it to the XMPP Editor. Within two weeks, the Council decides whether to accept this proposal as an Experimental XEP.

New

  • No new XEPs this month.

Deferred

If an experimental XEP is not updated for more than twelve months, it will be moved off Experimental to Deferred. If there is another update, it will put the XEP back onto Experimental.

  • No XEPs deferred this month.

Updated

  • Version 1.1.0 of XEP-0386 (Bind 2)
    • It’s authorization-identifier not authorization-identity (dg)

Last Call

Last calls are issued once everyone seems satisfied with the current XEP status. After the Council decides whether the XEP seems ready, the XMPP Editor issues a Last Call for comments. The feedback gathered during the Last Call can help improve the XEP before returning it to the Council for advancement to Stable.

  • No XEPs last calls this month.

Stable

  • No stable XEPs this month.

Deprecated

  • No XEPs deprecated this month.

Rejected

  • No XEPs rejected this month.

Spread the news

Please share the news on other networks:

Subscribe to the monthly XMPP newsletter
Subscribe

Also check out our RSS Feed!

Looking for job offers or want to hire a professional consultant for your XMPP project? Visit our XMPP job board.

Newsletter Contributors & Translations

This is a community effort, and we would like to thank translators for their contributions. Volunteers and more languages are welcome! Translations of the XMPP Newsletter will be released here (with some delay):

  • Contributors:

    • To this issue: emus, cal0pteryx, Gonzalo RaĂșl Nemmi, XSF iTeam
  • Translations:

    • French: Adrien Bourmault (neox), alkino, anubis, Arkem, BenoĂźt Sibaud, mathieui, nyco, Pierre Jarillon, Ppjet6, Ysabeau
    • Italian: Mario Sabatino, Roberto Resoli
    • Portuguese: Paulo

Help us to build the newsletter

This XMPP Newsletter is produced collaboratively by the XMPP community. Each month’s newsletter issue is drafted in this simple pad. At the end of each month, the pad’s content is merged into the XSF GitHub repository. We are always happy to welcome contributors. Do not hesitate to join the discussion in our Comm-Team group chat (MUC) and thereby help us sustain this as a community effort. You have a project and want to spread the news? Please consider sharing your news or events here, and promote it to a large audience.

Tasks we do on a regular basis:

  • gathering news in the XMPP universe
  • short summaries of news and events
  • summary of the monthly communication on extensions (XEPs)
  • review of the newsletter draft
  • preparation of media images
  • translations
  • communication via media accounts

Unsubscribe from the XMPP Newsletter

For this newsletter either log in here and unsubscribe or simply send an email to newsletter-leave@xmpp.org. (If you have not previously logged in, you may need to set up an account with the appropriate email address.)

License

This newsletter is published under CC BY-SA license.

February 08, 2026 00:00

February 07, 2026

Mathieu Pasquet

slixmpp v1.13

This version fixes a regression in the previous release regarding joining rooms, improves compatibility with the new aiodns releases, and brings a number of other features and fixes.

Thanks to everyone involved (with new contributors) for this release!

Fixes

  • A lot of deprecation warnings for current and future python versions
  • A bug in the JID implementation where bool() would always be true, which would prevent joining rooms with the XEP-0045 plugin
  • Plenty of typos in the documentation and docstrings, thanks to the typos tool
  • Removes most known "unknown stanza interface" messages
  • XEP-0356: Check the correct domain for privileges
  • XEP-0356: Set inner stanza namespace to jabber:client
  • XEP-0363: Do not advertise the httpupload feature by default
  • XEP-0054: Allow datetime.date for birthday info

Doc

  • Improve documentation by adding missing events to the index
  • Fix markup that prevented texinfo documentation generation

Features

  • XEP-0045: New groupchat_affiliation_change for affiliation changes of non-joined JIDs
  • XEP-0363: Give a human readable error message for large files
  • XEP-0421: add optional args to has_feature
  • Stanza objects: Add a get_toplevel_attr to get the xml attributes of the stanza instead of going through the plugin machinery
  • Roster: track pending_in subscription state for clients
  • Add a room_cleanup.py example script

Internal

  • Use of setuptools-scm for release version detection, and new release helper script
  • Integration test for component with CI container
  • CI fixes and tweaks
  • Brings good compatibility with aiodns 4

by mathieui at February 07, 2026 22:32

Prosodical Thoughts

Upcoming changes to Let's Encrypt and how they affect operators

On 11th February, Let’s Encrypt will be rolling out a change to the certificates they issue to servers by default. Although there is generally nothing that Prosody operators need to do, servers using the new certificates may experience problems connecting to some other XMPP servers on the network.

Certificate basics

First, a tiny bit of background on certificates. Certificate Authorities (CAs) such as Let’s Encrypt work by verifying that you own or control a domain, and then they issue you with a certificate that you can present to others as proof of this verification. Obtaining a certificate can be done using the ‘certbot’ tool or any one of the large number of tools compatible with the ACME protocol.

When an XMPP client connects to a server, it will expect the server to present a certificate which is valid for the domain the client is logging in to.

Likewise, certificates are also used when servers connect to other servers (server-to-server connections are often called “s2s” or generally “federation”). This prevents various attacks, including spoofing - because when your server receives a message claiming to be from “user@example.com”, it can ensure that the server it came from presented a valid certificate for “example.com” and has been verified.

Certificates can specify usage

Most people know that certificates contain the domain name that has been verified. However they contain other data too, including the details of the CA that signed and issued the certificate, validity period, and various metadata.

Another part of the certificate can specify limitations on what the certificate can be used for. For example, a CA’s own certificate will specify that they are allowed to use their certificate to sign other certificates. Similar restrictions can be used to permit whether it can be used for signing and/or encryption.

One such extension, called “Extended Key Usage” can be used to restrict whether the certificate is used for “server authentication” or “client authentication”.

What’s changing?

Let’s Encrypt currently issue certificates which specify they may be used for both “server authentication” and “client authentication”. However they have announced that they will be issuing certificates for only “server authentication” by default from 11th February 2026. In the rest of this post we’ll refer to these as “server-only” certificates.

Traditional interpretation of the relevant specifications would forbid use of those certificates by a client which is connecting to a server. Unfortunately, XMPP makes heavy use of connections between servers, and in the context of such server-to-server connections the TLS specifications actually consider the server that initiated the connection to be a “client” (not an XMPP client, but a TLS client).

Common TLS libraries and APIs such as OpenSSL will automatically verify the certificate’s key usage fields, and fail certificate validation if an incoming connection is received that uses a certificate without the “client authentication” purpose. This has the potential to break server-to-server connection authentication in XMPP (and also other protocols that make connections between servers).

Diagram of problematic server-to-server connection

Does this affect Prosody?

Not directly. Let’s Encrypt is not the first CA to issue server-only certificates. Many years ago, we incorporated changes into Prosody which allow server-only certificates to be used for server-to-server connections, regardless of which server started the connection. We believe that this is the correct approach for XMPP.

This means that Prosody will accept connections from servers that are using the new server-only certificates from Let’s Encrypt.

Unfortunately this behaviour is not standardized, partly due to controversy outside the XMPP community about this approach. The current CA ecosystem is heavily driven by web browser vendors (i.e. Google, Apple, Microsoft and Mozilla), and they are increasingly hostile towards non-browser applications using certificates from CAs that they say only provide certificates for consumption by web browsers.

An attempt at updating the specifications to clarify the expected roles of servers and clients failed to gain consensus at the IETF.

Does this affect the XMPP network?

Although Prosody will accept server-only certificates, some other server implementations do not have the alternative certificate usage validation that Prosody has, or they added it only recently.

Compatible servers:

  • ejabberd (requires 25.08 or later)
  • Openfire

Operators of incompatible server versions should upgrade to a version that is compatible with server-only certificates as soon as possible to prevent problems with federation.

Server software not listed above has not been tested, and may not accept connections from servers using server-only certificates.

What will happen with other servers?

If a server does not use the alternative validation (because the software doesn’t implement it, or it has not been updated) then it will treat the certificates of all other servers as invalid for initiating s2s connections.

Many servers still have the dialback protocol enabled, which will act as a fallback authentication mechanism (using DNS), and in this case the connections may still succeed.

However if dialback is disabled on either server, or if the target server strictly requires valid certificates, server-to-server connections will always fail entirely.

You may see errors in your Prosody log file such as:

Server-to-server connection failed: Could not authenticate to remote server

In such a case, the remote server operator usually needs to update their software.

How can I test my server?

Send an XMPP ping (XEP-0199) to le-tlsserver.badxmpp.eu - if you get a successful iq response, this means your server accepts server-only certificates. If you don’t get a response, check your server’s log file for any incoming s2s failures.

by The Prosody Team at February 07, 2026 14:26

February 03, 2026

JMP

Newsletter: Referral Event!

ï»żHi everyone

Welcome to the latest edition of your pseudo-monthly JMP update!

In case it’s been a while since you checked out JMP, here’s a refresher: JMP lets you send and receive text and picture messages (and calls) through a real phone number right from your computer, tablet, phone, or anything else that has a Jabber client.  Among other things, JMP has these features: Your phone number on every device; Multiple phone numbers, one app; Free as in Freedom; Share one number with multiple people.

This month begins JMP’s 2026 referral event! From now until June 1st, everyone you refer to JMP rewards you triple! That’s three free months of service for every person who signs up and pays.

For those who haven’t explored the referral system much, a short refresher on how it works. In your account settings there is a command Refer a friend for free credit. You will be presented with a message that reads like so:

This code will provide credit equivalent to one month of service to anyone after they sign up and pay: CODE These remaining codes are single use and give the person using them a free month of JMP service. You will receive credit equivalent to one month of service after someone uses any of your codes and their payment clears.

When someone uses this code during their signup process with JMP, they will sign up and pay as usual. But after they pay, they will get a free month deposited to their initial balance as well. Once their payment clears (about 90 days for a credit card transaction) your account will also get a month’s worth of credit deposited. Except for referrals which reward during this event, it will be three months! This code is appropriate for publishing publicly and can be used over and over again.

Under this message in the command result is a list of invite codes. If you are out of invite codes, you can always ask JMP support for more as well. These codes are each single-use and give the one person who uses them a free month of JMP service right away. They don’t pay anything. Then, if they pay, and once their payment clears (about 90 days for a credit card transaction) your account will also get a month’s worth of credit deposited. Except for referrals which reward during this event, it will be three months! These codes are appropriate for giving to trusted friends or family members, and each code can only be used once.

To learn what’s happening with JMP between newsletters, here are some ways you can find out:

Thanks for reading and have a wonderful rest of your week!

by Stephen Paul Weber at February 03, 2026 15:21

February 01, 2026

Sam Whited

Contra Vorbis Tags

Introduction

This document defines common Vorbis comments related to Contra, Square and other traditional called folk dances. Their use is also recommended (and identical) in other specifications that re-use Vorbis comments such as OGG/Opus Tag Definitions, and FLAC tags. The same names may be used in other metadata containers such as APE or ID3 but their use in these systems is not defined in this document.

Terminology

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

Namespace

Each tag defined in this document will use the CONTRA: namespace to differentiate it from similar tags that may already exist. This is true regardless of the dance form being used (ie. if the recording is of a square dance, the CONTRA: namespace is still used).

Tags

CONTRA:CALLER
The name of the caller heard in the track for recordings that include calls.
CONTRA:TITLE
The name of the dance in recordings that include calls. For example, “Scrubbies”.
CONTRA:CHOREOGRAPHER
The name of the dance author in recordings that include calls. For example, “David Smukler”. The special value “[traditional]” SHOULD be used for traditional dances where no known choreographer exists. For dances that are a variation on a previous dance the choreographers SHOULD be listed in reverse chronological order, with the author of the variant as the first author.
CONTRA:UNSYNCEDDANCE
The moves of the dance, a single time through, in a plain text format. No exact style is specified but the dance author, choreographer, difficulty, or any callers notes SHOULD NOT be included and should instead be read from the appropriate tags.
CONTRA:NOTES
Any caller or listener provided notes (ie. “Beginner friendly dance” or “When teaching the A1 part, have the Larks cross over first
”, etc.)
CONTRA:ROLES
The role terms used in the dance for recordings that include calls. For example: “Larks/Robins” or “Positional”. No specific format is defined.
CONTRA:LICENSE
Like the LICENSE field defined in vorbis/v-comment, but for the license of the dance instead of the recording.
CONTRA:POTATOES
The number of beats (not bars) of introduction before the first time through the dance begins (whether they are traditional bluegrass-style potatoes or an introductory phrase). This MAY be used in conjunction with CONTRA:START.
CONTRA:START
The start time (in milliseconds) of the first time through the dance (where the dancers would start moving, not where the caller would start calling). This MAY be used in conjunction with CONTRA:POTATOES.
CONTRA:TIMES
The number of complete times through the dance excluding any intros, potatoes, or outros. The exact definition will depend on the type of dance, for contras it should be complete 64 beat (32 bar) phrases.
CONTRA:CROOKED
Whether the dance is crooked (ie. not in perfect dance form) or not. This key MUST always be the value “TRUE” or “FALSE”.

February 01, 2026 14:16

The XMPP Standards Foundation

XMPP listed as Alternative Chat at DI.DAY Initiative

The German initiative ‘Digital Independence Day’ (DI.DAY) has been kicked off this year to enable users to migrate to open-source software alternatives in various contexts. Besides other services, XMPP is listed as an alternative chat option and XMPP Community members have created so-called switch recipes: Digital Independence Day.

The DI.DAY is not a single event, it takes place every first sunday of the month so interested users can switch one service at a time. This initiative shares many values of the XMPP community, such as digital sovereignty and digital privacy. Still, we believe XMPP as standardised technology for realtime communication serves these values best.

Many thanks to the XMPP Community members and beyond for investing their time and efforts to provide all material, namely Axel, Daniel, emus, Ge0rG, padeluun and especially IM from freie-messenger.de! Additional thanks to Digitalcourage and Save Social for sponsoring the handouts for FOSDEM!

Find many other chat apps at xmpp.org!

See you online via XMPP and open-source software!

The XMPP switch recipie handouts infront of the XMPP booth at FOSDEM.

The XMPP switch recipie handouts infront of the XMPP booth at FOSDEM.

February 01, 2026 09:00

January 29, 2026

Kaidan

Kaidan 0.15.0: Audio/Video Calls and Integrated Search Field

Screenshot of Kaidan in widescreen Screenshot of Kaidan

Welcome Kaidan 0.15.0! This release adds experimental support for calls. In addition, it contains some very useful improvements and lots of fixes.

Most of the work has been funded by NLnet via NGI Zero Entrust and NGI Zero Commons Fund with public money provided by the European Commission.

Audio/Video Calls

Kaidan has supported voice and video messages for a long time. Starting with this release, you can even have an audio or video call with a contact! An incoming call is indicated via a notification and you can either accept or reject it.

Please note that there are still some features missing and some setups may not work properly. Especially, calls are only supposed to work on Linux at the moment. But wee wanted to share the current achievements with you to get some feedback! Our goal is to extend the A/V calls functionality and make it available on other operating systems in the future.

Audio/Video calls

Notifications for Group Chat Replies

Formerly, you got a notification if someone mentioned you in a group chat while the corresponding setting was enabled. But you could miss replies to your messages. Kaidan notifies you now on receiving replies as well.

Message Input Field Focusing

In contrast to the soft keyboard on a mobile device, which needs to be opened each time you want to enter something, your keyboard is always reachable on a desktop device. Why not make use of that circumstance? Kaidan ensures that the most relevant message input field stays focused to allow entering text without an additional click into the corresponding field. That way, you can interact smoothly with the user interface and be more productive.

Advanced Message Highlighting

Kaidan 0.14 introduced highlighted messages if you opened their context menu. Messages are now also highlighted while they are being corrected or while you are choosing emojis to react to them. If another message was already highlighted before, that message is highlighted again once you sent the correction/reaction.

Advanced message highlighting

Integrated Search Field

With Kaidan, you can quickly search for chats and messages. But while searching for messages, the opened search bar reduced the space for messages. On mobile devices, the search bar even consumed unnecessary space within the chat list. Both problems are solved now! The search field is integrated into the main toolbar above the messages resp. the chat list. You can even focus each search field via an own keyboard shortcut to directly search without moving the cursor.

Integrated search field

Password Manager Fallback

Since Kaidan’s last version, passwords are stored in a password manager if the system provides one. But there was no fallback yet. It is now possible to use Kaidan even if no password manager is available. In that case, the passwords are stored in an unencrypted file. Once Kaidan detects a password manager on start, the unencrypted passwords are automatically migrated to the password manager.

Changelog

There are several other improvements. Have a look at the following changelog for more details.

Features:

  • Add support for audio/video calls (XEP-0166: Jingle, XEP-0167: Jingle RTP Sessions, XEP-0176: Jingle ICE-UDP Transport Method, XEP-0215: External Service Discovery, XEP-0320: Use of DTLS-SRTP in Jingle Sessions, XEP-0353: Jingle Message Initiation) (@melvo)
  • Show busy indicator while saving captured image/video data (@melvo)
  • Notify on receiving reply to own group chat message if ‘On mention’ notification setting is enabled (@melvo)
  • Select file after opening in folder on Linux if supported (@melvo)
  • Improve media capturing look/behavior (including preview after capturing image until image is saved) (@melvo)
  • Restore focusing of last focused user interface elements (especially message input field) for various use cases (@melvo)
  • Keep message bubble highlighted on reacting/correcting (@melvo)
  • Allow to select message for correction via Ctrl+Up/Ctrl+Down (@melvo)
  • Integrate search field into main toolbar increasing space for messages and, on mobile devices, even for chats in chat list (@melvo)
  • Show message search field via Ctrl+Shift+F (@melvo)
  • Display toolbar buttons on mobile devices exactly as on desktop devices (@melvo)
  • Hide horizontal separator above top-most chat unless chat list is scrolled (@melvo)
  • Store passwords in unencrypted file if no password manager is available or corresponding command-line option provided (@fazevedo)
  • Migrate unencrypted passwords to password manager if available on start (@fazevedo)

Bugfixes:

  • Fix overlapping message bubble tail (@melvo)
  • Fix medium preview hovering if hidden drop area info is hovered (@melvo)
  • Fix updating OMEMO 2 keys for all use cases (@melvo)
  • Fix deadlock on logout during upload of multiple files (@melvo)
  • Fix creating additional database connection on wrong thread (@melvo)
  • Fix sending/resetting whether message is being composed for various corner cases (switching chat, logging out, disabling corresponding setting) (@melvo)
  • Fix updating last message on receiving initial message after setting up existing account in Kaidan for first time (@melvo)
  • Fix resetting draft message after canceling message correction (@melvo)
  • Fix resending failed message reaction (@melvo)
  • Fix selecting previously selected message after changing reactions (@melvo)
  • Fix restoring message highlighting and cancel ongoing correction/reply on removing corresponding message (@melvo)
  • Fix displaying last message sender in chat list after draft message removal (@melvo)

Notes:

  • Kaidan requires Kirigami Addons 1.8 now
  • Kaidan requires QXmpp 1.14 now

Download

Or install Kaidan for your distribution:

Packaging status

January 29, 2026 23:00

January 28, 2026

ProcessOne

Introducing Fluux Messenger: A Modern XMPP Client Born from a Holiday Coding Session

Introducing Fluux Messenger: A Modern XMPP Client Born from a Holiday Coding Session

It was mid-December 2025, just before the Christmas break. My favorite XMPP client had broken on the main branch I was using. Frustrated, rather than waiting for a fix, I decided I wanted to give another try at working on a client. This time, I would be using the opportunity to explore a new set of tools I was curious about: TypeScript, React, and Tauri.

What started as a weekend experiment quickly turned into something more. Using AI tools to accelerate the initial setup, I found myself totally absorbed in the work. Days blurred together as features took shape. By early January, what had been a personal scratch project had become a surprisingly capable desktop client.

When I demonstrated it to my coworkers at ProcessOne, their reaction was unanimous: this was worth pursuing seriously. We decided to put the entire company behind the effort. Today, we&aposre sharing the first public release of Fluux Messenger.

More Than Just Another Chat Client

At ProcessOne, we&aposve spent over two decades building messaging infrastructure. Our XMPP server, ejabberd, has powered some of the world&aposs largest messaging deployments. But we&aposve always approached messaging from the server side. Fluux Messenger represents something new for us, bringing that same engineering philosophy to the client.

The key innovation isn&apost in the UI (though we&aposre proud of it). It&aposs in what lies beneath: the Fluux SDK.

The Fluux SDK: Bridging Two Worlds

Anyone who has built an XMPP client knows the challenge. XMPP is event-driven, signal-based, asynchronous. Modern UI frameworks expect reactive state, typed data, and predictable updates. There&aposs an impedance mismatch between these two worlds.

The Fluux SDK is our answer. It provides a high-level TypeScript API that handles all XMPP complexity internally. Developers work with clean types and reactive state, not XML stanzas. The SDK maintains local cache, manages reconnection, and handles synchronization intelligently. It&aposs not a passive pipe between server and UI; it&aposs an active participant that makes the client easier to develop and more resilient.

As an example, the client is not telling the SDK which presence it wants to publish when stepping away from the computer, but it will signal to the SDK that it is inactive. The SDK is responsible for doing the right thing.

This three-tiered architecture, Server -> Headless client (SDK) -> UI, lets us apply the same design principles that made ejabberd scalable to the client side. Distributed logic, local-first responsiveness, server-side efficiency.

What Fluux Messenger Offers Today

The current release (v0.11.1) already includes substantial functionality:

  • Reliable connection and message management
  • Cross-platform desktop app for Windows, macOS, and Linux, built on Tauri for a lightweight native experience
  • Web version: It works great on the Web as well.
  • 40+ XMPP extensions (XEPs) implemented, including message archive management, multi-user chat, HTTP file upload, message carbons, and reactions
  • MUC support with @mentions notification and bookmarks
  • Local message cache storage using IndexedDB with automatic sync on reconnect
  • Built-in XMPP console for developers and power users who want to see what&aposs happening under the hood
  • Preliminary admin capabilities letting you manage your ejabberd server directly from the client (But this is still mostly a work in progress).
  • 8 languages supported out of the box
  • Light and dark modes with theme system to come
Introducing Fluux Messenger: A Modern XMPP Client Born from a Holiday Coding Session

What I envision for Fluux Messenger is to follow the steps of major projects like Obsidian or VSCode. In my wildest dreams, I expect Fluux Messenger to become as configurable and versatile as those tools.

The Road Ahead

This is an ambitious project. The roadmap stretches far into the future, and we&aposre just getting started. Our plans include mobile support through PWA and eventually native apps, expansion to other frameworks (Vue, Svelte), and Kotlin Multiplatform for Android and iOS.

But ambitious doesn&apost mean closed. Fluux Messenger is open source under AGPL-3.0. We believe that modern, privacy-respecting messaging shouldn&apost require vendor lock-in. Connect to any XMPP server. Host it yourself.

I used AI to bootstrap this project and accelerate my learning phase. Many developers do now. But we are crafters at ProcessOne, and we want to own the responsibility for great code. Those who know me will tell you I&aposll be relentless until I master React and TypeScript, and they know I will. Fast.

A Continuation of ejabberd&aposs Vision

Fluux Messenger represents the client-side continuation of what we started with ejabberd over twenty years ago. The same principles, scalability, reliability, clean architecture, now flow from server to client. If you&aposve trusted ejabberd to power your messaging infrastructure, we hope you&aposll trust Fluux Messenger to be the interface your users deserve.

This is the beginning of an exciting journey. We hope you&aposll join us.


Get started

If you share our vision for clean, reactive messaging APIs, we&aposd love to collaborate. Reach out and let&aposs grow the Fluux community together.

by Mickaël Rémond at January 28, 2026 17:51

January 27, 2026

Snikket

Snikket at FOSDEM 2026

We’re looking forward to meeting new and familiar faces at FOSDEM in Brussels this weekend!

Every February, thousands of developers (and users) of open-source and free (as in freedom) software gather in Brussels to discuss and celebrate our communities, and collaborate and share ideas and projects.

If you are attending, come and find us in the AW building, Level 1. We’ll be sharing the stand with other projects in the XMPP ecosystem and adjacent to other communication projects such as Linphone, Delta Chat and Matrix.

You can bring us questions about Snikket or XMPP, receive help with your own Snikket deployment, or just stop by and say hi!

January 27, 2026 00:00

Prosodical Thoughts

Prosody at FOSDEM 2026

We’re looking forward to meeting new and familiar faces at FOSDEM in Brussels this weekend!

Every February, thousands of developers (and users) of open-source and free (as in freedom) software gather in Brussels to discuss and celebrate our communities, and collaborate and share ideas and projects.

If you are attending, come and find us in the AW building, Level 1. We’ll be sharing the stand with other projects in the XMPP ecosystem and adjacent to other communication projects such as Linphone, Delta Chat and Matrix.

You can bring us questions about Prosody or XMPP, receive help with your own Prosody deployment, or just stop by and say hi!

by The Prosody Team at January 27, 2026 00:00

January 26, 2026

XMPP Providers

Your European Union XMPP Chat Provider!

You can now easily find an XMPP provider based in the European Union (EU)! We have updated our filter options. Previously, you could filter for the server location of an XMPP provider. That filter now allows to select EU-only hosted services.

Try it out! Click the Filter list drop-down menu on the main page.

The location-based filter allows to select the server location.

The location-based filter allows to select the server location.

There are many other properties you can filter for, too. In addition, there is an overview table of providers with column filters and sorting options.

Looking forward to more European Union XMPP chat providers and beyond!

Info: Meet us this week at FOSDEM!

Improve the XMPP experience

For a good user experience, apps integrating XMPP Providers are as important as the providers themselves. If you are an XMPP developer, please consider adding XMPP Providers support to your app. If you are an operator of a public XMPP service, add your service to the list.

You can also consider to run your own XMPP server and become a public provider. With our automated XMPP server setup, you can operate a fully-featured XMPP server with minimal effort.

Feel free to reach out to us if you have any questions! If you like to support XMPP Providers, please consider making a donation. Follow us and spread the word!

XMPP Providers Logo

XMPP Providers Logo

January 26, 2026 00:00

January 23, 2026

Prosodical Thoughts

Prosody 13.0.4 released

We are pleased to announce a new minor release from our stable branch.

Welcome to another minor release from our stable branch!

We encourage any deployments using 13.0.3 to upgrade, partly due to a bug that was introduced into UUID generation in that release. We’re not aware of any direct consequences of this bug, but it may cause compatibility problems with other software.

Although not strictly bug fixes, we sneaked in some configuration-related improvements to this release which help make configuring Prosody a little easier and more reliable. We’re highlighting them because these changes have a chance to impact some rare configurations.

The first change is to prevent mod_pubsub from being loaded on a VirtualHost (easily done if you accidentally add it to your global modules_enabled list). Loading mod_pubsub on a normal user host can lead to unexpected behaviour. Now it will log an error and refuse to load if you do that.

The second change is to simplify configuration of archiving in MUCs. Practically all modern clients now use XEP-0313 to synchronize message history. For VirtualHosts this is implemented in mod_mam, and for MUC components it is implemented in mod_muc_mam. From this release, things get much simpler: loading mod_mam (globally or directly on a MUC component) will automatically load mod_muc_mam on the MUC component. This means most people (e.g. who have mod_mam loaded globally on their server) can now remove “muc_mam” from modules_enabled in their MUC component configuration. It will be loaded automatically.

This last point does mean that if you have mod_mam enabled globally, but do not want it enabled on your MUCs, you now have to state that explicitly by adding “mam” to modules_disabled under the MUC’s Component. Be aware that such a configuration may lead to missing messages in group chats.

A summary of changes in this release:

Fixes and improvements

  • mod_s2s: Fix traceback when outgoing s2s queue is full
  • util.uuid: Fix padding of group 2 of UUIDv7 to use zeroes

Minor changes

  • core.modulemanager: Fix shell commands on components
  • mod_s2s: Explicitly prevent sending recursive error replies when queue is full
  • modulemanager: Allow component modules to specify additional inherited modules
  • prosodyctl check features: Use modulemanager to calculate modules that will actually be loaded
  • prosodyctl check features: change recommendation from mod_muc_mam to mod_mam
  • prosodyctl check config: Fix traceback when zero modules are enabled
  • mod_pubsub: Fail early if loaded outside of a component to prevent misconfiguration
  • doap: Add XEP-0486
  • mod_pubsub/commands: Fix listing item numbers along with item names
  • mod_account_activity: Handle authentication provider returning no user info
  • mod_mam: Automatically load mod_muc_mam if loaded on a MUC component
  • mod_muc: Inherit mod_mam if globally loaded

Download

As usual, download instructions for many platforms can be found on our download page

If you have any questions, comments or other issues with this release, let us know!

by The Prosody Team at January 23, 2026 15:38

January 22, 2026

Snikket

A new look for Snikket Android

We’re sharing a sneak peek at the visual design of the upcoming release of Snikket’s Android app - what we’ve changed, why, and how we got here. The new app will be released on 25th January 2026. To learn more about using Snikket for your communication, check our homepage.


The foundational principles of good user interface design never really change. People should be able to easily find common actions, text should be clear and legible, buttons should be large enough to press, to name a few. But around these pillars, aesthetic conventions are always shifting and evolving.

Image of a button in 2009 version of Android

Android 2009

Image of a button in a 2014 version of Android

Android 2014

Image of a button in a 2026 version of Android

Android 2026

Years ago, square corners used to be lauded as “crisp”. Today, rounded edges are marvellously “smooth”. Where shadows used to add a three-dimensional realism to our interfaces, flat designs are now the norm in most apps.

One of Snikket’s goals is to be approachable and familiar to people who are used to other popular messaging ecosystems. It should be a welcoming gateway to the world of decentralized messaging. This means, where reasonable, keeping up with the conventions established by other widespread communication apps. We can’t stand still.

Snikket’s Android app has been looking increasingly out of place in recent years, compared to the rest of the apps on a typical Android phone. A large reason for this is the shift towards Google’s Material design - the latest design framework that Android uses, and provides to developers, to help with the design, colours, typography and user interface controls in applications.

For the next release, the Snikket app has been updated to Material 3. This is largely thanks to the work done by Daniel on the upstream Conversations app which underlies the Snikket Android app. On top of the work in Conversations, we have put a Snikket spin on the new interface, aligning it with our colours, and making adjustments to various elements to ensure the design feels familiar, friendly and accessible.

An image of the colours in Snikket's new palette, arranged as a grid of 48 coloured squares

A sample of our updated colour palette

While our brand colour remains our iconic yellow, we have designed a new colour palette for this release. This is derived from Material 3 guidelines, with assistance from the ever-helpful folk at Superbloom, plus a custom-built utility to ensure excellent colour contrast across all our new colours and ensure sufficient legibility.

Speaking of colours, the app now also supports “Material You”, which is a feature of modern Android that allows apps to adapt to a user-chosen colour scheme or wallpaper image without sacrificing usability. If enabled in the settings, Snikket will automatically follow your system’s dynamic colour scheme.

A graphic showing multiple overlapping chat bubbles, each in a different light colour, on a white background. The message says 'Game night at mine?'

Chat bubbles can now follow your system theme colours

A graphic showing multiple overlapping chat bubbles, the colours are darker and the background is black. The message says 'Game night at mine?'


in both light and dark mode

Chat bubbles have been given additional space to more clearly separate individual messages, and default font sizes have been slightly increased. These changes were made after carefully reviewing the interfaces of other similar messaging apps. The goal is to allow anyone to feel as “at home” when using Snikket as they would any other app on their device.

Screenshot of Snikket Android app, showing a conversation between two birds, sharing a picture of a blue parrot

The original Snikket Android

Screenshot of the redesigned Snikket Android app, showing a conversation between two birds, sharing a picture of a blue parrot

The new Snikket Android

Snikket continues to follow the system font preferences as in the past, but during our research we found our default font size was slightly smaller than other messaging apps we compared with. Our default size now matches what other similar apps use, and an in-app setting allows you to further boost the font size of messages in case you just need that little bit of extra clarity in your chats.

Three chat bubbles arranged left-to-right, slightly overlapping. The message says 'Yeah!'. The leftmost has the smallest font size, the middle has a slightly larger font size, and the third has a large font size.

Old font size, new size, and optional extra large size

We hope that each aspect of the new design helps people feel even more at home when using Snikket. The new release will be available on the 25th January!

January 22, 2026 00:00

January 21, 2026

ProcessOne

🚀 ejabberd 26.01

🚀 ejabberd 26.01

This release is the result of three months of development, implementing those new features, and fixing bugs.

Release Highlights:

If you are upgrading from a previous version, there are no mandatory changes in SQL schemas, configuration, API commands or hooks. However new mod_invites uses a new table in databases, see below.

Other contents:

Below is a detailed breakdown of the improvements and enhancements:

Database Serialization

This feature adds new way for migrating data between database backends by exporting data from one backend to a file and importing that into different backend (or possibly to same backend but on different machine).

Migrating data using this can be executed by first exporting all data with export_db command, changing configuration of ejabberd and switching modules to use new database backend, and then importing previously exported data using import_db command.

This mechanism works by calling those new command from ejabberdctl, for exporting data:

  • ejabberdctl export_db <host name> <path to directory where exported files should be placed>
  • ejabberdctl export_db_abort <host name>
  • ejabberdctl export_db_status <host name>

and for importing:

  • ejabberdctl import_db <host name> <path to directory with exported data>
  • ejabberdctl import_db_abort <host name>
  • ejabberdclt import_db_status <host name>

Exporting and importing work in background after starting them from ejabberdctl (commands executed by ejabberdctl have time limit for how long they can work, with this setup there should be not issue with export or import getting aborted by that), and current progress of background operation can be tracked by calling corresponding *_db_status command. Operation in progress can be also aborted by executing *_db_abort command.

Roster Invites and Invite-based Account Registration

Until now the canonical method to register an account in ejabberd was to let anybody register accounts using In-Band Registration (IBR) (mod_register) or Web Registration (mod_register_web), and then try to limit abuse with access limitations or CAPTCHAs. Often this process got abused, with the result that account registration had to be disabled and rely on manual registration by administrators.

The new mod_invites implements support for invite-based account registration: administrators can generate invitation URLs, and send them to the desired users (by email or whatever). Then the user that receives an invitation can visit this invitation URL to register a new account.

On top of that, mod_invites lets you create Roster Invites: you can send a link to some other person so they can connect to you in a very user-friendly and intuitive way that doesn&apost require any further interaction. If account creation is allowed, these links will also allow to setup an account in case the recipient doesn&apost have one yet.

Relevant links:

Quick setup:

  1. If using SQL storage for the modules and have disabled the update_sql_schema toplevel option, then create manually the SQL table, see below.

  2. If you plan to use the landing page included with mod_invites, install JavaScript libraries jQuery version 3.7.1 and Bootstrap version 4.6.2. This example configuration will assume they are installed in /usr/share/javascript. The ejabberd container image already includes those libraries. Some quick examples, in case you need some help:

    • Debian and related:

      apt install libjs-jquery libjs-bootstrap4
      
    • AlpineLinux and other operating systems where you can install npm, for example:

      apk -U add --no-cache nodejs npm ca-certificates
      
      npm init -y \
        && npm install --silent jquery@3.7.1 bootstrap@4.6.2
      
      mkdir -p /usr/share/javascript/jquery
      mkdir -p /usr/share/javascript/bootstrap4/{css,js}
      cp node_modules/jquery/dist/jquery.min.js /usr/share/javascript/jquery/
      cp node_modules/bootstrap/dist/css/bootstrap.min.css /usr/share/javascript/bootstrap4/css/
      cp node_modules/bootstrap/dist/js/bootstrap.min.js /usr/share/javascript/bootstrap4/js/
      
    • Generic method using the included script:

      tools/dl_invites_page_deps.sh /usr/share/javascript
      
  3. Configure ejabberd to serve the JavaScript libraries in path /share; serve mod_invites in any path of your selection; and enable mod_invites with some basic options. Remember to setup mod_register to allow registering accounts using mod_invites. For example:

    listen:
      - port: 5443
        ip: "::"
        module: ejabberd_http
        tls: true
        request_handlers:
          /invites: mod_invites
          /share: mod_http_fileserver
    
     modules:
      mod_http_fileserver:
        docroot:
          /share: /usr/share/javascript
      mod_invites:
        access_create_account: configure
        landing_page: auto
      mod_register:
        allow_modules:
          - mod_invites
    
  4. There are many ways to generate invitations:

    • Login with an admin account, then you can execute Ad-Hoc Commands like "Invite User" and "Create Account"
    • If mod_adhoc_api is enabled, you can execute equivalent API Commands generate_invite and generate_invite_with_username
    • Run those API Commands from the command-line, for example: ejabberdctl generate_invite localhost
  5. All those methods give you an invitation URL that you can send it to the desired user, and looks like

    https://localhost:5443/invites/Yrw5nuC1Kpxy9ymbRzmVGzWQ
    
  6. The destination user (or yourself) can visit that invitation URL and follow the instructions to register the account and download a compatible client.

If the user has installed already a compatible XMPP client, you don&apost no need to install JavaScript libraries and setup a landing page. In that case, when generating an invitation you will get only the XMPP URI; when the user opens that URI in a web browser, it will automatically open the XMPP client and the corresponding registration window.

Probably you don&apost want to expose the port directly, then you need to setup Nginx or Apache to act as a "reverse" proxy and change your landing_page parameter accordingly, for example just https://@HOST@/invites/{{ invite.token }}

Notice that the landing page can be fully translated using the existing ejabberd localization feature.

🚀 ejabberd 26.01

SQL table for mod_invites

There is a new table invite_token in SQL schemas, used by the new mod_invites. If you want to use this module, there are two methods to update the SQL schema of your existing database:

If using MySQL or PosgreSQL, you can enable the option update_sql_schema and ejabberd will take care to update the SQL schema when needed: add in your ejabberd configuration file the line update_sql_schema: true

Notice that support for MSSQL in mod_invites has not yet been implemented or tested.

If you are using other database, or prefer to update manually the SQL schema:

  • MySQL singlehost schema:

    CREATE TABLE invite_token (
        token text NOT NULL,
        username text NOT NULL,
        invitee text NOT NULL DEFAULT (&apos&apos),
        created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
        expires timestamp NOT NULL,
        type character(1) NOT NULL,
        account_name text NOT NULL,
        PRIMARY KEY (token(191))
    ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    
    CREATE INDEX i_invite_token_username USING BTREE ON invite_token(username(191));
    
  • MySQL multihost schema:

    CREATE TABLE invite_token (
        token text NOT NULL,
        username text NOT NULL,
        server_host varchar(191) NOT NULL,
        invitee text NOT NULL DEFAULT &apos&apos,
        created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
        expires timestamp NOT NULL,
        type character(1) NOT NULL,
        account_name text NOT NULL,
        PRIMARY KEY (token(191)),
    ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    
    CREATE INDEX i_invite_token_username USING BTREE ON invite_token(username(191));
    
  • PostgreSQL singlehost schema:

    CREATE TABLE invite_token (
        token text NOT NULL,
        username text NOT NULL,
        invitee text NOT NULL DEFAULT &apos&apos,
        created_at timestamp NOT NULL DEFAULT now(),
        expires timestamp NOT NULL,
        "type" character(1) NOT NULL,
        account_name text NOT NULL,
        PRIMARY KEY (token)
    );
    CREATE INDEX i_invite_token_username ON invite_token USING btree (username);
    
  • PostgreSQL multihost schema:

    CREATE TABLE invite_token (
        token text NOT NULL,
        username text NOT NULL,
        server_host text NOT NULL,
        invitee text NOT NULL DEFAULT &apos&apos,
        created_at timestamp NOT NULL DEFAULT now(),
        expires timestamp NOT NULL,
        "type" character(1) NOT NULL,
        account_name text NOT NULL,
        PRIMARY KEY (token)
    );
    
    CREATE INDEX i_invite_token_username_server_host ON invite_token USING btree (username, server_host);
    
  • SQLite singlehost schema:

    CREATE TABLE invite_token (
        token text NOT NULL,
        username text NOT NULL,
        invitee text NOT NULL DEFAULT &apos&apos,
        created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
        expires timestamp NOT NULL,
        type character(1) NOT NULL,
        account_name text NOT NULL,
        PRIMARY KEY (token)
    );
    
    CREATE INDEX i_invite_token_username ON invite_token(username);
    
  • SQLite multihost schema:

    CREATE TABLE invite_token (
        token text NOT NULL,
        username text NOT NULL,
        server_host text NOT NULL,
        invitee text NOT NULL DEFAULT &apos&apos,
        created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
        expires timestamp NOT NULL,
        type character(1) NOT NULL,
        account_name text NOT NULL,
        PRIMARY KEY (token)
    );
    
    CREATE INDEX i_invite_token_username_server_host ON invite_token(username, server_host);
    

New replaced_connection_timeout toplevel option

The new replaced_connection_timeout toplevel option enables new session to wait for termination of session that it replaces.

This should mitigate problems where old session presences unavailable sometimes were delivered after new session sent it&aposs presence available.

Improved mod_http_fileserver docroot option

mod_http_fileserver is a module to serve files from the local disk over HTTP, useful if you just want to serve some HTML or binary files that don&apost need PHP, and don&apost need to setup or configure a separate full-blown web server.

Now the docroot option may be a map of paths to serve, allowing this module to serve several paths with different directories for different purposes.

For example, let&aposs serve some public content from /var/service/www, also shared JavaScript libraries, and for base URL let&aposs serve from /var/www:

listen:
  -
    port: 5280
    module: ejabberd_http
    request_handlers:
      /pub/content: mod_http_fileserver
      /share: mod_http_fileserver
      /: mod_http_fileserver
modules:
  mod_http_fileserver:
    docroot:
      /pub/content: /var/service/www
      /share: /usr/share/javascript
      /: /var/www

Notice that ejabberd includes many modules that serve web services, that may be useful to save you from setting up a full-blown web server, see ejabberd_http.

Supported XEP versions

ejabberd supports close to 90 XMPP extension protocols (XEPs), either directly implemented in ejabberd source code, in the libraries that implement many of the internal features, or in other ejabberd modules available in other repositories like ejabberd-contrib.

Those XEPs are updated regularly to bring major improvements, minor changes, fixing typos, editorial or cosmetic changes... and this requires a regular review of those XEP updates in the software implementations to keep them up to date, or at least to document what exact version of the protocols are implemented.

In this sense, we have reviewed all the XEP versions that ejabberd and erlang xmpp library were not up-to-date, and have identified which ones are already up-to-date in their DOAP files. Now the pages at XMPP.org describe more accurately the supported protocol versions, see ejabberd at XMPP.org and erlang-xmpp at XMPP.org.

Erlang, Elixir and Container

ejabberd can be compiled with Erlang/OTP from 25.0 up to the latest 28.3.1. Regarding Elixir support, ejabberd supports from Elixir 1.14.0 up to the latest 1.19.5

Right now ejabberd compiles correctly with Erlang/OTP from git development branch and Elixir 1.20.0-RC1, so hopefully compatibility with the upcoming Erlang/OTP 29 and Elixir 1.20 will be easily achievable.

Binary installers and the ejabberd container now include Erlang/OTP 28.3.1 instead of 27.3, and Elixir 1.19.5 instead of 1.18.4.

Speaking of the container images, both ejabberd and ecs bring other minor changes: they expose more ports: 5478 UDP (STUN service), 7777 (SOCKS5 file transfer proxy) and 50000-50099 UDP (TURN service).
The container images in their ejabberd.yml file use new macros PORT_TURN_MIN, PORT_TURN_MAX, and STARTTLS_REQUIRED that you can setup easily without modifying ejabberd.yml, see macros in environment.

Improved ERL_DIST_PORT

ejabberd uses Erlang Distribution in the ejabberdctl shell script and also for building a cluster of ejabberd nodes.

That Erlang Distribution has historically used the epmd program to assign listening ports and discover ports of other nodes to connect. The problems of using epmd are that:

  • epmd must be running all the time in order to resolve name queries
  • epmd listens in port 4369
  • the ejabberd node listens in a random port number

How to avoid epmd since Erlang/OTP 23.1 and ejabberd 22.10 ? Simply set the ERL_DIST_PORT environment variable in the ejabberdctl.cfg file:

ERL_DIST_PORT=5210

Since now, ejabberdctl passes arguments to Erlang to listen for erlang distribution connections in TCP port 5210, and establish erlang distribution connections to remote ports 5210. That way you know exactly, in advance, what port number to open in the firewall or container.

This ejabberd release introduces some small improvements that facilitate using the ERL_DIST_PORT environment variable:

  • ejabberdctl prints an informative message when it detects that there may be a port number collision, which may happen if you start several ejabberd nodes in the same machine listening in the same ERL_DIST_PORT and same INET_DIST_INTERFACE.

  • When ejabberd is starting, now it prints the address and port number where it listens for erlang distribution:

    [info] ejabberd 26.01 is started in the node ejabberd@localhost in 1.90s
    [info] Elixir 1.19.4 (compiled with Erlang/OTP 28)
    [info] Erlang/OTP 29 [DEVELOPMENT] [erts-16.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns]
    
    [info] Start accepting TCP connections at 0.0.0.0:5210 for erlang distribution
    [info] Start accepting TCP connections at [::]:5222 for ejabberd_c2s
    [info] Start accepting TCP connections at [::]:5269 for ejabberd_s2s_in
    ...
    
  • A new make relivectl is introduced, which uses ejabberdctl script to start ejabberd (not like make relive), and starts ejabberd immediately without building a release (not like make dev).

  • The ejabberd Documentation site has improved and updated pages about Security, Erlang Distribution, and Clustering.

New make relivectl

make relive was introduced in ejabberd 22.05. It allows to start ejabberd in path _build/relive/ without installing it, by using rebar3 shell and mix run. It automatically compiles code at start and recompiles changed code at runtime. But it doesn&apost use the ejabberdctl script, and doesn&apost read ejabberdctl.cfg, this means that depending on what you are testing, it may not be useful and you had to switch to make dev.

A new make target is now introduced: make relivectl. This is similar, as it starts ejabberd without requiring installation, using path _build/relivectl/ to store the configuration, database and log files. The benefit over relive is that relivectl uses ejabberdctl and reads ejabberdctl.cfg. The drawback is that it doesn&apost recompile code automatically. The benefit over make dev is that relivectl doesn&apost build an OTP release, so it&aposs faster to start.

Let&aposs summarize all the make targets related to installation to determine their usage differences:

make ... install install-rel prod dev relivectl relive
Writes files in path / / _build/
prod/
_build/
dev/
_build/
relivectl/
_build/
relive/
Installs ✅ ✅ manually uncompress *.tar.gz - - -
Uninstall with uninstall
⚠ incomplete
uninstall-rel
✅
manual remove - - -
Start tool ejabberdctl ejabberdctl ejabberdctl ejabberdctl ejabberdctl rebar3/mix
Reads ejabberdctl.cfg ✅ ✅ ✅ ✅ ✅ ❌
Recompiles - ✅ ✅ ✅ ❌ ✅
Starts ejabberd - - - - ✅ ✅
Recompiles at runtime - - - - ❌ ✅
Execution time (s.) 13 40 57 35 4 9

As seen in the table, make install / uninstall seem unnecessary nowadays, because install-rel / uninstall-rel allow to install and uninstall correctly all the files. Maybe in the future the implementation of make install / uninstall could get replaced with make install-rel / uninstall-rel...

In the same sense, make dev now apparently falls short between make prod (which is absolutely indispensable to build a full OTP release) and make relive/relivectl (useful, featureful, and fast for development and testing purposes).

Do you remember that ejabberd 25.07 introduced a link in WebAdmin to the local Converse.js page in the left menu when the corresponding mod_conversejs is enabled?

Technically speaking, until now the WebAdmin menu included a link to the first request_handler with mod_conversejs that the admin configured in ejabberd.yml. That link included the authentication credentials hashed as URI arguments if using HTTPS. Then process/2 extracted those arguments and passed them as autologin options to Converse.

From now, mod_conversejs automatically adds a request_handler nested in WebAdmin subpath. The WebAdmin menu links to that converse URI; this allows to access the HTTP auth credentials, no need to explicitly pass them. process/2 extracts this HTTP auth and passes autologin options to Converse. Now scram password storage is supported too.

In practice, what does all that mean? Just enable the mod_conversejs module, and WebAdmin will have a private Converse URL for the admin, linked in the WebAdmin menu, with autologin. No need to setup a public request_handler!

For example, let&aposs configure conversejs only for admin usage:

listen:
  -
    port: 5443
    module: ejabberd_http
    tls: true
    request_handlers:
      /admin: ejabberd_web_admin
      /ws: ejabberd_http_ws

modules:
  mod_conversejs:
    conversejs_resources: "/home/conversejs/12.0.0/dist"

Of course, you can setup a public request_handler and tell your users to access the corresponding URL:

listen:
  -
    port: 5443
    module: ejabberd_http
    tls: true
    request_handlers:
      /admin: ejabberd_web_admin
      /public/web-client: mod_conversejs
      /ws: ejabberd_http_ws

modules:
  mod_conversejs:
    conversejs_resources: "/home/conversejs/12.0.0/dist"

With that configuration, what is the corresponding URL?

Login to the WebAdmin and look at the left menu: now it displays links to all the configured HTTP services: ejabberd_captcha, ejabberd_oauth, mod_conversejs, mod_http_fileserver, mod_register_web. Also mod_muc_log_http and mod_webpresence from ejabberd-contrib show links in the WebAdmin left menu. Additionally, the menu shows a lock if the page is encrypted HTTPS, and an ! if it is not.

Acknowledgments

We would like to thank the contributions to the source code, documentation, and translation provided for this release by:

And also to all the people contributing in the ejabberd chatroom, issue tracker...

Improvements in ejabberd Business Edition

Customers of the ejabberd Business Edition, in addition to all those improvements and bugfixes, also get the following changes:

  • New module mod_push_gate that can act as target service for mod_push, and which can deliver pushes using configured mod_gcm or mod_applepush instances.
  • New module mod_push_templates that can be used to have different push notifications for message class matching configured data patterns.
  • New database conversion routines targeting p1db backends

ChangeLog

This is a more complete list of changes in this ejabberd release:

Compile and Start

  • Remove dependencies, macros and code for Erlang/OTP older than 25
  • Require Elixir 1.14 or higher, that&aposs the lowest we can test automatically
  • ejabberdctl: Support NetBSD and OpenBSD su (#4320)
  • ejabberdctl.template: Show meaningful error when ERL_DIST_PORT is in use
  • ejabberd_app: Print address and port where listens for erlang node connections
  • Makefile.in: Add make relivectl similar to relive but using ejabberdctl

Databases

  • Add db_serialize support in mnesia modules
  • Add db serialization to mod_muc_sql
  • New database export/import infrastructure
  • Add commands for new database export/import
  • Apply timestamp pass in ?SQL_INSERT queries
  • Update p1_mysql to bring fix for timestamp decoding
  • Extend timestamp type handling in sql macros
  • Revert changes to conversion of pgsql int types

Installer and Container

  • make-binaries: Bump Erlang/OTP 28.3.1 and Elixir 1.19.5
  • Dockerfile: Bump Erlang/OTP 28.3.1 and Elixir 1.19.5
  • Dockerfile: Expose also port 7777 for SOCKS5
  • Dockerfile: Configure TURN ports and expose 5478 50000-50099
  • Dockerfile: Try to fix error with recent freetds Alpine package
  • Container: Setup new macro STARTTLS_REQUIRED to allow easy disabling

MUC

  • Add muc_online_rooms_count API command
  • Set enable_hats room option true by default
  • Allow vcard queries even when IQ queries are disabled (#4489)
  • Announce stable-id feature from XEP-0045 1.31, supported since long ago
  • Fix preload_rooms in case of SQL database (#4476)
  • Run new hooks: registering_nickmuc and registered_nickmuc (#4478)
  • When deleting account, unregister account&aposs nicks in all MUC hosts (#4478)
  • mod_muc_log: Crash in terminate/2 when stopping module (#4486)
  • mod_muc_occupantid: Keep salt per MUC service, not individual rooms
  • mod_muc_room: Rewrite hats code that gets xdata values
  • mod_muc_room: Handle hats without definition (#4503)
  • mod_muc_room: When user has no hats, don&apost store in hats_users

WebAdmin

  • ejabberd_http: Run new http_request_handlers_init fold hook
  • ejabberd_http: Add helper get_auto_urls/2 that returns all URLs and TLS
  • ejabberd_web_admin: Add helper functions make_menu_system
  • ejabberd_web_admin: Show menu system only when can view vhosts
  • ejabberd_web_admin: Pass Level in webadmin_menu_system_post and inside hooks
  • mod_conversejs: Improve link to conversejs in WebAdmin (#4495)
  • When epmd isn&apost running show explanation in Clustering WebAdmin page
  • Use improved WebAdmin menu system in more modules
  • When building WebAdmin menu system, {URLPATH} in link text is substituted

Web Services

  • rest: Use separate httpc profile
  • ejabberd_captcha: Use mod_host_meta:get_auto_url/2
  • ejabberd_http: Support repeated module in request_handlers
  • ejabberd_http: Get back handling when BOSH or WS are disabled
  • mod_host_meta: Move get_url functions from mod_host_meta to ejabberd_http
  • mod_host_meta: Allow calling get_url/2 for other modules, not only WebSocket
  • mod_host_meta: Cosmetic rename Module to Handler
  • mod_http_upload: New content_type option similar to mod_http_fileserver (#4488)
  • mod_http_upload: Pass ServerHost, not Host which may be "upload.HOST"
  • mod_http_upload: Amend the fix for #4450 to support IDNA correctly (#3519)
  • mod_http_fileserver: Support map of paths in docroot option
  • mod_conversejs: Add new Conversejs Paths and ContentTypes (#4511)
  • mod_conversejs: Use ContentType functions from mod_http_fileserver (#4511)
  • Use /websocket URL in default configuration like mod_conversejs, it&aposs more meaningful

Core and Modules

  • Add replaced_connection_timeout toplevel option
  • Fix nasty SSL warnings (#4475)
  • ejabberd_commands: Show meaningul error message when problem executing command (#4506)
  • ejabberd_logger: Append "color clean" only in console template, not file
  • ejabberd_oauth: Log error if oauth_list_tokens executed with unsupported DB (#4506)
  • misc: Get back functions and mark them as deprecated
  • mod_adhoc_api: Show nice command name, as WebAdmin already does
  • mod_pubsub: Deliver pubsub notifications to remote servers for nodes with presence based delivery
  • mod_scram_update: Don&apost hard-code iteration count
  • Bump many XEPs versions that are already supported
  • Improve documentation of install_contrib_modules (#4487)

Full Changelog

https://github.com/processone/ejabberd/compare/25.10...26.01

ejabberd 26.01 download & feedback

As usual, the release is tagged in the Git source code repository on GitHub.

The source package and installers are available in ejabberd Downloads page. To check the *.asc signature files, see How to verify ProcessOne downloads integrity.

For convenience, there are alternative download locations like the ejabberd DEB/RPM Packages Repository and the GitHub Release / Tags.

The ecs container image is available in docker.io/ejabberd/ecs and ghcr.io/processone/ecs. The alternative ejabberd container image is available in ghcr.io/processone/ejabberd.

If you consider that you&aposve found a bug, please search or fill a bug report on GitHub Issues.

by JérÎme Sautret at January 21, 2026 17:50

Ignite Realtime Blog

IgniteRealtime Heads to Brussels: XSF Summit & FOSDEM 2026

I am excited to share that members of the IgniteRealtime community will be heading to Brussels, Belgium, from January 29th to February 1st to take part in two important events for the open-source and real-time communications ecosystem: the annual XSF Summit and FOSDEM.

XSF Summit: Connecting the XMPP community

The XSF Summit, organized by the XMPP Standards Foundation, brings together developers, maintainers, and contributors from across the XMPP ecosystem. IgniteRealtime community members will be there to collaborate with peers, discuss the current state and future direction of XMPP, and share insights from ongoing IgniteRealtime projects.

These face-to-face discussions are invaluable for aligning on standards, exchanging implementation experience, and strengthening the relationships that keep open, decentralized communication thriving.

FOSDEM: Celebrating open source at scale

Following the XSF Summit, our community members will also attend FOSDEM (Free and Open source Software Developers’ European Meeting), one of the largest and most influential open-source conferences in the world.

FOSDEM is a unique opportunity to:

  • Learn about the latest developments across a wide range of open-source technologies
  • Meet contributors and users from diverse projects and communities
  • Represent IgniteRealtime and real-time communication technologies within the broader open-source ecosystem

You’ll likely find us at the XMPP & Realtime Lounge (building AW, level 1).

Meet us in Brussels

If you’re attending the XSF Summit, FOSDEM, or will be in Brussels during this time, we’d love to connect. These events are a great chance to meet fellow IgniteRealtime users and contributors, exchange ideas, and talk about where we’re headed next.

We look forward to productive discussions, new connections, and bringing fresh energy and ideas back to the IgniteRealtime community. See you in Brussels! :belgium:

For other release announcements and news follow us on Mastodon or X

1 post - 1 participant

Read full topic

by guus at January 21, 2026 12:05

The XMPP Standards Foundation

MongooseIM 6.5 - Open for Integration

MongooseIM 6.5: Open for Integration

Our latest release 6.5.0 of MongooseIM focuses on easier integration with your applications while continuing to deliver a scalable and reliable messaging server built on top of the extensible and battle-proven XMPP protocol.

For integration with other services, you can use the Admin or User GraphQL API. Another example is the interaction of MongooseIM with a database. A relational DB such as PostgreSQL, MySQL or CockroachDB can be used to store user accounts, message archives, multi-user chatrooms, publish-subscribe nodes, cluster nodes and much more. Other supported databases and storage services include Cassandra or Elastic Search for message archive, Redis for user sessions and LDAP for authentication.

You can see the complete list in our documentation.

There is another important way to let MongooseIM interact with your distributed system: event pushing. The core of this functionality is the event pusher module, which can push selected events to services like Amazon SNS, RabbitMQ or MongoosePush. In the most recent release 6.5.0, we have improved the event pushing mechanism, focusing on better integration with RabbitMQ.

Event pushing in MongooseIM 6.5.0

The diagram below explains the event pushing architecture in the latest version of MongooseIM:

Events utilize the concept of hooks and handlers. Currently, events are triggered for a few selected hooks, e.g. when a user logs in/out or sends/receives a message. There are almost 140 different hooks defined in MongooseIM though, so there is much room for adding custom events. A module called mod_event_pusher_hook_translator handles the selected hooks, creating events and passing them to the main event pusher API function, mod_event_pusher:push_event/2.

Then, a hook called push_event is triggered, leveraging the hooks-and-handlers mechanism for the second time. This hook is handled by configurable service-specific backend modules, such as:

  • sns – for sending notifications to Amazon SNS,
  • rabbit – for sending notifications to RabbitMQ or CloudAMQP,
  • http – for sending notifications to a custom service,
  • push – for sending push notifications to mobile devices with the help of MongoosePush.

These modules act as interfaces to the corresponding external services. A key feature of this design is its extensibility. For example, one can easily add a kafka backend module that would deliver the events to Apache Kafka as shown on the diagram above.

Push notifications

Let’s focus on the push module as it is a bit more complex. In general, it uses hooks and handlers once again – the push_notifications hook in particular. In order to actually deliver push notifications to a mobile device, a module called mod_push_service_mongoosepush handles that hook by sending the notifications to a separate service called MongoosePush. Finally, MongoosePush will dispatch the notification request and send the notifications to configured services such as APNs or Google FCM.

Each stage of this process is configurable and extensible. Firstly, we have assumed that a virtual pubsub host is used, but there is also an option to use a separate pubsub node for push notifications as described in XEP-0357: Push Notifications, adding another step before running the push_notifications hook. Speaking about that hook, you can implement your own module handling it by calling your own service instead of MongoosePush. Additionally, if you need to extend the notification logic with additional filtering and processing, you can implement a plugin module to mod_event_pusher_push.

Pushing events to RabbitMQ

The RabbitMQ backend module was improved and made production-ready in version 6.5.0, and our full blog post shows how you can easily configure MongooseIM to push events to RabbitMQ - you can literally set up a working dockerized solution in a few minutes.

Summary

The most important improvement in MongooseIM 6.5.0 is the production-ready integration with RabbitMQ, allowing external services to process the events from the server. It is worth noting that the mechanism is highly extensible – you can craft such extensions yourself, but of course don’t hesitate to contact us if you are considering using it in your business – we will be happy to help you install, configure, maintain, and – if necessary – customise it to fit your particular needs. For more information about the latest improvements, see the release notes.

Read about Erlang Solutions as sponsor of the XSF.

January 21, 2026 00:00

January 20, 2026

Erlang Solutions

MongooseIM 6.5: Open for Integration

MongooseIM 6.5: Open for Integration is now available. This release focuses on easier integration with your applications while continuing to deliver a scalable and reliable XMPP-based messaging server.

For such integration, you can use the Admin or User GraphQL API. Another example is the interaction of MongooseIM with a database. A relational DB such as PostgreSQL, MySQL or CockroachDB can be used to store user accounts, message archives, multi-user chatrooms, publish-subscribe nodes, cluster nodes and much more. Other supported databases and storage services include Cassandra or Elastic Search for message archive, Redis for user sessions and LDAP for authentication. 

You can see the complete list in our documentation.
There is another important way to let MongooseIM interact with your distributed system: event pushing. The core of this functionality is the event pusher module, which can push selected events to services like Amazon SNS, RabbitMQ or MongoosePush. In the most recent release 6.5.0, we have improved the event pushing mechanism, focusing on better integration with RabbitMQ.

Event pushing in MongooseIM 6.5.0

The diagram below explains the event pushing architecture in the latest version of MongooseIM:


Events utilize the concept of hooks and handlers. Currently, events are triggered for a few selected hooks, e.g. when a user logs in/out or sends/receives a message. There are almost 140 different hooks defined in MongooseIM though, so there is much room for adding custom events. A module called mod_event_pusher_hook_translator handles the selected hooks, creating events and passing them to the main event pusher API function, mod_event_pusher:push_event/2.

Then, a hook called push_event is triggered, leveraging the hooks-and-handlers mechanism for the second time. This hook is handled by configurable service-specific backend modules, such as:

  • sns – for sending notifications to Amazon SNS,
  • rabbit – for sending notifications to RabbitMQ or CloudAMQP,
  • http – for sending notifications to a custom service,
  • push – for sending push notifications to mobile devices with the help of MongoosePush.

These modules act as interfaces to the corresponding external services. A key feature of this design is its extensibility. For example, one can easily add a kafka backend module that would deliver the events to Apache Kafka as shown on the diagram above.

Push notifications

Let’s focus on the push module as it is a bit more complex. In general, it uses hooks and handlers once again – the push_notifications hook in particular. In order to actually deliver push notifications to a mobile device, a module called mod_push_service_mongoosepush handles that hook by sending the notifications to a separate service called MongoosePush. Finally, MongoosePush will dispatch the notification request and send the notifications to configured services such as APNs or Google FCM.


Each stage of this process is configurable and extensible. Firstly, we have assumed that a virtual pubsub host is used, but there is also an option to use a separate pubsub node for push notifications as described in XEP-0357: Push Notifications, adding another step before running the push_notifications hook. Speaking about that hook, you can implement your own module handling it by calling your own service instead of MongoosePush. Additionally, if you need to extend the notification logic with additional filtering and processing, you can implement a plugin module to mod_event_pusher_push.

Pushing events to RabbitMQ

As the RabbitMQ backend module was improved and made production-ready in version 6.5.0, let’s use it as an example of how you can easily configure MongooseIM to push events to RabbitMQ. The simplest way to demonstrate this is with Docker containers. Firstly, we need a container for RabbitMQ:

docker network create example
docker run --rm -d --network example --name rabbit rabbitmq:management

The management tag is used because we will need the rabbitmqadmin command. The default port 5672 will be used by MongooseIM. The connection is unencrypted for simplicity, but it is recommended to use TLS in a production environment.


As the next step, let’s obtain the default mongooseim.toml configuration file from the MongooseIM 6.5.0 image:

docker create --name mongooseim erlangsolutions/mongooseim:6.5.0
docker cp mongooseim:/usr/lib/mongooseim/etc/mongooseim.toml .
docker rm mongooseim

This default configuration file uses the Mnesia internal database. Although we recommend using CETS and a relational database instead of Mnesia, in this example we will try to keep it as simple as possible – so you only need to add the following to mongooseim.toml:

[outgoing_pools.rabbit.event_pusher]
  connection.host = "rabbit"

[modules.mod_event_pusher.rabbit]
  chat_msg_exchange = {}

The first section configures a pool of connections to RabbitMQ with the default settings, while the second one enables the event pusher module with the rabbit backend, and includes chat_msg_exchange in order to enable the exchange for one-to-one chat messages (called chat_msg by default – see all options). If you are wondering where to add these lines to mongooseim.toml – you can put them anywhere, but it is recommended to group them by section (e.g. outgoing_pools, modules etc.) for readability.

Having the configuration file ready, we can start the MongooseIM container:

docker run --rm -d --network example -e JOIN_CLUSTER=false \
  -v ./mongooseim.toml:/usr/lib/mongooseim/etc/mongooseim.toml \
  --name mongooseim erlangsolutions/mongooseim:6.5.0

After it starts, the chat_msg exchange should be automatically created in RabbitMQ. In order to see its messages, we need to bind a queue to it.

docker exec -it rabbit rabbitmqadmin declare queue --name recv
docker exec -it rabbit rabbitmqadmin declare binding --source chat_msg --destination recv --destination-type queue --routing-key "*.chat_msg_recv"

The routing key *.chat_msg_recv means that only the events for received messages will be routed – in this example we skip all events for sent messages. Now let’s create two user accounts in MongooseIM:

docker exec -it mongooseim mongooseimctl account registerUser --username alice --domain localhost --password secret
docker exec -it mongooseim mongooseimctl account registerUser --username bob --domain localhost --password secret

You should get the “User 
 successfully registered” message for each of them. Next, send the message from alice to bob – we could do that with an XMPP client, but the simplest way here is to use the admin CLI:

docker exec -it mongooseim mongooseimctl stanza sendMessage --from alice@localhost --to bob@localhost --body hello

Now we can check if the message event was sent to our RabbitMQ queue:

docker exec -it rabbit rabbitmqadmin get messages --queue recv

The payload should be:

{"to_user_id": "bob@localhost", "from_user_id": "alice@localhost", "message": "hello"}

This simple example shows how easy it is to extend the functionality of MongooseIM beyond XMPP – as soon as you have the events in a message queue like RabbitMQ, you can perform various actions on them such as calculating statistics for billing purposes, performing analytics or storing them in an external database separate from MongooseIM.

Summary

The most important improvement in MongooseIM 6.5.0 is the production-ready integration with RabbitMQ, allowing external services to process the events from the server. It is worth noting that the mechanism is highly extensible – you can craft such extensions yourself, but of course don’t hesitate to contact us if you are considering using it in your business – we will be happy to help you install, configure, maintain, and – if necessary – customise it to fit your particular needs. For more information about the latest improvements, see the release notes.

The post MongooseIM 6.5: Open for Integration appeared first on Erlang Solutions.

by Pawel Chrzaszcz at January 20, 2026 12:04

January 18, 2026

Sam Whited

2026-01-13 Trolley Barn Contra Post Mortem

On the 13th of January I was invited back to play for the Trolley Barn Contra Dance’s first dance of 2026. For the first time since I’ve been DJing for the Tuesday night dances at the Trolley Barn I was working with a caller (or “callers”, plural, in this case) other than my friend Valerie. I’ve heard Rob and Amanda call plenty of times and even spent some time with them at caller workshops, so we’re not exactly strangers, but I still have much less knowledge of their capabilities, likes, and dislikes than I do with Valerie. This adds a set of complications over working with a close personal friend. The night was a bit rougher, in my estimation, than previous nights when I’ve DJed, and I think a large part of that comes down to how I prepare and work with the caller. This is something I hadn’t considered previously, and something I’m going to have to work on getting better at for future engagements. That said, the evening was still a lot of fun and I think the dancers had a good time.

The Set

The evening started out with “Push the Button” by an unknown choreographer. I used a mix that I had done previously, Basketball / FIDDLE DISCO! by Countercurrent and Elias Alexander. Like last time I let it run a little long before the caller had signaled the end of the song and had to jump around a bit in a way that was a bit jarring.

I was also a little disappointed with the pairing, as I had previously decided to use something else with this dance that I think would have been much more fun. The callers and I had exchanged sets (dances and music) in advance specifically to make the musical pairings for the dance a little better and so that Rob and Amanda could practice to unfamiliar and, sometimes, more challenging music. Unfortunately Rob was having trouble calling to my original medley, and asked me to change it last minute.

I’m not sure that I will share the set this way again, instead I might send callers samples of things I’ve played in the past, ask if they have any requests (if it’s early enough to do so), but otherwise ask to be treated just like a normal band. I may also ask how experienced the caller is and if they’re comfortable calling to music that may not sound like a traditional contra tunes. At the very least, even if I do send someone the set in advance in the future, I will set a hard deadline for when changes can be requested (and it will not be “the night before”).

Next Amanda called “Al’s Safeway Produce” by Robert Cromartie. I tried something that I knew would be a tiny it harder with this one and did a mix of “Morrison’s” and “Quarry Cross”, both by The Gaslight Tinkers. We got a bit off at one point and wound up off the phrase, but Amanda did a great job of continuing to call and I doubt the dancers noticed that they were perpetually 4 bars behind.

Rob was up again next and called “The Nice Combination” by Gene Hubert. I had originally planned a fun and very high energy mix for this dance, but Amanda had vetoed it saying she just didn’t like the music and that it was too difficult to call to. Since this was another last minute change, I swapped in another medley that I had performed previously: Muscles / Garbage in A by Buddy System and Great Bear, respectively. This one I was excited to do again because I had broken it a bit last time, and I felt that it went much smoother this time around.

Next was Amanda calling “Happy Birthday” by Dean Snipes. This dance is fairly smooth so I played Serenity Knoll and Will Drive All Night, both by Buddy System. I screwed up the mix a little bit by leaving loop running after mixing in to Will Drive All Night, so we ended up jumping back to the beginning of the song. What should have been a build up followed by a high energy part of the next tune turned into a jarring leap back to a low energy intro. Nothing really to learn here, mistakes will happen and I’ll just have to practice more next time.

Afterwards Amanda stepped away and forgot to hand the mic to Rob. I covered by playing a waltz (Salish Sea by The Faux Paws) since we were overdue for a waltz break anyways so we took an unintended late break.

Once Rob found the mic he called “Spring Break” by Nils Fredland. I assumed this would be the second to last dance of the evening given how close we were to the end, so I decided to break out the show stopper I had planned even though the transition from slow waltzing to the highest energy tune of the evening felt a bit iffy. The last time I had played my medley of Griffin Road, Trip to Moscow, and Rasputin by Kingfisher and Boney M. I had failed to get a recording of it, so I was excited to have a live recording this time around. Unfortunately, this one ended up falling apart completely.

Despite having practiced it (and it being a very simple mix), I repeatedly screwed up and am still not entirely sure what I did. Whether it was me getting off during the initial mix in of Rasputin, or me breaking the beat and the phrasing trying to fix it, or me letting it get way too fast to dance to at a point in the song when I should have been riding the tempo, it was just a mess. The dancers got off the music, Rob got off in his calling, and eventually he just decided to end it early while I was still scrambling to get the song under control.

I don’t have much to say about this one other than it kind of killed the energy of the evening and was entirely my fault. Sorry Rob (and dancers)!

Amanda was up again and called “The Eyes Have It” by Becky Hill. This dance is another smoother one, and (if I hadn’t killed the energy on the last one) I had planned to bring the energy down just a touch after the show stopper, so I did a mix of “Waiting for Earl / Calamity” both by Elixir.

Finally, Rob ended the evening with “Simplicity Swing” by Becky Hill. Since I’d just done a low energy dance, relaxing dance, I wanted to bring it back up again so I did Devil / The Druid by Countercurrent. This one did okay, except that Rob and I had a miscommunication about how many times through were remaining and it ended up going a bit long. I’m not sure if it was bad communication on Rob’s part or me just being tired and misunderstanding, so chalk this one up to the night just being full of mistakes and move on. In the end it didn’t really sound bad, it just meant we looped a particular section one or two more times than I would have liked and it got a bit repetitive towards the end.

Sadly, we were way over time at this point and had no time for the traditional closing waltz.

Lesson’s Learned

The main thing I learned from this evening was that I need to have a list of things to discuss with callers up front when I’m working with them for the first time. In the future when working with a caller that I haven’t worked with before I think I’ll do the following:

  • Don’t send a set list or practice recordings in advance, only sample recordings from past events.
  • Ask if the caller is comfortable calling “off phrase”, and ask how they stay on phrase as a caller (by listening for phrasing, counting beats, a mix of both, etc.)
  • Ask about the types of dances they do (all 32-bar contras? Triplets in A.B.C. form, etc.)
  • Any special requests? It’s also important to make it clear that requests are fine (from the caller, not the dancers) but that they may or may not be able to be honored and there is a hard cutoff beyond which I will be practicing and unwilling to make changes.
  • Ask them to always give at least 3x through before ending the dance if possible (sometimes there will be emergencies where this can’t happen, that’s fine).
  • Ask how they do calling over lyrics or if they expect to drop out on most songs.
  • Make sure they know that some songs will be non-traditional.
  • Ask them how long they like to run dances in this hall (if they’ve called there before).

This is almost certainly an incomplete list, and if any other called social dance DJs want to chime in I’d love to know what you do when working with a caller.

This got me thinking about how I interface with the sound folks / organizers too. A few things I should have a chat about with them include:

  • Do you prefer that I run sound off my board, or do you have someone who will run sound?
  • Ask if the sound person can record the evening or has an extra place to plug up a multi-track recorder (and check if it’s digital, XLR, pre or post mix, etc.)
  • Ask if they have a position in mind for the DJ in the hall and is it near the caller (preferably in the center with visibility across all lines)?
  • Any obstructions in the hall that will mess with sound?
  • And of course give them my own requirements: 3 power outlets, monitor speaker with 1/4" TRS input, 1 XLR mono input to whatever board they’re using, a mic that doesn’t require phantom power if I’m running sound.

I haven’t run into problems with this yet since I only DJ for a single dance/venue, but it’s worth thinking about. Again, I’d be curious to get other social dance DJs (called or no) opinions on this list; I’m sure I’m missing something important.

Conclusion

Something that I didn’t mention in my thinking about what went wrong above is that the “energy” of the evening felt off almost from the very beginning. None of my song choices were landing the way I wanted them to, I had to shuffle some around in ways where I didn’t really feel like they flowed from one dance to the next, and the dancers in general just didn’t seem as excited as they normally would be.

I felt a bit bummed afterwards, but it’s also important to remember that it really doesn’t matter. At the end of the day, even if the event wasn’t as good as it could have been, dancers still showed up and had a good time. There were still a ton of smiling faces, friends catching up between songs, chatting, and general merriment even if there were some problems. So give yourself a break and do better next time, me.

January 18, 2026 14:55

The XMPP Standards Foundation

XMPP at FOSDEM 2026 UPDATE!

The XMPP Community is very excited to announce its presence at the coming FOSDEM 2026!

Once again, many members of the XMPP community will be attending, and will happily welcome you!

Realtime Lounge: UPDATE!

The XMPP community invites you to the join the Realtime Lounge, where you can come and meet community members, project developers, see demos and ask all the questions.

This year the XMPP & Realtime Lounge has been reallocated to the AW building, Level 1.

Map of the AW building, Level 1

Map of the AW building, Level 1

Decentralized Communication Devroom

We would like to invite you to join the technical talks around decentralised communication. There will also be talks on various messaging and Real-time communication (RTC) projects such as ActivityPub, ATProto, Automerge, DeltaChat, Matrix and of course XMPP in the Decentralised Communication developer room.

Talks

These are the XMPP related talks that will take place on the Decentralised Communication track. These talks will take place in room AW1.126 on Sunday, January 31st, 2026. You can also join the conversation or watch the live videos at aw1126.

  • Engineering XMPP Federation: Building Messaging, Voice & Social Features Across Independent Projects: The XSF is a standards body that sits at the core of a development ecosystem of independent implementations by different individuals and organizations that actually work together, all highly interoperable, shipping new features at a high pace. This talk, by JĂ©rĂŽme Sautret will share how things work at this scale and will be co-presented by a server and client developer, showing how they work together to fine-tune their implementations. This talk starts at 13:15 and ends at 13:45 hs. (UTC+1:00)
  • Movim: Building a Decentralized Social Network on XMPP: In this talk, TimothĂ©e Jaussoin will present how Movim leverages the XMPP standard and its extensions to deliver features users expect from modern social platforms (communities, IM, group chats, video calls, blogging and a complete publishing platform into a unified experience), without giving up your data to a centralized platform, while remaining fully federated, interoperable with other XMPP clients like Conversations and Dino, and capable of bridging to centralized platforms like Discord, Telegram, and WhatsApp!. This talk starts at 13:45 and ends at 14:15 hs. (UTC+1:00)
  • What are you listening to now?: Implementing “Now Playing” feature in modern XMPP: In this talk, Özcan Oğuz will share the journey on his research on implementing this feature in modern XMPP clients, the protocols of certain operating systems to read the currently playing media, the current status of the support of XEP-0118 (User Tune) and the PoC of a modern “Now Playing” feature. This talk starts at 14:15 and ends at 14:45 hs. (UTC+1:00)

What to expect

  • The chance to meet and engange in face to face conversations with the developers of the XMPP client that you use, the server that you may be selfhosting, the libraries and/or tools that you may be using in your project.
  • Promotional and informational material: XMPP 2025 highlight Flyers, DI.DAY for XMPP Flyer 

  • Free candy!
  • And .. say what? Sticker? You are in for a treat! XMPP logo stickers, OMEMO, Movim, Dino, Monocles Chat, Conversations IM, Libervia, 
 you name it! ( And who knows? Maybe somebody will even be there presenting the new mascot for their project!! ).

Don’t forget to come by our stand, please believe us: you really won’t want to miss it!

Info & Dates

When? 31st January + 1st February 2026
Where? ULB, Campus du Solbosch, Av. F. D. Roosevelt 50, 1050 Bruxelles, Belgium
Where exactly? AW building, Level 1
Contact XMPP Community chats & XMPP Community mailing lists

XMPP Summit 28 prior to FOSDEM 2026

Prior to FOSDEM, the XSF will also traditionally hold its 28th XMPP summit. This is where community members gather to discuss protocol changes and the XMPP roadmap. Everyone is welcome to join, just kindly list yourself free of cost as there is only limited space. Please make yourself known by filling out your details on the wiki page for Summit 28. Check the official online presence and communication, too (see the media links in the footer).

Looking forward to see you there!

Spread the word 📱

January 18, 2026 00:00

January 13, 2026

Erlang Solutions

The Always-On Economy: Fintech as Critical Infrastructure

​​We are living in an economy that rarely sleeps. Payments clear late at night. Payroll runs in the background. Businesses expect every digital touchpoint to work when they need it.

Most people do not think about this shift. They assume the systems behind it will hold.

That assumption carries weight.

Fintechs, including small and mid-sized ones, now sit inside the basic infrastructure of how money moves. Their uptime affects cash flow. Their stability affects trust. When something breaks, real businesses feel it immediately.

Expectations changed faster than most systems did.This follows on from our earlier piece, From Prototype to Production, which explored how early technical shortcuts surface as systems scale. Here, we look at what happens next, when those systems become part of the infrastructure businesses rely on every day.

When “tech downtime” becomes infrastructure failure

Outages no longer feel contained. A single failure can affect services that millions of people and businesses depend on.

Large providers experience this as much as small ones. When a shared platform falters, the impact spreads quickly. More than 60 percent of outages now come from third-party providers rather than internal systems, highlighting how tightly connected the ecosystem has become.

The true cost is trust

For fintechs, the impact is immediate because money is involved.

A payment delay blocks cash flow. A failed identity check stops onboarding. A stalled platform damages credibility.

For an SME, this can play out over the course of a single day. Payroll does not process in the morning. Supplier payments stall in the afternoon. Customer support queues fill up while teams wait for systems to recover. Even short interruptions create knock-on effects that last far longer than the outage itself.

And the numbers reflect that risk:

  • ÂŁ25,000 is the average cost of downtime for SMEs.
  • 40% of customers consider switching providers after a single outage.
  • Fintech revenue losses account for approximately US$37 million of downtime-related costs each year.

At this level of dependency, downtime stops being a technical issue. It becomes an infrastructure failure.

Fintechs have become infrastructure whether they intended to or not

Fintech services have moved beyond convenience. They now underpin everyday economic activity for businesses that depend on constant access to money, credit, and financial data.

This shift shows up in uptime expectations. Platforms that handle financial activity are measured against standards once reserved for mission-critical systems. Even brief disruption can have outsized consequences when services are expected to remain available throughout the day..

Customers do not adjust expectations based on company size or stage. If money flows through a service, users expect it to be available around the clock. When it is not, the failure feels systemic rather than technical. What breaks is not just functionality, but confidence.

That is the environment fintech leaders are operating in now.

Where resilience typically breaks down

Most fintech systems do not fail because the idea was weak. They fail because early decisions prioritised speed over durability.

Teams optimise for launch. They prove demand. They ship quickly. That works early on, but systems designed for experimentation often struggle once demand becomes constant rather than occasional.

Shortcuts that felt harmless early on start to surface under pressure. Shared components become bottlenecks. Manual processes turn into operational risk. Integrations that worked at low volume become fragile at scale. Recent analysis shows average API uptime has fallen year over year, adding more than 18 hours of downtime annually for systems dependent on third-party APIs.
 

Common pressure points include:

  • Shared components that act as single points of failure
  • Manual operational work that cannot keep up with growth
  • Third-party dependencies with limited visibility or control
  • Architecture built for bursts of usage instead of continuous demand

These are not accidental outcomes. They are the result of trade-offs made under pressure. Funding milestones, launch timelines, and growth targets shape architecture as much as technical skill does.

When outages happen, they rarely trace back to a single bug. They trace back to earlier choices about what mattered and what could wait.

From product thinking to infrastructure grade systems

Product thinking is about features and speed. Infrastructure thinking is about continuity.

Infrastructure-grade systems assume failure will happen. They are built to contain it, recover quickly, and keep the wider platform running. The goal is not perfection. The goal is staying available.

The goal is not perfection. The goal is staying available.

Continuous availability is now expected in financial services. Systems are updated and maintained without noticeable downtime because users do not tolerate interruptions when money is involved.

This approach does not slow teams down. It reduces risk. Deployments feel routine instead of stressful. Engineering effort shifts away from incident response and toward steady improvement.

Over time, this changes how organisations operate. Teams plan differently. Roadmaps become more realistic. Reliability becomes part of delivery rather than a separate concern.

Elixir and the always-on economy

Elixir programming language is designed for systems that are expected to stay available. It runs on the BEAM virtual machine, which was built in environments where downtime carried real consequences.

That background shows up in how Elixir applications are structured. Systems are composed of many small, isolated processes rather than large, tightly coupled components. When something fails, it fails locally. Recovery is expected. The wider system continues to operate.

Elixir in Fintech

This matters in fintech, where failure is inevitable and interruptions are costly. External services misbehave. Load changes without warning. Elixir applications are built to absorb those conditions and recover quickly without cascading outages.

Teams working in Elixir tend to spend less time managing fragile behaviour and more time improving core functionality. Systems evolve instead of being replaced. Reliability becomes part of the foundation rather than a promise teams struggle to maintain.

For fintechs operating in an always-on economy, that approach aligns with the expectations already placed on them.

Reliability as a competitive advantage

Reliable systems can completely change how a fintech operates day to day.

For growing fintechs, uptime supports trust and regulatory confidence. Customers stay because the platform behaves predictably. Growth becomes steadier because teams are not constantly reacting to incidents. Downtime costs make this real, especially for small businesses that lose revenue when systems are unavailable.

For larger providers, reliability reduces operational strain. Fewer incidents mean fewer emergency fixes and fewer difficult conversations with partners and regulators. Teams spend more time improving core services and less time managing fallout.

Reliability also shapes perception. Platforms that stay up become easier to trust with deeper integrations and higher volumes. Over time, that trust compounds and turns stability into a real advantage, even if it is rarely visible from the outside.

To conclude

The always-on economy creates real opportunity for fintechs, but it also raises expectations that many platforms were not originally built to meet.

The question is whether your system has the resilience to operate as infrastructure day after day. If you are a fintech and want to build with reliability in mind, get in touch.

Designing for resilience early makes it far easier to scale without introducing fragility later on.


The post The Always-On Economy: Fintech as Critical Infrastructure appeared first on Erlang Solutions.

by Erik Schön at January 13, 2026 09:01