xmatic

Rating: 
5
Your rating: None Average: 5 (6 votes)

Native Matrix client built on matrix-rust-sdk with a Silica UI.

FEATURES

- Sliding sync, end-to-end encryption, cross-signing, device verification (both directions), key backup and recovery
- Rooms, spaces (nested), direct chats, threads (answer in one or start one), room directory search
- Create rooms, invite, leave; member list and member profiles with moderation
- Send, edit, delete, reply, pagination in encrypted rooms
- Search the messages of a conversation. The index lives on the device and is encrypted with the same key as the rest of the local storage; the query never leaves the phone
- Formatted messages: bold, italic, code, quotes, lists and links render as themselves
- Pinned messages, favourites, low priority, per-room mute, ignored users
- A line marks where reading stopped. A room opens there or at its newest message, whichever you set, and says who has read what
- A message whose authenticity could not be confirmed carries a mark next to its time, with a page explaining what each mark means
- Four coloured lines say how safe the device is: backup, recovery, cross-signing, local storage
- Reactions from an emoji picker whose first tab you fill yourself
- Pictures, files, sharing (also as share target from Gallery / file manager)
- Voice messages; voice and video calls (classic 1:1 VoIP; MatrixRTC-only clients cannot be called)
- Notifications, offline send queue, encrypted local storage
- OAuth (MAS) login, device-code login, password login
- 29 interface languages, switchable in the app

LANGUAGES

The interface is available in the 24 official languages of the European Union
plus Russian, Norwegian, Icelandic, Simplified Chinese and Hindi. Norwegian was contributed by a Norwegian
speaker and German is the project language; the rest are machine translations,
usable but unchecked. Account has a language setting of its own, English
included, so there is always a way back out of one. A change applies at the
next start.

Corrections are welcome at the GitHub repository below - the file to edit is
translations/harbour-xmatic-<language>.ts, and translations/STATUS.md says
which languages have been read by a native speaker.

LOCAL STORAGE

Session tokens and the message database are encrypted with a key from Sailfish
Secrets.

Some Sailfish images ship only the client library of that key service and not
the service itself. On such a device xmatic no longer creates an unencrypted
database quietly: it says what is missing, gives the command to install it and
a command to check the result with, and offers to continue without encryption
as an explicit choice. The package also requires the service, so on most
devices this never comes up.

An installation that already holds data is never blocked - that would strand
its room keys. Where a database simply predates the key, the encryption page
offers to re-create it encrypted, which costs one sign-out and your recovery
key.

How safe the device is stands in four coloured lines - backup, recovery,
cross-signing, local storage. Green is in order, orange is something you can
put right, red is something the system does not offer. If anything is not
green, the app says so once after starting, with the action that fits and
"later" always available. When everything is green you never see any of it.

WHY IS THE PACKAGE SO BIG?

The app ships the complete Matrix stack statically: matrix-rust-sdk, E2EE
(vodozemac), sliding sync, rustls, its own HTTP runtime and a bundled SQLite.
None of that exists as a system library on Sailfish OS, and Qt 5.6 is too old
for the C++ alternatives - which is exactly why the protocol core is written in
Rust. Installed size ~60 MB (Element X, same SDK: ~100 MB), RPM ~18 MB.

NO BACKGROUND DAEMON

Messages arrive while the app is running (the cover is enough). Like other
daemonless messengers on this platform, a closed app does not receive.

PUSH NOTIFICATIONS (off by default)

Requested by users. It is off, it has its own setting, and it does nothing
until you switch it on by hand. It needs a UnifiedPush distributor installed
separately and a push gateway you choose yourself, and it discloses metadata —
which rooms, at what times — to parties that otherwise know nothing about you.

Details, and what to weigh before turning it on:
https://github.com/JimKnopfIoT/harbour-xmatic/blob/master/docs/PUSH.md

Leaving it off changes nothing.

ARCHITECTURES

aarch64 (Sailfish OS 5.0+), armv7hl (Sailfish OS 4.6+). Tested on J2, Xperia10III and Gemini PDA.

REQUIREMENTS

xmatic syncs over simplified sliding sync (MSC4186), the same mechanism
Element X uses. Your homeserver must support it. If it does not, sign-in
works but no rooms load and the app keeps showing "Offline".

How to check your server: open this address in a browser

https://YOUR-SERVER/_matrix/client/versions

and look for this line:

"org.matrix.simplified_msc3575": true

If it is missing, xmatic cannot load your rooms from that server.

Sign-in methods supported: OAuth 2.0 / Matrix Authentication Service,
device code ("Sign in on another device"), and username plus password on
servers without OAuth.

The classic SSO redirect sign-in (SAML, CAS) is not supported.

Written with Claude Code (Anthropic), icons included; the protocol core is upstream matrix-rust-sdk.

Source, issues, releases:
https://github.com/JimKnopfIoT/harbour-xmatic

Screenshots: 
Application versions: 
AttachmentSizeDate
File harbour-xmatic-0.28.0-1.aarch64.rpm18.35 MB01/09/2026 - 23:45
File harbour-xmatic-0.28.0-1.armv7hl.rpm18.87 MB01/09/2026 - 23:45
Changelog: 

- Rooms stopped receiving on accounts with many rooms. 0.27.0 widened the sync
window per room so the unread badge could count, and that number is
multiplied by the rooms in one request - which the room list grows to a
hundred at a time. On an account with two hundred rooms the request asked for
forty thousand events, timed out, and everything but the twenty most recent
rooms stopped updating, silently and for good. The window is back where it
was, and the badge now says where it stopped looking: it counts to twenty and
shows "20+" beyond, in the list and on the cover.
- The emoji comparison had no buttons. Verifying could not be finished from
that page at all in 0.26.2 and 0.27.0 - neither a device of one's own nor
another person - because the two answers were laid out in a way that gave
them a width of zero. They are back.
- Verifying another person moved out of the encryption page, where it sat as a
Matrix address to type in directly under the button that verifies one's own
second device. In a two-party encrypted chat the room's own menu now offers
it without asking for an address; for everybody else there is one entry in
the chat list's pull-down.
- The security page that comes up after signing in no longer stays on screen
once everything is green. Entering the recovery key settles it from the page
above, and coming back landed on the alarm that had just been cleared.
- A failed request stopped claiming there is no key backup. Asking the server
is a question over the network, and while a sync fault made the app believe
it was offline, the answer "could not ask" was read as "there is none" - so
the security page raised an alarm about a backup that was on the server all
along. It says the server could not be asked, and asks again once the
connection is back.
- The cover says when nothing is arriving. Being cut off was written under the
room's name and in the chat list, but not on the tile - and this app has no
background service, so the tile is how it is watched.
- Account has an error log now, at the top of its pull-down menu. Whatever
fails is kept there for the run, newest first, instead of flashing as a red
line on one page and being overwritten by the next failure. Identifiers are
already stripped by the core, so the list can be copied and passed on as it
stands. Nothing is written to disk.
- "Token is not active" no longer appears as an error. The sign-in token is
rotated in the background, and a download that was in flight across the
rotation came back with that message - which reads as an ended session while
the session is perfectly alive. It goes to the log; a session that really has
ended still signs out and says so.
- Everything a message can be done to is on a page now instead of a context
menu. That menu shares its machinery with the room's pull-down: opened on a
message near the top of the view it took the pull-down's place, and with that
on screen there was no way to leave the room, call, search it or open its
page at all.
- Forwarding works on attachments. A picture could only be forwarded from the
full-screen view, and every other attachment offered "Forward" and then sent
the file name as a sentence.
- Push notifications, asked for by users and off by default. They have their
own setting and do nothing until switched on by hand: Account › Push
notifications. A UnifiedPush distributor has to be installed separately - it
is the app that holds the connection, this client still has no background
service of its own - and a push gateway has to be chosen, because a
homeserver cannot talk to a distributor directly and nobody can guess whose
gateway you trust. Notifications carry no message text; the message is
fetched and decrypted on the device. What it does disclose, and to whom, is
written out in docs/PUSH.md - read that before turning it on. Leaving it off
changes nothing.
- A picture in a reply quote is shown whole and in a frame of its own. It was
cropped to a square out of the middle, which is where a photograph says the
least, and it lay against the reply's text with no edge to separate it.

Comments

kaulian's picture

Hello, Same revsiew for me about the new message action page for me

Sharks's picture

Thanks for continuing to develop this app.
Unfortunately, the latest update, which moves message actions to a new page rather than a context menu, has broken reactions. Selecting the react option just takes you back to the conversation without being asked for an emoji to react with.
On a personal note, I prefer the previous UI despite the drawbacks documented in the changlog. It's harder to choose what you want to do with the message (reply, react, forward, delete, etc.) when you can't see it onscreen

JimKnopfIoT's picture

@Sharks Yeah, you're right. I (and others) don't like the extra page either. It's a workaround for the Gemini in landscape mode. But it doesn't have that Sailfish feel. One critical comment called it “Windows 95-like.” It was a test/hotfix for an issue with the menu and the top message displayed, but it will be gone again starting with version 0.28.1.

stoefelz's picture

very nice

stiltskin's picture

impressive progress!

are there plans to implement 'new' audiocalls method later?

JimKnopfIoT's picture

@stiltskin This is a limitation by Jollas Qt 5.6. If, at some point in the future, call.element.io works in a native Sailfish browser, i can dig into it. Until then, it's a lost cause.

dumol's picture

Impressive work... Unfortunately, can't see bridged rooms on Beeper, even though I find "org.matrix.simplified_msc3575":true at https://matrix.beeper.com/_matrix/client/versions. Any ideas? Thanks!

Sharks's picture

A new bug I have noticed, attempting to play a video sent to me (via mautrix-meta, but probably from other sources too) crashes the app. Pictures come through fine, but videos are impossible to view.

JimKnopfIoT's picture

@Sharks  I can't reproduce it yet: mp4 videos play fine on all three of my devices, so it's likely something specific to the file or the device. A few things would let me pin it down:

1. Device model, cat /etc/sailfish-release (the VERSION_ID line) and rpm -q harbour-xmatic.
2. When exactly does it die — while the spinner is still turning, or after the first frame appears? Roughly how many seconds after you tap?
3. The journal while it happens. In a terminal: devel-su journalctl -f, then reproduce and send the last ~30 lines.
A kernel line with segfault or code=dumped is what I'm after.
4. Open the video page, wait for the spinner to finish, then use the pulley menu → Save. Does saving work? If yes, play that file from Downloads with the stock Gallery/video app. If the stock player fails too, it's the platform's codec support, not xmatic.
5. About the file: how large is it in MB, and is the room encrypted? If you can run ffprobe -hide_banner -i video.mp4 on a PC, that output answers everything at once. On the phone, head -c 4096 video.mp4 | strings |head -20 also helps — I'm looking for avc1 (H.264) versus hvc1/hev1 (HEVC) or av01 (AV1).
6. Does it happen with every video, or only ones from that bridge? A video sent from another Matrix client would be a useful comparison.

 

kempertom's picture

Such great work. I have an issue: I am using matrix chat with bridges to avoid using android. Voicenotes work with xmatic with mautrix (WhatsApp bridge) and the Telegram bridge, but not for the most important Signal bridge. It says that audio format is not supported for bridging. Maybe ist is possible from xmatic side?

JimKnopfIoT's picture

Fixed.

JimKnopfIoT's picture

Please try 0.24 and report if it's fixed for you.

Sharks's picture

Latest 0.22 update is great, very glad to see reaction support added. This now fully replaces Hydrogen for me on SFOS. Thankyou for your work!

The only feature I would still want for is an option to show the message content in notifications like an SMS notification would. Requiring to unlock the phone and open the app to see a message you may not be interested in responding to is a minor annoyance.

JimKnopfIoT's picture

Fixed.

stiltskin's picture

seems like there is no read status for messages (sent/read)

JimKnopfIoT's picture

Fixed.

windes's picture

Wow, man!! First impression - GREAT!  UI is smooth and nice, all balanced. Did you do UI by yourself, manually, not with AI?

 

Can't open page with user info. There's no this feature for now?

Sailfish 5.1.0.11, armv7hl - all is working)

Nice description, monumental, by the way. All questions gone right after read it. No water, strict and needed, every word.

Do you have a group of xmatic in matrix?

Sharks's picture

Looks promising! Unfortunately while I can login, I just see "Offline - Waiting for the network" glitching and flashing up the top, none of my chats get loaded.

JimKnopfIoT's picture

@Sharks Please read the new REQUIREMENTS section above and try again with the latest Version (> 0.19.0). 

Sharks's picture

It appears I am missing msc4186, thanks. Will have to look into it.

Sharks's picture

Have decomissioned my Dendrite server and spun up a Synapse one. xmatic is now working beautifully! Thanks very much. Keen to see further development, looks like a great app already.

kempertom's picture

Will it be frequently maintained? I have wishes and Ideas...

sourcrowd's picture

Thank you! With this client I'm finally able to login on a homeserver, that requires SSO for which the Firefox 91 WebView that SFOS 5.1 bundles, is too old.

kaulian's picture

Thanks a lot.

Manisak's picture

Damed I Love you ;-)

kempertom's picture

Wow. Wonderful. What are you plan to implement?