Note: This post is about contributing to the
project, an XMPP library for Go.
The most up-to-date version of this document can always be found at
This post provides a high-level architectural overview of the
Its target audience is contributors looking to familiarize themselves with the
The Mellium project is designed to be very modular.
It is itself a complete XMPP implementation with many features useful in instant
messaging, but it is also designed for users who have special requirements to be
able to reuse only small pieces in their own libraries and services.
Broadly speaking, the module can be divided into three ‘tiers’ of packages.
The highest level packages implement XEPs or individual features.
These packages import the mid-level
xmpp package to perform actions on an
XMPP session such as handling a request for history, or sending a ping.
High level packages and the mid-level
xmpp package import the lowest level of
These are the basic building blocks of XMPP such as the primitive stanza types
stanza, dialing a socket with
dial, or the
for handling XMPP addresses.
Packages may only import packages at the same or a lower level to avoid circular
These boundaries aren’t strictly defined, but it can be helpful to think about them when creating new packages or deciding where to implement some functionality.
Connections and Service Discovery
Dialing TCP connections is implemented in its own package,
Discovering locations to dial is handled by
internal/discover so that it can
be used by
dial for finding TCP endpoints but also by the
package for finding WebSocket endpoints.
jid package contains functionality for handling XMPP addresses,
historically known as “Jabber Identifiers” (JIDs).
It is used by almost every package in the module and will likely be imported by
almost every user of the module.
Stanzas, Errors, and Streams
Multiple APIs for creating stanzas and stanza-level errors are present in the
APIs for creating and parsing stream headers and stream-level errors are present
If you are handling anything related to payloads sent over the wire (but not
related to a specific XEP), chances are it lives in one of these two packages or
in the related
internal/stream package which contains other stream related
helper functions that aren’t generally useful or flexible enough to be part of
the public API.
Sessions and Feature Negotiation
xmpp package contains just enough functionality to get a connection
up and running.
Within this package the main files are:
session.gowhich includes the session creation and negotiation logic,
negotiator.gowhich implements the default handshake used when creating sessions and the modified WebSocket handshake, and
features.gowhich contains types for creating stream features and the logic used by the default negotiator pick and negotiate individual features.
Individual stream features are in separate files that match their name such as
mux package is also arguably a mid-level package.
It is imported by most high-level feature packages and provides an
xmpp.Handler that can be used to route events to other handlers based on the
type of the element and/or its payload.
If you are asked to make modifications to routing logic, this is the place to
Other XEPs and Features
XEPs are normally implemented in packages named after their functionality.
This may be the XEPs name or short name if it is large enough to warrant its own
For example, XEP-0313: Message Archive Management might be
implemented in the
Smaller XEPs or large features that are spread across many XEPs may be
implemented together, for example, XEP-0082: XMPP Date and Time
Profiles and XEP-0202: Entity Time are both implemented
For more information on naming and writing feature packages see “Implementing XMPP Extensions”. If you are looking for a specific XEP and the package that implements it see: mellium.im/docs/xeps.