call_end

    • chevron_right

      Mathieu Pasquet: Poezio 0.15 / 0.15.1

      news.movim.eu / PlanetJabber • 28 March • 1 minute

    About three years since the last version, poezio 0.15 (and 0.15.1 to address a small packaging mishap, version numbers are cheap) was released yesterday!

    Poezio is a terminal-based XMPP client which aims to replicate the feeling of terminal-based IRC clients such as irssi or weechat; to this end, poezio originally only supported multi-user chats.

    Features

    Not a lot this time around… Maybe next time?

    • A new moderate plugin (for XEP-0425 moderation).
    • Better self-ping (through the use of the slixmpp now builtin XEP-0410 plugin).
    • Use the system CA store by default.
    • Add a Ctrl-↑ shortcut to run /correct on the last message.
    • Poezio benefits from the recent slixmpp improvements, which means it can now transparently use Direct TLS as well as StartTLS.

    Fixes

    • Duplicated first message in conversation/private tab.
    • The many "clone" users in a room roster when on a spotty connection.
    • Python 3.13 and 3.14 compatibility (plenty of deprecations and removals).
    • Plenty of type checking mistakes and minor bugs spotted by mypy and pylint.

    Removals

    • Only python 3.11 and up is supported (was: 3.7).
    • The OTR plugin has been removed.
    • The launch/update.sh have been heavily simplified to use the uv tool instead of custom logic. It will be updated in the future to be able to run on pipx too, as uv is not available on some platforms.
    • wifi_tethering open_in_new

      This post is public

      blog.mathieui.net /en/poezio-0-15.html

    • chevron_right

      Erlang Solutions: My Journey from Ruby to Elixir: Lessons from a Developer

      news.movim.eu / PlanetJabber • 27 March • 8 minutes

    Why I Looked Beyond Ruby

    For years, Ruby was my go-to language for building everything from small prototypes to full-fledged production apps. I fell in love with its elegance and expressiveness and how Ruby on Rails could turn an idea into a working web app in record time. The community—with its focus on kindness and collaboration—only deepened my appreciation. In short, Ruby felt like home.

    But as my projects grew in complexity, I started running into bottlenecks. I had apps requiring real-time features, massive concurrency, and high availability. Scaling them with Ruby often meant juggling multiple processes, external services, or creative threading approaches—all of which worked but never felt truly seamless. That’s when I stumbled upon Elixir.

    At first glance, Elixir’s syntax reminded me of Ruby. It looked approachable and developer-friendly. But beneath the surface lies a fundamentally different philosophy, heavily influenced by Erlang’s functional model and the concurrency power of the BEAM. Moving from Ruby’s object-oriented approach to Elixir’s functional core was eye-opening. Here’s how I made that transition and why I think it’s worth considering if you’re a fellow Rubyist.

    The Mindset Shift: From Objects to Functions

    Life Before: Classes and Objects

    In Ruby, I approached problems by modeling them as classes, bundling data and behavior together. It was second nature to create an @name instance variable in an initializer, mutate it, and rely on inheritance or modules to share behavior. This style allowed me to write expressive code, but it also hid state changes behind class boundaries.

    A New Paradigm in Elixir

    Elixir flips that script. Data is immutable, and functions are the stars of the show. Instead of objects, I have modules that hold pure functions. Instead of inheritance, I rely on composition and pattern matching. This required me to unlearn some habits.

    • No more hidden state : Every function receives data as input and returns a new copy of that data, so you always know where transformations happen.

    No more deep class hierarchies : In Elixir, code sharing happens via modules and function imports rather than extending base classes.

    Example: Refactoring a Class into a Module

    Ruby

    class Greeter
      def initialize(name)
        @name = name
      end
    
      def greet
        "Hello, #{@name}!"
      end
    end
    
    greeter = Greeter.new("Ruby")
    puts greeter.greet  # => "Hello, Ruby!"
    

    Elixir

    defmodule Greeter do
    
      def greet(name), do: "Hello, #{name}!"
    
    end
    IO.puts Greeter.greet("Elixir")  # => "Hello, Elixir!"
    

    At first, I missed the idea of storing state inside an object, but soon realized how clean and predictable code can be when data and functions are separated. Immutability drastically cut down on side effects, which in turn cut down on surprises.

    Concurrency: Learning to Trust Processes

    Ruby’s approach

    Ruby concurrency typically means spinning up multiple processes or using multi-threading for IO-bound tasks. If you need to queue background jobs, gems like Sidekiq step in. Sidekiq runs in its own OS processes, separate from the main web server, and these processes can run on multiple cores for true parallelism. This approach is straightforward but often demands more memory and additional infrastructure for scaling.

    On the plus side, Ruby can handle many simultaneous web requests if they’re primarily IO-bound (such as database queries). Even with the Global Interpreter Lock (GIL) limiting the parallel execution of pure Ruby code, IO tasks can still interleave, allowing a single OS process to serve multiple requests concurrently.

    Elixir and the BEAM

    Elixir, on the other hand, was built for concurrency from the ground up, thanks to the BEAM virtual machine. It uses lightweight processes (not OS processes or threads) that are cheap to create and easy to isolate. These processes don’t share memory but communicate via message passing—meaning a crash in one process won’t cascade.

    This design was a game-changer for me: I no longer needed to layer so many external tools just to achieve scalable concurrency. When the language itself embraces concurrency, writing fault-tolerant, parallel code becomes second nature.

    Example: Background Jobs

    Ruby ( Sidekiq )

    class UserSyncJob
      include Sidekiq::Worker
    
      # This job fetches user data from an external API
      # and updates the local database.
      def perform(user_id)
        begin
          # 1. Fetch data from external service
          external_data = ExternalApi.get_user_data(user_id)
    
          # 2. Update local DB (pseudo-code)
          user = User.find(user_id)
          user.update(
            name: external_data[:name],
            email: external_data[:email]
          )
    
          puts "Successfully synced user #{user_id}"
        rescue => e
          # If something goes wrong, Sidekiq can retry
          # automatically, or we can log the error.
          puts "Error syncing user #{user_id}: #{e.message}"
        end
      end
    end
    
    # Trigger the job asynchronously:
    UserSyncJob.perform_async(42)
    
    

    Elixir ( GenServer )

    defmodule UserSyncServer do
      use GenServer
    
      # We'll store a simple state map for demonstration.
      def start_link(_opts) do
        GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
      end
    
      @impl true
      def init(state), do: {:ok, state}
    
      # Public API to sync a user:
      def sync_user(user_id) do
        GenServer.call(__MODULE__, {:sync, user_id})
      end
    
      @impl true
      def handle_call({:sync, user_id}, _from, state) do
        # 1. Fetch data from external API
        case ExternalApi.get_user_data(user_id) do
          {:ok, external_data} ->
            # 2. Update local DB
            user = MyApp.Repo.get(User, user_id)
            MyApp.Repo.update!(User.changeset(user, %{
              name: external_data.name,
              email: external_data.email
            }))
            IO.puts("Successfully synced user #{user_id}")
    
          {:error, reason} ->
            IO.puts("Error syncing user #{user_id}: #{reason}")
        end
    
        {:reply, :ok, state}
      end
    end
    
    # Start the GenServer somewhere in your supervision tree:
    {:ok, _pid} = UserSyncServer.start_link(%{})
    
    # Call the sync_user function to process the job:
    UserSyncServer.sync_user(42)
    
    

    No extra dependencies or external queue systems are needed; Elixir’s native process model just handles it.

    Debugging and Fault Tolerance: A New Perspective

    Catching Exceptions in Ruby

    Error handling in Ruby typically involves begin/rescue blocks. If a critical background job crashes, I might rely on Sidekiq’s retry logic or external monitoring. It worked, but I always worried about a missed exception bringing down crucial parts of the app.

    Supervision Trees in Elixir

    Elixir uses a concept called a supervision tree , inherited from Erlang’s OTP. Supervisors watch over processes, restarting them automatically if they crash. At first, I found it odd to let a process crash on purpose instead of rescuing the error. But once I saw how quickly the supervisor restarted a failed process, I was hooked.

    defmodule Worker do
      use GenServer
    
      def start_link(_) do
    	GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
      end
    
      def init(_), do: {:ok, %{}}
    
      def handle_call(:risky, _from, state) do
        raise "Something went wrong"
        {:reply, :ok, state}
      end
    end
    
    defmodule SupervisorTree do
      use Supervisor
    
      def start_link(_) do
        Supervisor.start_link(__MODULE__, :ok, name: __MODULE__)
      end
    
      def init(:ok) do
        children = [
          {Worker, []}
        ]
        Supervisor.init(children, strategy: :one_for_one)
      end
    end
    
    

    Now, if Worker crashes, the supervisor restarts it automatically. No manual intervention, no separate monitoring service, and no global meltdown.

    LiveView: A Game-Changer for Web Development

    Why I Loved Rails

    Rails made it trivial to spin up CRUD apps, handle migrations, and integrate with robust testing tools like RSpec. But building real-time interactions (like chat or real-time dashboards) could be tricky without relying heavily on JavaScript frameworks or ActionCable .

    Phoenix + LiveView

    Elixir’s Phoenix framework parallels Rails in many ways: fast bootstrapping, a clear folder structure, and strong conventions. But Phoenix Channels and LiveView push it even further. With LiveView, I can build highly interactive, real-time features that update the DOM via websockets—all without a dedicated front-end framework.


    Elixir (Phoenix LiveView)

    defmodule ChatLive do
      use Phoenix.LiveView
    
      def mount(_params, _session, socket) do
        {:ok, assign(socket, :messages, [])}
      end
    
      def handle_event("send", %{"message" => msg}, socket) do
        {:noreply, update(socket, :messages, fn msgs -> msgs ++ [msg] end)}
      end
    
      def render(assigns) do
        ~H"""
        <h1>Chat</h1>
        <ul>
          <%= for msg <- @messages do %>
            <li><%= msg %></li>
          <% end %>
        </ul>
    
        <form phx-submit="send">
          <input type="text" name="message" placeholder="Type something"/>
          <button type="submit">Send</button>
        </form>
        """
      end
    end
    
    

    This simple LiveView code handles real-time chat updates directly from the server, minimising the JavaScript I need to write. The reactive UI is all done through server-rendered updates.

    My Takeaways

    Embracing Immutability

    At first, it was tough to break free from the habit of mutating data in place. But once I got comfortable returning new data structures, my code became far more predictable. I stopped chasing side effects and race conditions.

    Let It Crash

    Ruby taught me to rescue and recover from every possible error. Elixir taught me to trust the supervisor process. This “let it crash” philosophy took some getting used to, but it simplifies error handling significantly.

    Less JavaScript, More Productivity

    LiveView drastically cut down my front-end overhead. I don’t need a full client framework for real-time updates. Seeing how quickly I could build a proof-of-concept live chat convinced me that Elixir was onto something big.

    Still Love Ruby

    None of this means I dislike Ruby. I still think Rails is fantastic for many use cases, especially when you need to prototype something quickly or build a classic CRUD app. Ruby fosters a developer-friendly environment that many languages can only aspire to. I simply reached a point where concurrency and fault tolerance became a top priority—and that’s where Elixir really shines.

    Final Advice for Rubyists Curious About Elixir

    1. Start Small : Experiment with a tiny service or background job. Don’t rewrite your entire monolith on day one.
    2. Get Comfortable with Functional Concepts : Embrace immutability and pattern matching. The mental shift is real, but it pays off.
    3. Check Out Phoenix and LiveView : If you’re doing web dev, see how your typical Rails flow translates in Phoenix. And definitely try LiveView.
    4. Utilise Existing Ruby Skills : Your understanding of test-driven development, domain modeling, and code readability all carry over—you’ll just write them differently.

    Ultimately, if you’re running into the same scaling or concurrency issues I did, Elixir might just be the upgrade you need. It brings a breath of fresh air to large-scale, real-time, and fault-tolerant applications while keeping developer happiness front and center. For me, it was worth the leap, and I haven’t looked back since. If you’re looking for a detailed comparison of Elixir and Ruby, our comprehensive Elixir vs. Ruby guide has you covered.

    The post My Journey from Ruby to Elixir: Lessons from a Developer appeared first on Erlang Solutions .

    • wifi_tethering open_in_new

      This post is public

      www.erlang-solutions.com /blog/my-journey-from-ruby-to-elixir-lessons-from-a-developer/

    • chevron_right

      The XMPP Standards Foundation: Open Letter to Meta: Support True Messaging Interoperability with XMPP

      news.movim.eu / PlanetJabber • 27 March • 1 minute

    It has been a little over a year since Meta announced their proposal for third-parties to achieve messaging interoperability with WhatsApp, with Facebook Messenger following half a year later. Not for everyone, and only because these services were designated as Gate Keepers under the recent Digital Markets Act (DMA) in the EU. So only in the EU, and then with many strings attached. In that time, a lot has been written. Element/Matrix have put in efforts to work with Meta to get some interoperability going. Unfortunately, the reference offers don’t provide what we would call true interoperability, and given that virtually nobody has taken up Meta on this offer, their proposal just falls short across the board.

    Over at the IETF, the More Instant Messaging Interoperability (MIMI) working group is working on mechanisms for interoperability. While several of our members are involved with MIMI and working on the implementation of the related MLS protocol for end-to-end encryption, we believe it is time to have true interoperability using a well-tested and widely implemented set of standards: XMPP.

    To that end, we today publish an Open Letter to Meta . A call to action, urging Meta to adopt XMPP for messaging interoperability. For a more in-depth reasoning, we also provide a detailed technical briefing .

    We are ready. Let’s make it happen.

    • wifi_tethering open_in_new

      This post is public

      xmpp.org /2025/03/open-letter-to-meta-support-true-messaging-interoperability-with-xmpp/

    • chevron_right

      Mathieu Pasquet: slixmpp v1.10

      news.movim.eu / PlanetJabber • 26 March • 2 minutes

    This new version does not have many new features, but it has quite a few breaking changes, which should not impact many people, as well as one important security fix.

    Thanks to everyone who contributed with code, issues, suggestions, and reviews!

    Security

    After working on TLS stuff, I noticed that we still allowed unencrypted SCRAM to be negociated, which is really not good. For packagers who only want this security fix, the commit fd66aef38d48b6474654cbe87464d7d416d6a5f3 should apply cleanly on any slixmpp version.

    (most servers in the wild have unencrypted connections entirely disabled, so this is only an issue for Man in the Middle attacks)

    Enhancements

    • slixmpp now supports XEP-0368 and allows to choose easily between direct TLS, or STARTTLS.

    Breaking Changes

    • The security issue mentioned above is a breaking change if you actively want to connect to servers without encryption. If that is a desired behavior, you can still set xmpp['feature_mechanisms'].unencrypted_scram = True on init.

    • Removal of the timeout_callback parameter anywhere it was present. Users are encouraged to await on the coroutine or the future returned by the function, which will raise an IqTimeout exception when appropriate.

    • Removal of the custom google plugins, which I am guessing have not worked in a very long time (both the google and gmail_notify plugin).

    • Removal of the Stream Compression ( XEP-0138 ) plugin. It was not working at all and use of compression is actively discouraged for security reasons .

    • Due to the new connection code, the configuration of the connection parameters has changed quite a bit:

      • The XMLStream (from which inherits the ClientXMPP class) does not have a use_ssl parameter anymore. Instead it has enable_direct_tls and enable_starttls as well as enable_plaintext attributes. Those attributes control whether we want to connect using starttls or direct TLS. The plaintext is for components since we only implement the jabber component protocol ( XEP-0114 ).
      • Handling of custom addresses has changed a bit, now they are set through calling connect() , and kept until connect() is called without arguments again.
      • The DNS code will now fetch both xmpps-client and xmpp-client records (unless direct TLS is explicitly disabled) and prefer direct TLS if it has the same priority as STARTTLS.
      • The SRV targeted by the queries can be customized using the tls_services and starttls_services of ClientXMPP (but have no idea why anyone would do this)

    Fixes

    • Another issue encountered with the Rust JID, trying to compare a JID against strings that cannot be parsed or other objects would raise an InvalidJID exception instead of returning False .
    • The ssl_cert event would only be invoked on STARTTLS.
    • One of the asyncio warnings on program exit (that a coroutine is still running).
    • Traceback with BaseXMPP.get .
    • A potential edge case in the disco ( XEP-0030 ) plugin when using strings instead of JIDs.
    • A traceback in vcard-temp ( XEP-0054 ) and Legacy Delayed Delivery ( XEP-0091 ) when parsing datetimes.
    • A traceback when manipulating conditions in feature mechanisms.
    • A traceback in Ad-hoc commands ( XEP-0050 ) during error handling.
    • Many tracebacks in OAuth over XMPP ( XEP-0235 ) due to urllib API changes.

    Links

    You can find the new release on codeberg , pypi , or the distributions that package it in a short while.

    • wifi_tethering open_in_new

      This post is public

      blog.mathieui.net /en/slixmpp-1.10.html

    • chevron_right

      Kaidan: Kaidan 0.12.0: User Interface Polishing and Account Migration Fixes

      news.movim.eu / PlanetJabber • 20 March • 1 minute

    Kaidan 0.12.0 looks and behaves better than ever before! Chats can now quickly be pinned and moved. In addition, the list of group chat participants to mention them is placed above the cursor if enough space is available. With this release, OMEMO can be used right after migrating an account and migrated contacts are correctly verified.

    Have a look at the changelog for more details.

    Changelog

    Features:

    • Use square selection to crop avatars (fazevedo)
    • Use background with rounded corners for chat list items (melvo)
    • Remove colored availability indicator from chat list item (melvo)
    • Display group chat participant picker above text cursor in large windows (melvo)
    • Do not allow to enter/send messages without visible characters (melvo)
    • Remove leading/trailing whitespace from exchanged messages (melvo)
    • Ignore received messages without displayable content if they cannot be otherwise processed (melvo)
    • Allow to show/hide buttons to pin/move chat list items (melvo)

    Bugfixes:

    • Fix style for Flatpak (melvo)
    • Fix displaying video thumbnails and opening files for Flatpak (melvo)
    • Fix message reaction details not opening a second time (melvo)
    • Fix opening contact addition view on receiving XMPP URIs (melvo)
    • Fix format of text following emojis (melvo)
    • Fix eliding last message text for chat list item (melvo)
    • Fix unit tests (mlaurent, fazevedo, melvo)
    • Fix storing downloaded files with unique names (melvo)
    • Fix overlay to change/open avatars shown before hovered in account/contact details (melvo)
    • Fix verification of moved contacts (fazevedo)
    • Fix setting up end-to-end encryption (OMEMO 2) after account migration (melvo)

    Notes:

    • Kaidan requires KWindowSystem and KDSingleApplication now (mlaurent)
    • Kaidan requires KDE Frameworks 6.11 now
    • Kaidan requires KQuickImageEditor 0.5 now
    • Kaidan requires QXmpp 1.10.3 now

    Download

    Or install Kaidan for your distribution:

    Packaging status

    • wifi_tethering open_in_new

      This post is public

      kaidan.im /2025/03/21/kaidan-0.12.0/

    • chevron_right

      Erlang Solutions: Meet the team: Lorena Mireles

      news.movim.eu / PlanetJabber • 20 March • 3 minutes

    Lorena Mireles is an influential force in the BEAM community, known for her work as an Elixir developer and as a dedicated member of the Code BEAM America programme committee. She’s been instrumental in fostering connections and shaping discussions that help drive the future of Elixir.

    In this interview, Lorena opens up about her journey with Elixir, her role on the committee, and what makes the BEAM community so unique.

    Meet the team: Lorena Mireles

    What first drew you to Elixir, and what keeps you hooked?

    The community was, without a doubt, the first reason I became interested in Elixir. I had no prior knowledge of Elixir the first time I attended a conference, but I felt very comfortable at the talks. The explanations were clear and interesting, which motivated me to investigate the programming language further.

    Also, everyone was very kind and willing to share their knowledge. Over time, I discovered the advantages of this programming language for designing powerful systems. I’m still amazed at how easy it is to create projects with complex technical requirements, all thanks to the way Elixir and BEAM were created, and all the material available to learn about them.

    How did you get involved with the Code BEAM America committee, and what’s that experience been like?

    I joined the committee at the invitation of the organisers, and I’m very grateful, as I’ve been a part of it for three consecutive editions, and I continue to learn and be surprised each time.

    My work focuses primarily on promoting women’s participation at the conference and supporting the diversity program, which has allowed me to meet great women and learn about their projects and experiences. Overall, it’s a great opportunity to get to know the speakers a little better and get involved in the BEAM community.

    I also learn about new topics, as seeing the talks they submit also motivates me to explore them.

    What were your standout moments from this year’s Code BEAM America?

    I’ll start with my favorite- reconnecting with the BEAM community. I admire so many people and their work, so Code BEAM America was a great experience to learn more about it. I also loved seeing the new speakers and first-time attendees. I chatted with some of them, and they loved the experience. It was great to get their feedback.

    The keynotes were also some of my favorites. Machine Learning and AI were discussed, which seemed very appropriate given the current relevance of these topics. There were also a couple of talks focused on social aspects, which are always necessary to foster continuous improvement in teams.

    What excites you most about the future of the BEAM community?

    All the projects that will likely be happening this year. At this year’s Code BEAM, I met new speakers and saw new attendees, which means the knowledge continues to expand and the community grows, and that also means new projects and more material about Elixir and BEAM in general.

    I’m excited to think about all the new things we’ll see and how we continue to encourage new people to participate because, without a doubt, Elixir is a programming language worth learning.

    Final thoughts

    Lorena’s experience with Elixir and her role in the BEAM community show just how powerful collaboration and innovation can be in shaping the ecosystem. Beyond that, her Women in BEAM survey and Women in Elixir webinar are amazing resources she’s put together to foster more inclusivity in the community.

    You can find her on social media channels below, so feel free to reach out and connect!

    The post Meet the team: Lorena Mireles appeared first on Erlang Solutions .

    • chevron_right

      Prosodical Thoughts: Prosody 13.0.0 released!

      news.movim.eu / PlanetJabber • 17 March • 7 minutes

    Welcome to a new major release of the Prosody XMPP server! While the 0.12 branch has served us well for a while now, this release brings a bunch of new features we’ve been busy polishing.

    If you’re unfamiliar with Prosody, it’s an open-source project that implements XMPP , an open standard protocol for online communication. Prosody is widely used to power everything from small self-hosted messaging servers to worldwide real-time applications such as Jitsi Meet. It’s part of a large ecosystem of compatible software that you can use for realtime online communication.

    Before we begin…

    The first thing anyone who has been following the project for a while will notice about this release is the version number.

    Long adherents of the cult of 0ver , we finally decided it was time to break away. While, as Shakespeare wrote, “That which we call a rose, by any other name would smell as sweet”, such is true of version numbers. Prosody has been stable and used in production deployments for many years, however the ‘0.x’ version number occasionally misled people to believe otherwise. Apart from shifting the middle component leftwards, nothing has changed.

    If you’re really curious, you can read full details in our versioning and support policy .

    Our version numbers have also been in step with Debian’s for several versions now. Could this become a thing? Maybe!

    Overview of changes

    This release brings a wide range of improvements that make Prosody more secure, performant, and easier to manage than ever before. Let’s review the most significant changes that administrators and users can look forward to across a range of different topics.

    Security and authentication

    Security takes centre stage in this release with several notable improvements. Building on DNSSEC, the addition of full DANE support for server-to-server connections strengthens the trust between federating XMPP servers.

    We’ve enhanced our support for channel binding, which is now compatible with TLS 1.3, and we’ve added support for XEP-0440 which helps clients know which channel binding methods the server supports. Channel binding protects your connection from certain machine-in-the-middle attacks, even if the server’s TLS certificate is compromised.

    Account management

    Administrators now have more granular control over user accounts with the ability to disable and enable them as needed. This can be particularly useful for public servers, where disabling an account can act as a reversible alternative to deletion.

    In fact, we now have the ability to set a grace period for deleted accounts to allow restoring an account (within the grace period) in case of accidental deletion.

    Roles and permissions

    A new role and permissions framework provides more flexible access control. Prosody supplies several built-in roles:

    • prosody:operator - for operators of the whole Prosody instance. By default, accounts with this role have full access, including to operations that affect the whole server.
    • prosody:admin - the usual role for admins of a specific virtual host (or component). Accounts with this role have permission to manage user accounts and various other aspects of the domain.
    • prosody:member - this role is for “normal” user accounts, but specifically those ones which are trusted to some extent by the administrators. Typically accounts that are created through an invitation or through manual provisioning by the admin have this role.
    • prosody:registered - this role is also for general user accounts, but is used by default for accounts which registered themselves, e.g. if the server has in-band registration enabled.
    • prosody:guest - finally, the “guest” role is used for temporary/anonymous accounts and is also the default for remote JIDs interacting with the server.

    For more details about how to use these roles, customize permissions, and more, read our new roles and permissions documentation . You will also find the link there for the development documentation, so module developers can make use of the new system.

    Shell commands

    Since the earliest releases, the prosodyctl command has been the admin’s primary way of managing and interacting with Prosody. In 0.12 we introduced the prosodyctl shell interface to send administrative commands to Prosody at runtime via a local connection. It has been a big success, and this release significantly extends its capabilities.

    • prosodyctl adduser/passwd/deluser commands now use the admin connection to create users, which improves compatibility with various storage and authentication plugins. It also ensures Prosody can instantly respond to changes, such as immediately disconnecting users when their account is deleted.
    • Pubsub management commands have been added, to create/configure/delete nodes and items on pubsub and PEP services without needing an XMPP client.
    • One of our own favourites as Prosody developers is the new prosodyctl shell watch log command, which lets you stream debug logs in real-time without needing to store them on the filesystem.
    • Similarly, there is now prosodyctl shell watch stanzas which lets you monitor stanzas to/from arbitrary JIDs, which is incredibly helpful for developers trying to diagnose various client issues.
    • Server-wide announcements can now be sent via the shell, optionally limiting the recipients by online status or role.
    • MUC has gained a few new commands for interacting with MUC rooms.

    Improved Multi-User Chat (MUC) Management

    The MUC system has received a significant overhaul focusing on security and administrative control. By default, room creation is now restricted to local users, providing better control over who can create persistent and public rooms.

    Server administrators get new shell commands to inspect room occupants and affiliations, making day-to-day operations more straightforward.

    One notable change is that component admins are no longer automatically owners. This can be reverted to the old behaviour with component_admins_as_room_owners = true in the config, but this has known incompatibilities with some clients. Instead, admins can use the shell or ad-hoc commands to gain ownership of rooms when it’s necessary.

    Better Network Performance

    Network connectivity sees substantial improvements with the implementation of RFC 8305’s “Happy Eyeballs” algorithm, which enhances IPv4/IPv6 dual-stack performance and increases the chance of a successful connection.

    Support for TCP Fast Open and deferred accept capabilities (in the server_epoll backend) can potentially reduce connection latency.

    The server now also better handles SRV record selection by respecting the ‘weight’ parameter, leading to more efficient connection distribution.

    Storage and Performance Improvements

    Under the hood, Prosody now offers better query performance with its internal archive stores by generating indexes.

    SQLite users now have the option to use LuaSQLite3 instead of LuaDBI, potentially offering better performance and easier deployment.

    We’ve also added compatibility with SQLCipher , a fork of SQLite that adds support for encrypted databases.

    Configuration Improvements

    The configuration system has been modernized to support referencing and appending to previously set options, making complex configurations more manageable.

    While direct Lua API usage in the config file is now deprecated, it remains accessible through the new Lua.* namespace for those who need it.

    Also new in this release is the ability to reference credentials or other secrets in the configuration file, without storing them in the file itself. It is compatible with the credentials mechanisms supported by systemd , podman and more.

    Developer/API changes

    The development experience has always been an important part of our project - we set out to make an XMPP server that was very easy to extend and customize. Our developer API has improved with every release. We’ve even had first-time coders write Prosody plugins!

    There are too many improvements to list here, but some notable ones:

    • Storage access from modules has been simplified with a new ‘keyval+’ store type, which combines the old ‘keyval’ (default) and ‘map’ stores into a single interface. Before this change, many modules had to open the store twice to utilize the two APIs.
    • Any module can now replace custom permission handling with Prosody’s own permission framework via the simple module:may() API call.
    • Providing new commands for prosodyctl shell is now much easier for module developers.

    Backwards compatibility is of course generally preserved, although is_admin() has been deprecated in favour of module:may() . Modules that want to remain compatible with older versions can use mod_compat_roles to enable (limited) permission functionality.

    Important Notes for Upgrading

    A few breaking changes are worth noting:

    • Lua 5.1 support has been removed (this also breaks compatibility with LuaJIT, which is based primarily on Lua 5.1).
    • Some MUC default behaviors have changed regarding room creation and admin permissions (see above).

    Conclusion

    We’re very excited about this release, which represents a significant step forward for Prosody, and contains improvements for virtually every aspect of the server. From enhanced security to better performance and more flexible administration tools, there has never been a better time to deploy Prosody and take control of your realtime communications.

    As always, if you have any problems or questions with Prosody or the new release, drop by our community chat !

    • wifi_tethering open_in_new

      This post is public

      blog.prosody.im /prosody-13.0.0-released/

    • chevron_right

      Erlang Solutions: Elixir vs Haskell: What’s the Difference?

      news.movim.eu / PlanetJabber • 13 March • 11 minutes

    Elixir and Haskell are two very powerful, very popular programming languages. However, each has its strengths and weaknesses. Whilst they are similar in a few ways, it’s their differences that make them more suitable for certain tasks.

    Here’s an Elixir vs Haskell comparison.

    Elixir vs Haskell: a comparison

    Core philosophy and design goals

    Starting at a top-level view of both languages, the first difference we see is in their fundamental philosophies. Both are functional languages. However, their design choices reflect very different priorities.

    Elixir is designed for the real world. It runs on the Erlang VM (BEAM), which was built to handle massive concurrency, distributed systems, and applications that can’t afford downtime, like telecoms, messaging platforms, and web apps.

    Elixir prioritises:

    • Concurrency-first – It uses lightweight processes and message passing to make scalability easier.
    • Fault tolerance – It follows a “Let it crash” philosophy to ensure failures don’t take down the whole system.
    • Developer-friendly – Its Ruby-like syntax makes functional programming approachable and readable.

    Elixir is not designed for theoretic rigidness—it’s practical. It gives you the tools you need to build robust, scalable systems quickly, even if that means allowing some flexibility in functional integrity.

    Haskell, on the other hand, is all about mathematical precision. It enforces a pure programming model. As a result, functions don’t have side effects, and data is immutable by default. This makes it incredibly powerful for provably correct, type-safe programs, but it also comes with a steeper learning curve.

    We would like to clarify that Elixir’s data is also immutable, but it does a great job of hiding that fact. You can “reassign” variables and ostensibly change values, but the data underneath remains unchanged. It’s just that Haskell doesn’t allow that at all.

    Haskell offers:

    • Pure functions – No surprises; given the same input, a function will always return the same output.
    • Static typing with strong guarantees – The type system (with Hindley-Milner inference, monads, and algebraic data types) helps catch errors at compile time instead of run time.
    • Lazy evaluation – Expressions aren’t evaluated until they’re needed, optimising performance but adding complexity.

    Haskell is a language for those who prioritise correctness, mathematical rigour, and abstraction over quick iterations and real-world flexibility. That does not mean it’s slower and inflexible. In fact, experienced Haskellers will use its strong type guarantees to iterate faster, relying on its compiler to catch any mistakes. However, it does contrast with Elixir’s gradual tightening approach. Here, interaction between processes is prioritised, and initial development is quick and flexible, becoming more and more precise as the system evolves.

    Typing: dynamic vs static

    The next significant difference between Elixir and Haskell is how they handle types.

    Elixir is dynamically typed. It doesn’t require explicitly declared variable types; it will infer them at run time. As a result, it’s fast to write and easy to prototype. It allows you to focus on functionality rather than defining types up front.

    Of course, there’s a cost attached to this flexibility. If variables are computed at run time, any errors are also only detected then. Mistakes that could have been caught earlier come up when the code is executed. In a large project, this can make debugging a nightmare.

    For example:

    def add(a, b), do: a + b  
    
    IO.puts add(2, 3)      # Works fine
    IO.puts add(2, "three") # Causes a runtime error
    

    In this example, “three” is a string but should’ve been a number and is going to return an error. Since it doesn’t type check at compile time, the error will only be caught when the function runs.

    Meanwhile, Haskell uses static typing, which means all variable types are checked at compile time. If there’s a mismatch, the code won’t compile. This is very helpful in preventing many classes of bugs before the code execution.

    For example:

    add :: Int -> Int -> Int
    add a b = a + b
    
    main = print (add 2 3)    -- Works fine
    main = print (add 2 "three")  -- Compile-time error
    
    

    Here, the compiler will immediately catch the type mismatch and prevent runtime errors.

    Elixir’s dynamic typing gives you faster iteration and more flexible development. However, it doesn’t rely only on dynamic typing for its robustness. Instead, it follows Erlang’s “Golden Trinity” philosophy, which is:

    • Fail fast instead of trying to prevent all possible errors.
    • Maintain system stability with supervision trees, which automatically restart failed processes.
    • Use the BEAM VM to isolate failures so they don’t crash the system.

    Haskell’s static typing, on the other hand, gives you long-term maintainability and correctness up front. It’s particularly useful in high-assurance software projects, where errors must be kept to a minimum before execution.

    In comparison, Elixir is a popular choice for high-availability systems. Both are highly reliable, but the former is okay with failure and relies on recovery at runtime, whilst the latter enforces correctness at compile-time.

    Concurrency vs parallelism

    When considering Haskell vs Elixir, concurrency is one of the biggest differentiators. Both Elixir and Haskell are highly concurrent but take different approaches to it. Elixir is built for carrying out a massive number of processes simultaneously. In contrast, Haskell gives you powerful—but more manual—tools for parallel execution.

    Elixir manages effortless concurrency with BEAM. The Erlang VM is designed to handle millions of lightweight processes at the same time with high fault tolerance. These lightweight processes follow the actor model principles and are informally called “actors”, although Elixir doesn’t officially use this term.

    Unlike traditional OS threads, these processes are isolated and communicate through message-passing. That means that if one process crashes, BEAM uses supervision trees to restart it automatically while making sure it doesn’t affect the others. This is typical of the ‘let it crash’ philosophy, where failures are expected and handled. There is no expectation to eliminate them entirely.

    As a result, concurrency in Elixir is quite straightforward. You don’t need to manage locks, threads, or shared memory. Load balancing is managed efficiently by the BEAM scheduler across CPU cores, with no manual tuning required.

    Haskell also supports parallelism and concurrency but it requires more explicit management. To achieve this, it uses several concurrency models, including software transactional memory (STM), lazy evaluations, and explicit parallelism to efficiently utilise multicore processors.

    As a result, even though managing parallelism is more hands-on in Haskell, it also leads to some pretty significant performance advantages. For certain workloads, it can be several orders of magnitude faster than Elixir.

    Additionally, Cloud Haskell extends Haskell’s concurrency model beyond a single machine. Inspired by Erlang’s message-passing approach, it allows distributed concurrency across multiple nodes, making Haskell viable for large-scale concurrent systems—not just parallel computations.

    Scaling and parallelism continue to be one of the headaches of distributed programming. Find out what the others are.
    [ Read more ]

    Best-fit workloads

    Both Haskell and Elixir are highly capable, but the kinds of workloads for which they’re suitable are different. We’ve seen how running on the Erlang VM allows Elixir to be more fault-tolerant and support massive concurrency. It can also run processes along multiple nodes for seamless communication.

    Since Elixir can scale horizontally very easily—across multiple machines—it works really well for real-time applications like chat applications, IoT platforms, and financial transaction processing.

    Haskell optimises performance with parallel execution and smart use of system resources.  It doesn’t have BEAM’s actor-based concurrency model but its powerful programming features that allow you to make fine-grained use of multi-core processors more than make up for it.

    It’s perfect for applications where you need heavy numerical computations, granular control over multi-core execution, and deterministic performance.

    So, where Elixir excels at processing high volumes of real-time transactions, Haskell works better for modelling, risk analysis, and regulatory compliance.

    Ecosystem and tooling

    Both Elixir and Haskell have strong ecosystems, but you must have noticed the theme running through our narrative. Yes, both are designed for different industries and development styles.

    Elixir’s ecosystem is practical and industry-focused, with a strong emphasis on web development and real-time applications. It has a growing community and a well-documented standard library, supplemented with production-ready libraries.

    Meanwhile, Haskell has a highly dedicated community in academia, finance, human therapeutics, wireless communications and networking, and compiler development. It offers powerful libraries for mathematical modelling, type safety, and parallel computing. However, tooling can sometimes feel less user-friendly compared to mainstream languages.

    For web development, Elixir offers the Phoenix framework: a high-performance web framework designed for real-time applications, which comes with built-in support for WebSockets and scalability. It follows Elixir’s functional programming principles but keeps development accessible with a syntax inspired by Ruby on Rails.

    Haskell’s Servant framework is a type-safe web framework that leverages the language’s static typing to ensure API correctness. While powerful, it comes with a steeper learning curve due to Haskell’s strict functional nature.

    Which one you should choose depends on your project’s requirements. If you’re looking for general web and backend development, Elixir’s Phoenix is the more practical choice. For research-heavy or high-assurance software, Haskell’s ecosystem provides formal guarantees.

    Maintainability and refactoring

    It’s important to manage technical debt while keeping software maintainable. Part of this is improving quality and future-proofing the code. Elixir’s syntax is clean and intuitive. It offers dynamic typing, meaning you can write code quickly without specifying types. This can make runtime errors harder to track sometimes, but debugging tools like IEx (Interactive Elixir) and Logger make troubleshooting straightforward.

    It’s also easier to refactor because of its dynamic nature and process isolation. Since BEAM isolates processes, refactoring can often be done incrementally without disrupting the rest of the system. This is particularly handy in long-running, real-time applications where uptime is crucial.

    Haskell, on the other hand, enforces strict type safety and a pure functional model, which makes debugging less frequent but more complex. As we mentioned earlier, the compiler catches most issues before runtime, reducing unexpected behaviour.

    However, this strictness means that refactoring in Haskell must be done carefully to maintain type compatibility, module integrity, and scope resolution. Unlike dynamically typed languages, where refactoring is often lightweight, Haskell’s strong type system and module dependencies can make certain refactorings more involved, especially when they affect function signatures or module structures.

    Research on Haskell refactoring highlights challenges like name capture, type signature compatibility, and module-level dependency management, which require careful handling to preserve correctness.

    Then, there’s pattern matching, which both languages use, but do it differently.

    Elixir’s pattern matching is flexible and widely used in function definitions and control flow, making code more readable and expressive.

    Haskell’s pattern matching is type-driven and enforced by the compiler, ensuring exhaustiveness but requiring a more upfront design.

    So, which of the two is easier to maintain?

    Elixir is better suited for fast-moving projects where codebases evolve frequently, thanks to its fault-tolerant design and incremental refactoring capabilities.

    Haskell provides stronger guarantees of correctness, making it a better choice for mission-critical applications where stability outweighs development speed.

    Compilation speed

    One often overlooked difference between Elixir and Haskell is how they handle compilation and code updates.

    Elixir benefits from BEAM’s hot code swapping, where updates can be applied without stopping a running system. Additionally, Elixir compiles faster than Haskell because it doesn’t perform extensive type checking at compile time.

    This speeds up development cycles, which is what makes Elixir well-suited for projects requiring frequent updates and rapid iteration. However, since BEAM uses Just-In-Time (JIT) compilation, some optimisations happen at runtime rather than during compilation.

    Haskell, on the other hand, has a much stricter compilation process. The compiler performs heavy type inference and optimisation, which increases compilation time but results in highly efficient, predictable code.

    Learning curve

    Elixir is often considered easier to learn than Haskell. Its syntax is clean and approachable, especially if you’re coming from Ruby, Python, or JavaScript. The dynamic typing and friendly error messages make it easy to experiment without getting caught up in strict type constraints.

    Haskell, on the other hand, has a notoriously steep learning curve. It requires a shift in mindset, especially for those unfamiliar with pure functional programming, monads, lazy evaluation, and advanced type systems. While it rewards those who stick with it, the initial learning experience can be challenging, even if you’re an experienced developer.

    Metaprogramming

    Both Elixir and Haskell allow you to write highly flexible code, but they take different approaches.

    Elixir provides macros, which you can modify and extend the language at compile time. This makes it easy to generate boilerplate code, create domain-specific languages (DSLs), and build reusable abstractions. However, improper use of macros can make code harder to debug and maintain.

    Haskell doesn’t have macros but compensates with powerful type-level programming. Features like type families and higher-kinded types allow you to enforce complex rules at the type level. This enables incredible flexibility, but it also makes the language even harder to learn.

    Choosing between the two

    As you’ve seen, both Elixir and Haskell can be great, if used correctly in the right circumstances.

    If you do choose Elixir, we’ve got a great resource that discusses how Elixir and Erlang—the language that forms its foundation—can help in future-proofing legacy systems. Find out how their reliability and scalability make them great for modernising infrastructures.

    [ Read more ]

    Want to learn more? Drop the Erlang Solutions team a message.

    The post Elixir vs Haskell: What’s the Difference? appeared first on Erlang Solutions .

    • chevron_right

      Mathieu Pasquet: slixmpp v1.9.1

      news.movim.eu / PlanetJabber • 11 March

    This is mostly a bugfix release over version 1.9.0 .

    The main fix is the rust JID implementation that would behave incorrectly when hashed if the JID contained non-ascii characters. This is an important issue as using a non-ascii JID was mostly broken, and interacting with one failed in interesting ways.

    Fixes

    • The previously mentioned JID hash issue
    • Various edge cases in the roster code
    • One edge case in the MUC ( XEP-0045 ) plugin in join_muc_wait
    • Removed one broken entrypoint from the package
    • Fixed some issues in the MUC Self-Ping ( XEP-0410 ) plugin

    Enhancements

    • Stanza objects now have a __contains__ (used by x in y ) method that allow checking if a plugin is present.
    • The You should catch Iq… exceptions message now includes the traceback
    • The MUC Self-Ping ( XEP-0410 ) plugin allows custom intervals and timeouts for each MUC.
    • Added a STRICT_INTERFACE mode (currently a global var in the stanzabase module) that controls where accessing a non-existing stanza attribute should raise or warn, it previously only warned.
    • The CI does more stuff
    • More type hints here and there

    Links

    You can find the new release on codeberg , pypi , or the distributions that package it in a short while.

    • wifi_tethering open_in_new

      This post is public

      blog.mathieui.net /en/slixmpp-1.9.1.html