# How to Contribute Code to the Amnezia-Client Project: A Complete Developer's Guide

> Contribute code to the Amnezia-Client project easily. Follow this guide to fork, build, test, and submit pull requests for the amnezia-vpn/amnezia-client repository.

- Repository: [Amnezia VPN/amnezia-client](https://github.com/amnezia-vpn/amnezia-client)
- Tags: how-to-guide
- Published: 2026-07-29

---

**To contribute code to the amnezia-client project, fork the amnezia-vpn/amnezia-client repository, set up a Qt 6 and CMake build environment, verify your changes compile across target platforms using the deploy scripts, and submit a pull request against the `dev` branch with properly formatted code.**

Contributing to this cross-platform VPN client requires understanding its modular Qt/C++ architecture. The amnezia-vpn/amnezia-client repository splits functionality between the graphical interface, background service daemon, and server-side helpers, with build automation handled by CMake and Conan. This guide covers the complete workflow from environment setup to submission, referencing specific source files and build commands used by the maintainers.

## Prerequisites and Development Environment

Before modifying any source files, install the required toolchain. The amnezia-client project builds with **CMake 3.21+**, **Qt 6.10+** (Core, Qt 5 Compatibility, and Remote Objects modules), and **Conan** for dependency management.

**Platform-specific requirements:**

- **Linux:** GCC toolchain and `make`
- **macOS:** Xcode or Xcode command-line tools (Qt available via `homebrew install qt@6`)
- **Windows:** Visual Studio 2022 or Build Tools
- **Android:** Android SDK, NDK, and Ninja

Most continuous integration jobs use the scripts in `deploy/`, which auto-detect dependencies if installed in default locations.

## Setting Up the Repository

Clone the repository and initialize submodules to pull vendored dependencies like OpenVPN and WireGuard:

```bash
git clone https://github.com/amnezia-vpn/amnezia-client.git
cd amnezia-client
git checkout dev
git submodule update --init --recursive

```

Always work against the `dev` branch, as `main` reflects stable releases.

## Building the Project

The `deploy/` directory contains platform-specific build scripts that invoke CMake with the correct toolchain settings.

### Unix-like Systems (Linux/macOS)

```bash
./deploy/build.sh                # Build host executables

./deploy/build.sh --installer all   # Build installer packages

```

### Windows

```cmd
deploy\build.bat                 # Build host executables

deploy\build.bat --installer ifw   # Build with Qt Installer Framework

```

### Android

```bash
./deploy/build.sh -t android --aab   # Build Android App Bundle

```

These scripts automatically set `QT_INSTALL_DIR`, `ANDROID_HOME`, and other environment variables. Run `deploy/build.sh -h` to view all available options.

## Understanding the Architecture

The codebase organizes functionality into three high-level components. Knowing where to place your code ensures clean integration.

**Client UI** (`client/`)

Desktop and mobile graphical interfaces built with Qt 6. Key files include [`client/vpnConnection.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/vpnConnection.cpp), which handles UI-level connection states and persists user settings via `QSettings`.

**Service** (`service/src/`)

The background daemon controlling VPN containers and platform networking. The entry point is [`service/src/qtservice.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/service/src/qtservice.cpp), which exposes a common `QtService` interface regardless of platform. Platform-specific adapters like [`qtservice_win.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/qtservice_win.cpp) and [`qtservice_unix.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/qtservice_unix.cpp) implement OS-level details.

**Server Helpers** (`service/server/`)

Pure C++ utilities for managing Docker-based VPN containers (XRay, WireGuard, OpenVPN). For example, [`service/server/xray.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/service/server/xray.cpp) wraps the XRay core binary, while [`service/server/router_linux.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/service/server/router_linux.cpp) handles routing tables.

All components communicate via the IPC layer defined in `ipc/ipc_interface.rep`, with shared utilities located in `common/`.

## Making Changes

### Adding UI Features

When extending the interface, inherit from `QWidget` or `QMainWindow` and register new files in [`client/CMakeLists.txt`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/CMakeLists.txt). For example, adding an auto-connect toggle in [`client/vpnConnection.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/vpnConnection.cpp) follows this pattern:

```cpp
void VpnConnection::toggleAutoConnect(bool enabled) {
    QSettings settings;
    settings.setValue(QStringLiteral("AutoConnect"), enabled);
    emit autoConnectChanged(enabled);
}

```

### Extending Service Logic

To add functionality accessible from the UI, modify the IPC interface definition in `ipc/ipc_interface.rep`:

```cpp
[method] GetLatestRelease()
{
    string tag;
}

```

After editing the `.rep` file, the CI generates the corresponding C++ stub ([`ipc/ipc_interface.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/ipc/ipc_interface.cpp)). Implement the logic in [`service/src/qtservice.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/service/src/qtservice.cpp), where platform-agnostic code calls the appropriate adapter.

### Adding Server Protocols

New VPN protocols require extending the server helpers. Follow the existing pattern in [`service/server/router_linux.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/service/server/router_linux.cpp):

```cpp
bool RouterLinux::addRoute(const QString &cidr) {
    QString cmd = QStringLiteral("ip route add %1 dev %2")
                  .arg(cidr, m_interface);
    return system(cmd.toLocal8Bit().data()) == 0;
}

```

Register new source files in [`service/server/CMakeLists.txt`](https://github.com/amnezia-vpn/amnezia-client/blob/main/service/server/CMakeLists.txt) and ensure they follow the `*.cpp`/`*.h` naming convention.

## Code Quality and Submission

The project enforces code standards through automated checks. Before submitting:

1. **Verify formatting** using the project's `clang-format` configuration:

   ```bash
   git clang-format --style=file -i $(git diff --name-only)
   ```

2. **Build locally** on your target platform using the `deploy/build.*` scripts to catch compilation errors early.

3. **Update documentation** in [`README.md`](https://github.com/amnezia-vpn/amnezia-client/blob/main/README.md) if your change affects user-visible behavior or build requirements.

4. **Submit a Pull Request** against the `dev` branch with a clear description of what changed and how to test it.

The CI pipeline automatically runs the build scripts for all supported platforms (Linux, macOS, Windows, Android, iOS) and checks formatting compliance.

## Summary

- **Fork and branch** from `amnezia-vpn/amnezia-client:dev` to isolate your changes.
- **Use the deploy scripts** ([`deploy/build.sh`](https://github.com/amnezia-vpn/amnezia-client/blob/main/deploy/build.sh) or `deploy/build.bat`) to ensure consistent CMake configuration across platforms.
- **Place UI code** in `client/`, service logic in `service/src/`, and Docker helpers in `service/server/`.
- **Update IPC definitions** in `ipc/ipc_interface.rep` when changing the UI-service contract.
- **Run `git clang-format`** before committing to match the project's style requirements.
- **Reference specific files** like [`qtservice.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/qtservice.cpp) and [`vpnConnection.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/vpnConnection.cpp) to understand implementation patterns.

## Frequently Asked Questions

### Which branch should I target for pull requests?

Always open pull requests against the `dev` branch. The `main` branch contains stable releases, while `dev` receives active development and integration testing. The repository maintainers merge `dev` into `main` during release cycles.

### How do I format my code to match the project style?

Run `git clang-format --style=file -i $(git diff --name-only)` before committing. The repository includes a `.clang-format` file that defines the style rules. The CI pipeline rejects pull requests that introduce formatting violations, so local verification prevents delays.

### Can I build the Android client on Linux or macOS?

Yes. Use `./deploy/build.sh -t android --aab` to generate Android App Bundle files on either Linux or macOS. Ensure you have the Android SDK, NDK, and Ninja installed, and set `ANDROID_HOME` environment variable. The script handles the CMake toolchain configuration automatically.

### What is the purpose of the `.rep` files in the `ipc/` directory?

The `ipc/ipc_interface.rep` file defines the Remote Objects interface used for communication between the UI (`client/`) and the background service (`service/`). When you add new methods to this interface, the Qt Remote Objects compiler generates the necessary proxy and replica classes. You must implement the service-side logic in [`service/src/qtservice.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/service/src/qtservice.cpp) and invoke it from the UI side through the generated interface.