# Amnezia VPN Client Main Entry Point: Qt Boot Sequence in client/main.cpp Explained

> Discover the Qt boot sequence for the Amnezia VPN client. Explore client/main.cpp to understand how the application initializes, migrates config, and starts the local server.

- Repository: [Amnezia VPN/amnezia-client](https://github.com/amnezia-vpn/amnezia-client)
- Tags: internals
- Published: 2026-07-28

---

**The Amnezia VPN client starts execution in [`client/main.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/main.cpp), where the standard C++ `main()` function initializes the Qt application, runs configuration migrations, and launches the local server before starting the event loop.**

Understanding the main entry point for the Amnezia VPN client is essential for anyone auditing the startup behavior or contributing to the `amnezia-vpn/amnezia-client` repository. In [`client/main.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/main.cpp), the `main()` function orchestrates a precise sequence of migration checks, singleton prevention, GUI setup, and service initialization. This article breaks down every step of that boot pipeline using the actual source code.

## The Role of client/main.cpp in the Startup Pipeline

The file [`client/main.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/main.cpp) serves as the single entry point for the desktop client. It defines `int main(int argc, char *argv[])`, which the linker invokes when the operating system loads the binary.

According to the `amnezia-vpn/amnezia-client` source code, this function does not immediately start the GUI. Instead, it performs pre-flight initialization to ensure the runtime environment is stable and only one instance is running on desktop platforms.

## Six-Step Boot Sequence in main.cpp

The `main()` function in [`client/main.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/main.cpp) executes the following high-level tasks in order:

1. **Run migrations** – Instantiates `Migrations` and calls `doMigrations()` to upgrade the user's configuration and database schema.
2. **Initialize the Qt application** – Creates `AmneziaApplication`, sets up OS signal handling via `OsSignalHandler::setup()`, and initializes libssh with `ssh_init()`.
3. **Prevent multiple instances** – On non-mobile platforms, checks for an existing instance using `isAnotherInstanceRunning()`; if found, it schedules a quit and enters the event loop briefly.
4. **Start the local server** – If this is the primary instance, it calls `app.startLocalServer()` to establish IPC.
5. **Register QML types and load fonts** – Prepares the UI layer by calling `app.registerTypes()` and `app.loadFonts()`, then parses CLI arguments with `app.parseCommands()`.
6. **Launch the event loop** – When parsing indicates the app should run, it calls `app.init()` followed by `app.exec()` to start the Qt event loop.

## Entry Point Code Breakdown

The following excerpt from [`client/main.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/main.cpp) shows the complete initialization flow:

```cpp
int main(int argc, char *argv[])
{
    Migrations migrationsManager;
    migrationsManager.doMigrations();

    AmneziaApplication app(argc, argv);
    OsSignalHandler::setup();

    ssh_init();
    QObject::connect(&app, &QCoreApplication::aboutToQuit, []() {
        ssh_finalize();
    });

    // Prevent duplicate instances on desktop platforms
    if (isAnotherInstanceRunning()) {
        QTimer::singleShot(1000, &app, [&]() { app.quit(); });
        return app.exec();
    }
    app.startLocalServer();

    app.registerTypes();
    app.loadFonts();

    bool doExec = app.parseCommands();
    if (doExec) {
        app.init();
        return app.exec();
    }
    return 0;
}

```

## Key Files in the Startup Sequence

Several headers and classes support the main entry point. Each plays a distinct role in the client bootstrap:

- **[`client/amneziaApplication.h`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/amneziaApplication.h)** – Defines `AmneziaApplication`, the core Qt-based application class that handles QML registration, font loading, and command parsing.
- **[`client/core/utils/migrations.h`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/core/utils/migrations.h)** – Declares the `Migrations` class responsible for configuration and database schema upgrades via `doMigrations()`.
- **[`client/localserver.h`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/localserver.h)** – Provides the internal IPC layer; its `startLocalServer()` method enables communication between the UI and background services.
- **[`client/core/utils/osSignalHandler.h`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/core/utils/osSignalHandler.h)** – Implements `OsSignalHandler::setup()`, which registers OS-level signal handlers for graceful shutdown.

## How Instance Locking Works on Desktop

Before fully initializing the GUI, the entry point ensures only one client process owns the session. The function `isAnotherInstanceRunning()` attempts to bind a local socket. If another process already holds it, the current instance triggers `QTimer::singleShot(1000, &app, [&]() { app.quit(); })`, enters the event loop with `app.exec()`, and exits cleanly after the timeout. This guards against duplicate tray icons and conflicting VPN states.

## Summary

- The **Amnezia VPN client main entry point** is [`client/main.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/main.cpp), which contains the standard `int main(int argc, char *argv[])` function.
- Startup begins with **configuration migrations** via `Migrations::doMigrations()` to ensure schema compatibility.
- The **Qt application** is instantiated through `AmneziaApplication`, followed by **libssh initialization** and **OS signal handling**.
- A **local socket check** prevents multiple desktop instances from running simultaneously.
- If this is the primary instance, `startLocalServer()` launches the IPC backend before the UI layer registers QML types and fonts.
- Finally, `app.exec()` enters the Qt event loop and the client becomes interactive.

## Frequently Asked Questions

### Where is the main entry point for the Amnezia VPN client application?

The main entry point is [`client/main.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/main.cpp) in the `amnezia-vpn/amnezia-client` repository. This file defines the `main()` function that the operating system calls when the application launches.

### What does the Amnezia VPN client do before starting the GUI?

Before any UI appears, the client runs configuration migrations, initializes libssh with `ssh_init()`, sets up OS signal handlers, and verifies that no other instance is running. It also starts a local IPC server via `startLocalServer()` to support background services.

### How does the Amnezia VPN client prevent multiple instances?

The `main()` function in [`client/main.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/main.cpp) checks `isAnotherInstanceRunning()`, which tests a local socket. If the socket is already held by another process, the new instance schedules a one-second quit timer and returns from the event loop without fully initializing.

### Which class manages the Qt application lifecycle?

`AmneziaApplication`, declared in [`client/amneziaApplication.h`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/amneziaApplication.h), manages the lifecycle. It encapsulates command-line parsing, QML type registration, font loading, and ultimately runs the event loop through its inherited `exec()` method.