# Mullvad VPN client app: what the open source repository actually contains

> The mullvadvpn-app repository holds the full client for Mullvad's VPN service: a Rust daemon, a desktop GUI and CLI, and separate Android and iOS frontends. Here is what it ships, how to build it, and where it stops being the right tool.

**mullvad/mullvadvpn-app** — The Mullvad VPN client app for desktop and mobile

- Repository: https://github.com/mullvad/mullvadvpn-app
- Website: https://mullvad.net/
- Stars: 7,611 · Forks: 527
- Language: Rust
- License: GPL-3.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/mullvad-mullvadvpn-app

## Who the mullvadvpn-app repository is for

This is the client software for the Mullvad VPN service, not the service itself. The README describes the repository as containing all the source code for the desktop and mobile versions of the app. That sentence sets the boundary: you get the thing that talks to Mullvad's network, not the network. Anyone expecting to stand up their own VPN endpoint from this code is looking at the wrong project.

The audience is narrower than the download page suggests. There are three groups. First, people who want to read or audit the client that runs on their machine, which the repository supports by publishing external audit results in unredacted form under audits/. Second, distribution maintainers and packagers who need to build the app from source rather than ship a binary. Third, developers working on the client itself, who need the workspace to compile across desktop and mobile targets.

Ordinary users who just want a VPN do not need this repository at all. The README points them to built and signed releases for macOS, Windows, Linux and Android on mullvad.net/download and on GitHub, with the Android app also on Google Play and F-Droid and the iOS version on the App Store. Building from source is a maintainer or auditor activity, not a prerequisite for using the product.

## How the daemon, GUI, CLI and mobile frontends fit together

The architecture separates the tunnel and security logic from the user interface, and the repository layout makes that separation explicit. On desktop there are three parts: the system service or daemon in mullvad-daemon/, a graphical user interface in desktop/, and a command line interface in mullvad-cli/. The Android app, per the README, uses the same backing system service for the tunnel and security but has a dedicated frontend in android/. iOS is the outlier: it consists of a completely standalone implementation in ios/.

The Cargo workspace confirms how the pieces are named and grouped. The default-members list is deliberately small, containing mullvad-cli, mullvad-daemon, mullvad-problem-report and mullvad-version, and the comment in Cargo.toml explains why: a plain cargo build in the root directory should be fast and should avoid crates that need extra input to compile, naming windows-installer as an example. Everything else, including the talpid-* crates that handle routing, DNS, WireGuard and platform specifics, is a workspace member you opt into with --workspace.

That split has a practical consequence. The daemon and the CLI share the same management interface, so scripting against the CLI exercises the same code path the GUI uses. The mullvad-management-interface, mullvad-types and mullvad-api crates sit between the frontends and the tunnel layer, which is why the Android app can reuse the desktop service rather than reimplementing tunnel setup. iOS does not share that path, and the feature table reflects the divergence: split tunneling is marked available on Windows, Linux, macOS and Android but not iOS, and the README notes that the local network is always accessible on iOS with the current implementation.

## Cloning and building the Mullvad VPN app from source

The README is explicit that a recursive clone is the wrong move. Some submodules contain further submodules that are large and not needed to build the app, so the documented sequence is a normal clone followed by one level of submodule initialization.

```bash
git clone https://github.com/mullvad/mullvadvpn-app.git
cd mullvadvpn-app
git submodule update --init
```

After this, the checkout is complete but the submodules are not recursive. One of them, dist-assets/binaries, holds third party binaries and build scripts that get bundled with the app, Wintun among them. The README states that this submodule follows the same integrity rules as the main repository: every merge commit should be signed, and the main repository should only ever point at a signed merge commit of that submodule.

Building is platform-specific and the README does not inline the steps. It points to BuildInstructions.md for desktop platforms, android/docs/BuildInstructions.md for Android and ios/BuildInstructions.md for iOS. Before starting, check docs/supported-platforms.md, which the README says lists supported operating systems, versions and architectures and which ones the automated test suite covers.

The Cargo.toml comment states that default members dictate what is built when running cargo build in the root directory, and that the list is set to a minimal set of packages to speed up the build and avoid building crates which might not compile without additional input, such as the windows-installer crate. It also notes that to build or test everything you add --workspace to your cargo commands. That is the only build command the repository files in front of me spell out, so treat the platform documents as the place where the real steps live.

## The feature table is the map of what the client will not do for you

Mullvad publishes a platform feature matrix in the README, and it is unusually honest about gaps. WireGuard, quantum-resistant tunnels, DAITA, WireGuard multihop, WireGuard over TCP, over Shadowsocks, over QUIC, lightweight WireGuard obfuscation, custom DNS server and content blockers are all marked available across Windows, Linux, macOS, Android and iOS. Split tunneling is the exception, marked for the four desktop and Android platforms but absent for iOS.

The README adds a caveat that is easy to miss: the table is intended to reflect the current state of the latest code in git, not necessarily any existing release. If you are comparing platforms before installing a signed build, the table can be ahead of what you have. That is a real limitation of using the repository as documentation.

The design philosophy behind these defaults is stated plainly. The README calls the app privacy preserving and says it goes to great lengths to stop traffic leaks, with basically all settings defaulting to the more secure or private option, requiring the user to explicitly allow looser rules. docs/security.md is cited for the details of what the app blocks and allows. That default-deny posture is a deliberate trade-off: it means the client will block traffic in situations where a more permissive client would simply let it through, and the user has to understand which switch to flip. For someone who wants a client that never gets in the way, this is friction by design.

## Where this repository is the wrong tool

The clearest failure mode is category error. This is client software for a commercial VPN service. If your goal is a self-hosted tunnel on your own hardware, the daemon here is built around Mullvad's relay selection, account model and API, and the README describes the service as the thing you visit mullvad.net to learn about. Nothing in the repository suggests it can be pointed at your own server, and the mullvad-api and mullvad-relay-selector crates are named for exactly the opposite arrangement.

A second boundary is platform support. The README does not promise that every platform builds, only that docs/supported-platforms.md states which operating systems, versions and architectures are supported and which are covered by automated tests. An unsupported architecture may still compile, but the test coverage claim does not extend to it, and the README does not document a fallback.

A third is build complexity. The workspace excludes ci/ios/test-router/raas and the Cargo.toml comment warns that some crates, windows-installer specifically, might not compile without additional input. A recursive clone is discouraged because of submodule size. This is a repository that assumes you are following its build documents, not improvising.

Finally, iOS is effectively a separate codebase. The README calls it a completely standalone implementation, so any reasoning you do from the shared desktop and Android service does not transfer. Split tunneling is missing there, and local network access behaves differently.

## How Mullvad VPN compares with a self-hosted WireGuard setup

The honest alternative is running WireGuard yourself on a VPS. Both use WireGuard as the tunnel protocol, so the cryptographic core is not the differentiator. What changes is everything around it.

With a self-hosted setup, you own the endpoint, which means you own key distribution, relay uptime, IP reputation and the operational work of keeping a server patched. There is no relay selection to fall back to when a node is blocked, no multihop option, and no obfuscation layer. The Mullvad client's feature list is largely a list of answers to those problems: WireGuard over TCP, over Shadowsocks, over QUIC and lightweight WireGuard obfuscation exist because plain WireGuard to a single endpoint is easy to identify and block. DAITA, described in the README as Defense Against AI-Guided Traffic Analysis, has no equivalent in a stock self-hosted deployment.

The trade is control for capability. A self-hosted tunnel gives you a dedicated IP and no third party in the path. The Mullvad client gives you a shared, rotating relay fleet and the obfuscation and analysis-resistance features built on top, at the cost of trusting an operator and paying for the service. If your threat model centers on a single operator seeing your traffic, self-hosting wins on paper. If it centers on the tunnel being detected and blocked, the feature matrix in this repository is the argument for the client.

## Maintenance, releases and what the GPL-3.0 licence means here

The repository is not archived, and the last push was on 2026-09-21. Releases are frequent and versioned per platform: the recent list includes android/2026.10 on 2026-09-17, android/2026.9 on 2026-09-15 and 2026.5 on 2026-09-14. The Android and desktop version numbers move on separate tracks, so a version string alone does not tell you which platform it belongs to.

Upgrade cost depends on how you consume the project. If you install signed builds, the README says they are available on mullvad.net/download and GitHub, with Android also on Google Play and F-Droid. If you build from source, you carry the toolchain burden: the workspace pins rust-version to 1.97.1 and notes it must be less than or equal to the channel in rust-toolchain.toml, so a Rust upgrade on your machine can break the build until the pinned channel is respected.

The licence is GPL-3.0, per the LICENSE.md file in the repository root and the project metadata. That is a copyleft licence, and the practical implication for anyone embedding this code in another product is that derivative distributions carry source disclosure obligations. This is not legal advice; if you plan to redistribute a modified client, the terms of GPL-3.0 and the trademark questions around the Mullvad name are worth raising with a lawyer.

On process, the repository is unusually strict. The README states that all merge commits to main must be PGP signed in git, which signs off the entire feature branch, with individual commits exempt unless they touch files listed in the verify-locked-down-signatures workflow. The project also reports external audits every second year, published unredacted in audits/, and carries an OpenSSF Best Practices badge.

## Conclusion

Adopt this repository if you are auditing the Mullvad client, packaging it for a distribution, or building the desktop app from source; it is a client for a paid service, not a self-hosted VPN, so it is the wrong tool if you want to run your own server. Before building, check docs/supported-platforms.md for your OS and architecture, confirm the Rust version in rust-toolchain.toml against the workspace's rust-version of 1.97.1, and verify the signed merge commits and release tags rather than trusting an unsigned checkout.

## FAQ

### Why would someone use Mullvad VPN?

The README frames the app as a privacy preserving client that goes to great lengths to stop traffic leaks, with settings defaulting to the more secure option so the user must explicitly allow looser rules. The feature set includes WireGuard, quantum-resistant tunnels, DAITA, multihop and several obfuscation transports across all five supported platforms.

### Does the Mullvad VPN app have a mobile app?

Yes. The repository contains an Android frontend in android/ that uses the same backing system service for the tunnel and security as desktop, and a completely standalone iOS implementation in ios/. Signed Android releases are also distributed on Google Play and F-Droid, and the iOS version on the App Store.

### Was Mullvad VPN raided by the police?

The repository does not discuss any raid or law enforcement action. The README covers the client source, build and release process, supported platforms, security defaults and published audits, and says nothing about police activity.

## Sources

- [License: GPL-3.0](https://github.com/mullvad/mullvadvpn-app/blob/main/LICENSE)
- [mullvad/mullvadvpn-app on GitHub](https://github.com/mullvad/mullvadvpn-app)
- [Project website](https://mullvad.net/)
- [README](https://github.com/mullvad/mullvadvpn-app/blob/main/README.md)
- [Releases](https://github.com/mullvad/mullvadvpn-app/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mullvad-mullvadvpn-app
