Session Desktop: a private messenger on Oxen service nodes
Session Desktop - A Decentralized, Onion Routed, Private Messenger
At a glance
- What is it?
- Session Desktop is the Electron client for Session, a messenger that stores messages on decentralized Oxen service nodes and routes them over onion routing instead of a central server. The repository publishes signed builds, a Debian repository and a pnpm-based build you can run yourself.
- Who is it for?
- Session Desktop suits users who want a messenger without a central server in the path and who are willing to verify release signatures before installing. It is the wrong tool if you need a synchronous voice or video stack, a corporate compliance story or a client your organisation can centrally update.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Session Desktop is and where the service nodes fit
Session Desktop is the desktop client for Session, a messenger whose distinguishing feature is that there is no company operating the server you talk to. The repository description calls it a decentralized, onion routed, private messenger, and the README frames it as private messaging from your desktop with the download hosted at getsession.org.
The mechanism is worth understanding before the code. Session integrates directly with Oxen Service Nodes, which the README describes as a set of distributed, decentralized and Sybil resistant nodes. Those nodes act as servers which store messages offline, so a message is held by a set of nodes rather than by one operator, and a second set of nodes provides the onion routing that obfuscates users' IP addresses. The README points to the Session Whitepaper for the full picture.
That architecture has consequences for how you use the client. Delivery is not the instant, guaranteed send that a server-backed messenger gives you, because the network has to route and store on your behalf, and the storage model means a message can sit on nodes before it is collected. The client is where that behaviour becomes visible, which is why the project invests in the desktop app rather than treating it as a thin shell.
The project is version 1.18.x, with v1.18.2 published on 2026-10-13, v1.18.1 on 2026-07-10 and v1.18.0 on 2026-04-09, and the package manifest records the same 1.18.2 version. The repository was last pushed on 2026-10-19 and is not archived.
Verifying a release with GPG and SHA-256 before you install it
The README documents signature verification in four steps, and for a messenger this is the most useful part of the documentation to read. The signer is named directly: Jason Rhinelander, a member of the Session Technology Foundation, is the current signer for all Session Desktop releases, and his GPG key is on his GitHub and other sources.
Step one is importing that key.
wget https://github.com/jagerman.gpg
gpg --import jagerman.gpgStep two fetches the signed hashes for the release, with the version taken from an environment variable so the same commands work for any release.
export SESSION_VERSION=1.15.0
wget https://github.com/session-foundation/session-desktop/releases/download/v$SESSION_VERSION/signature.ascStep three verifies the signature over the hashes file, and the README states what a good result looks like: the output should print Good signature from Jason Rhinelander. If it does, the hashes are valid, though the README is careful to add that this alone is not enough, because the signed hashes still have to match the file you actually downloaded.
gpg --verify signature.asc 2>&1 |grep "Good signature from"Step four does that comparison, and the commands differ per platform. On Linux it hashes the .deb package, on macOS it hashes the arm64 or x64 .dmg, and on Windows there are two forms, a PowerShell Get-FileHash call and a bash sha256sum alternative. The README notes that the PowerShell checksum is uppercase but should otherwise match.
sha256sum session-desktop-linux-amd64-$SESSION_VERSION.deb
grep .deb signature.ascThat structure is deliberate. Verifying a detached signature over a list of hashes, then hashing the download and comparing, is the pattern that lets a single signature cover every platform artifact of a release without signing each binary.
Installing on Linux, macOS and Windows
Prebuilt binaries are downloaded from getsession.org, and the README points at the release page for the list of supported platforms and the system requirements, which is where you should check before picking an artifact.
On Linux there is a dedicated Debian repository at deb.oxen.io, which is the smoother path for a machine that manages packages with apt rather than a manual install of a .deb file.
The verification commands above double as the installation guide in practice, since they name the exact artifacts: a Debian package for Linux, an Apple Silicon or Intel disk image for macOS, and a Windows executable for x64. The README's macOS instructions point at the arm64 image first and the x64 image as the alternative, which matches the current split in Apple hardware.
For anyone who wants to run the client without trusting a downloaded binary at all, the build instructions live in CONTRIBUTING.md rather than in the README, and the project also ships an internal build document, INTERNALBUILDS.md, alongside a release process description in RELEASING.md. Building from source is the option with the strongest supply chain story and the highest maintenance cost, since you own the toolchain.
Inside the Electron codebase: workers, protos and stylesheets
The repository layout describes the architecture more honestly than a feature list would. The application is an Electron app with its entry point at ts/mains/main_node.js and the app itself under an app directory, and the TypeScript source lives in ts. Several build configurations target distinct pieces: a libsession worker config, a utils worker config and an image processor worker config, which shows that the heavy work is pushed out of the main process into workers rather than run on the UI thread.
Protocol buffers are central, with a protos directory and a build script that runs pbjs to compile the .proto files into a static module and pbts to emit the TypeScript declarations. The protos directory is where the wire format between the client, the service node network and the storage layer is defined, and the compiled output lands in ts/protobuf.
The presentation layer is separated by concern as well, with a stylesheets directory, a sass.config.js for Sass compilation, an svgs directory with its own webpack config, fonts, images and sound directories, and a THEMES.md document. The presence of a dedicated themes document suggests that appearance is a supported axis of customisation rather than a hard-coded skin. There is also an actions directory, which in this layout is the Redux-style action layer, and a patches directory, which usually holds patches applied to dependencies during build.
The quality tooling is modern and layered. ESLint is configured with local rules in eslint-local-rules.js and separate rule directories, Prettier handles formatting with its own configuration, husky and lint-staged manage commit hooks, and there is a .pylintrc alongside a .mocharc.json, which points to Python tooling somewhere in the build. A commitlint configuration enforces commit message conventions, which is a strong signal about how a project with many contributors keeps its history readable.
Building, contributing and the dependency pinning
The package manifest pins the package manager to pnpm 10.28.1, and the repository carries both pnpm-lock.yaml and pnpm-workspace.yaml. The scripts show the development loop: start-dev and start-prod run the app through Electron with cross-env setting NODE_ENV and a NODE_APP_INSTANCE value, and there are pretty variants that pipe the output through pino-pretty for readable logs.
A performance script is worth noticing, because it is the kind of thing most projects keep private. start-perf launches Electron with the V8 inspector on port 9229, with precise memory information enabled and the V8 flags that expose garbage collection and native syntax, which together give you a CPU profile and a reliable memory measurement of the renderer and workers.
The dependency pinning is unusually aggressive for a desktop app. The manifest lists a resolutions block that overrides transitive versions of lodash, react at 19.2.1, redux at 5.0.1, reselect, nanoid, linkify-it and the types for react, node and libsodium-wrappers. That is the pattern of an application that has been bitten by a transitive upgrade and pinned it deliberately. It also means the build is reproducible in a way most Electron apps are not.
Contributing runs through pull requests against the development branch rather than the main one, and the README asks people to search existing issues first to avoid duplicates. Issues tagged good-first-issue are the suggested entry point for newcomers, and CONTRIBUTING.md holds the build instructions for anyone who wants to work on the code.
Licence, attributions and where Session Desktop is not the right choice
The licence is GPLv3, and the README keeps a full copyright chain: 2011 Whisper Systems, 2013 to 2017 Open Whisper Systems, 2019 to 2024 The Oxen Project, and 2024 to 2025 the Session Technology Foundation. The project has been renamed twice and the licence has not changed, which tells you the code lineage is continuous rather than a rewrite.
Two third-party attributions are recorded. The IP-to-country mapping data used for showing a user's country comes from MaxMind GeoLite2, which carries its own terms and its own update cadence, and the Lucide Icon Font is used under the ISC licence with the text kept in the third_party_licenses directory. That directory existing at all is a good sign, since most projects that vendor assets do not keep the licences next to them.
The wrong-tool case is worth being concrete about. Session is a messenger, and the desktop client covers messaging, not the rest of a communications suite. There is no voice or video calling stack in the repository, no screen sharing, no meeting room, and no enterprise administration console, so a team that needs those has to look elsewhere. The other mismatch is operational: because there is no central operator, there is also no central support, no SLA and no forced key rotation schedule, and an outage of the service node network is an outage of the network rather than of one company's service.
The alternative is the reference implementation of the same protocol at a different layer. The desktop app embeds libsession through its worker configuration, which means a team that needs a client with a very different user interface can build on the same library rather than on this repository, keeping the network and storage behaviour identical while replacing the interface entirely. The trade is that you own the interface work, the packaging and the signature-verification story that this repository already handles.
Editorial conclusion
Session Desktop suits users who want a messenger without a central server in the path and who are willing to verify release signatures before installing. It is the wrong tool if you need a synchronous voice or video stack, a corporate compliance story or a client your organisation can centrally update. Verify first that the signature on the release hashes says Good signature from Jason Rhinelander, that the SHA-256 of the file you downloaded matches the signed hash for your platform, and that the service node network you depend on is the one the README describes.
Frequently asked questions
What is Session Desktop?
It is the desktop client for Session, the private messenger that stores messages on Oxen Service Nodes and uses onion routing to obfuscate users' IP addresses. The client is an Electron application and the license is GPLv3.
How do I verify a Session Desktop release?
Import Jason Rhinelander's GPG key, download the signed signature.asc for the release, verify it with gpg so the output reads Good signature from Jason Rhinelander, then compare the SHA-256 of the downloaded file for your platform with the hash listed in signature.asc.
Is there a Debian package repository for Session Desktop?
Yes. The README points to a Debian repository at deb.oxen.io, alongside the prebuilt downloads hosted at getsession.org.
What do Oxen Service Nodes do in Session?
According to the README they act as servers that store messages offline, and a set of them provides the onion routing functionality that obfuscates users' IP addresses. The nodes are described as distributed, decentralized and Sybil resistant.
How do you build Session Desktop from source?
The README points to CONTRIBUTING.md for build instructions. The repository pins pnpm 10.28.1 as its package manager, compiles the protocol buffers with pbjs and pbts, and builds the stylesheets and SVG assets with webpack.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/session-foundation-session-desktop)Was this useful?