# How I Run Affinity V2 on NixOS with affinity-nix

Run Affinity Photo 2, Designer 2, and Publisher 2 on NixOS with affinity-nix, local official installers, persistent Wine state, and a declarative flake configuration.

Author: Ruhani Rabin
Canonical: https://rabin.blog/run-affinity-v2-on-nixos/
Published: 2026-09-20T13:00:00.000Z
Updated: 2026-10-26T10:58:06.000Z

I have owned the Affinity V2 Universal License for a while, and I still had the complete Windows installations for Photo 2, Designer 2, and Publisher 2 on one of the Windows drive.

They were surprisingly portable on Windows. I had previously reinstalled Windows 11, opened the applications from their old location. After that, entered my license details, and moved on using them.

Linux was the more interesting question.

Could I run Affinity Photo 2 properly on NixOS without turning the machine into a science project of Wine-prefix six months later?

The answer, as of Affinity V2 2.6.5, is **yes**. It is not native Linux software, and one acceleration feature still remains unavailable, but the actual editing workflow worked:

* Affinity Photo launched repeatedly;
* my V2 Universal License activated from the built-in account page;
* existing documents opened;
* PSD, PNG, and WebP exports worked;
* the NVIDIA GPU appeared as the renderer;
* preferences and UI scaling persisted between launches.

This is how I tested it, avoided downloading several gigabytes of installers again, and then moved it into my declarative NixOS configuration.

**Warning**: [`mrshmllow/affinity-nix`](https://github.com/mrshmllow/affinity-nix) is community packaging. It is not maintained or supported by Affinity, Serif, or Canva. Affinity under Wine is also not perfect, so keep a known-good Windows path for work you absolutely cannot afford to surprise you.

I also did something similar with [the process of installing ChatGPT+Codex](https://rabin.blog/install-chatgpt-codex-desktop-app-declaratively-nixos/) but this one is a bit more time-consuming and complex.

## TLDR;

The short version is:

1. Run Affinity Photo temporarily with `nix run`.
2. Allow the unfree package for that command.
3. If the upstream installer downloads are slow, download the official V2 2.6.5 MSI/EXE installers from your Affinity account.
4. Verify that they match the hashes expected by `affinity-nix`.
5. Import them into the Nix store instead of manually copying anything into `/nix/store`.
6. Launch Photo, set Wine to 144 DPI if the interface is tiny, and activate the license from **My Account**.
7. Once the trial works, pin `affinity-nix` in `flake.lock` and declare the applications normally.
8. Back up `~/.local/share/affinity/`, but never commit it or the proprietary installers to Git.

The first test command is:

```bash
NIXPKGS_ALLOW_UNFREE=1 nix run --impure \
  github:mrshmllow/affinity-nix#affinity-photo
```

Do not be surprised if the first build is large and severely time consuming. More on this, later in this article.

## Why I used affinity-nix

I already had Bottles installed, and manually creating a Wine prefix was still an option. But [`affinity-nix`](https://github.com/mrshmllow/affinity-nix) fits NixOS better.

It builds the Wine environment and dependencies through Nix, then mounts an overlay at runtime so user preferences remain writable. The immutable package and mutable state is unchanged instead of slowly becoming one unrepeatable prefix.

The V2 packages are:

```text
affinity-photo
affinity-designer
affinity-publisher
```

There is one slightly surprising detail: the three V2 applications share the same prepared prefix. Running only `affinity-photo` may cause Photo, Designer, and Publisher sources to be fetched and extracted.

That confused me at first when the terminal said it was downloading Publisher while I had asked for Photo. It was not installing random software behind my back. It was preparing the shared V2 environment used by all three launchers.

```mermaid
flowchart TB
    A["🔒 flake.lock"]
    B["📦 affinity-nix + Wine dependencies"]
    C["🧱 Shared Affinity V2 prefix"]
    D["🖼️ Photo 2"]
    E["✒️ Designer 2"]
    F["📚 Publisher 2"]
    G["💾 ~/.local/share/affinity/"]
    H["🗄️ Backrest"]


    A --> B --> C
    C --> D
    C --> E
    C --> F
    G <-->|"preferences, activation, Wine overlay"| C
    G --> H
```

## First run: allow the unfree package

Running the simple command directly gave me this error:

```text
Refusing to evaluate package 'affinity-photo-2.6.5'
because it has an unfree license ('unfree')
```

For a one-off flake command, use the temporary environment variable and `--impure` together:

```bash
NIXPKGS_ALLOW_UNFREE=1 nix run --impure \
  github:mrshmllow/affinity-nix#affinity-photo
```

`--impure` is required here because the flake must be allowed to read `NIXPKGS_ALLOW_UNFREE` from the environment.

This does not permanently change the NixOS configuration.

## The first run can take forever

The project provides an optional binary cache at [`cache.forall.systems`](https://cache.forall.systems/). That cache provides Wine, helper tools, and other non-proprietary build results.

It deliberately does **not** cache the proprietary Affinity archives.

**This note in the upstream README means**:

```text
This repo does not attempt to redistribute affinity archives.
Any instance of caching Canva IP should be reported as a bug.
```

The Nix expressions still tell the local machine where to fetch the required Affinity installers and which hashes to expect. The installers are downloaded and verified on your machine. They are not served from the project’s binary cache.

My initial run spent a very long time downloading (I stopped the download at 97 minutes) the three V2 2.6.5 installers from Archive.org. Archive.org downloads are super slow. I already had the exact official files from my Affinity v2 account, so downloading them again was pointless.

**There is a cleaner route.**

## Use official local installers instead of downloading them again

Download the final Affinity V2 Windows MSI/EXE installers from your own Affinity account. For me it took me 32 seconds to download all 3 of them.

For the current V2 package, the expected filenames are:

```text
affinity-photo-msi-2.6.5.exe
affinity-designer-msi-2.6.5.exe
affinity-publisher-msi-2.6.5.exe
```

I keep my recovery copies here:

```text
/home/rabin/installers/affinity-v2/
```

Use whatever protected path makes sense on your machine. Do not put proprietary installers inside a public Git repository.

### Verify the files first

Check each file with Nix:

```bash
nix hash file --type sha256 --sri \
  /home/rabin/installers/affinity-v2/affinity-photo-msi-2.6.5.exe


nix hash file --type sha256 --sri \
  /home/rabin/installers/affinity-v2/affinity-designer-msi-2.6.5.exe


nix hash file --type sha256 --sri \
  /home/rabin/installers/affinity-v2/affinity-publisher-msi-2.6.5.exe
```

At the revision used in this guide, `affinity-nix` expects:

```text
Photo 2.6.5
sha256-waCX33rWVzZ8AYZWmv2EOqS6ikT6p7s9qRJ+8rDo6Wk=


Designer 2.6.5
sha256-b5K1FtsCWCjyn/NC4trB0g9Wv+AfLoDWgaZK2ZGXW0w=


Publisher 2.6.5
sha256-76ikkAnbAghaSU5YLYLxXiHfAuqVfoEcQK16rHd6+7A=
```

All three of my account downloads matched byte for byte.

**Important**: Do not rename a different release to `2.6.5` and assume it is close enough. The contents must match the expected cryptographic hash. If upstream changes its package sources later, inspect the current `packages/sources.nix` in the pinned `affinity-nix` revision rather than copying these hashes blindly.

### Import the matching files correctly

Never copy files directly into `/nix/store`.

Add the verified installers through Nix (change the `/home/rabin/installers/affinity-v2/` to the correct location):

```bash
nix store add --mode flat --hash-algo sha256 \
  --name affinity-photo-msi-2.6.5.exe \
  /home/rabin/installers/affinity-v2/affinity-photo-msi-2.6.5.exe


nix store add --mode flat --hash-algo sha256 \
  --name affinity-designer-msi-2.6.5.exe \
  /home/rabin/installers/affinity-v2/affinity-designer-msi-2.6.5.exe


nix store add --mode flat --hash-algo sha256 \
  --name affinity-publisher-msi-2.6.5.exe \
  /home/rabin/installers/affinity-v2/affinity-publisher-msi-2.6.5.exe
```

Nix calculates the content-addressed store paths. Because the names and contents match the fixed-output sources expected by `affinity-nix`, the next build reuses them.

After importing the files, I ran the original test again:

```bash
NIXPKGS_ALLOW_UNFREE=1 nix run --impure \
  github:mrshmllow/affinity-nix#affinity-photo
```

The installer download stage disappeared, and the application started almost immediately because the remaining prefix work had already completed.

## Fix the tiny Wine interface

Affinity launched, but its menus and interface were much too small on my 1440p displays.

Affinity V2 does not expose a useful application-level UI scaling control. The correct place to fix this was Wine DPI.

Close Affinity, then open `winecfg` through the same package wrapper:

```bash
NIXPKGS_ALLOW_UNFREE=1 nix run --impure \
  github:mrshmllow/affinity-nix#affinity-photo \
  -- wine winecfg
```

Open **Graphics**, change **Screen resolution**, then apply the setting.

My displays use 1.2x compositor scaling. I tried 120 DPI first because the arithmetic looked sensible. It was still too small. **144 DPI** was the setting that actually looked correct.

Use your eyes, not just the equation.

![Wine configuration graphics tab, I set mine to 144dpi](https://rabin.blog/_astro/wine-configuration-graphics-tab-i-set-mine-to-144dpi.arwff3uD_Z28Qlhr.webp)

The DPI choice persisted across multiple launches because the writable Wine state files are here:

```text
~/.local/share/affinity/
```

## Activate the V2 license

Affinity did not force a license prompt during the initial launches. I signed in using **My Affinity Account** and activated the V2 Universal License.

The account page then reported that the license was active and would not expire.

I closed and reopened Photo several times. The activation and preferences persisted.

![Affinity v2 licence activated on NixOS wine](https://rabin.blog/_astro/affinity-v2-licence-activated-on-nixos-wine.CG9kr3HZ_8RoS8.webp)

**Warning**: `~/.local/share/affinity/` may contain account, activation, registry, and application state. Back it up as sensitive mutable data. Do not commit it to Git, paste its registry files into an issue, or casually share the entire directory.

## NVIDIA works, but OpenCL does not

Affinity detected my NVIDIA RTX 3080 Ti as the renderer. Canvas interaction, opening documents, and exports all worked.

The **Hardware Acceleration** option could not be enabled, though.

This is not a missing CUDA checkbox. Affinity V2’s Windows compute-acceleration path uses **OpenCL**, not CUDA. The package provides Vulkan/VKD3D for the Direct3D rendering path, but the current Wine environment does not expose a compatible Windows OpenCL device to Affinity.

In practical terms:

* GPU-backed display rendering works;
* some compute-heavy operations fall back to the CPU;
* OpenCL acceleration remains unavailable;
* PSD, PNG, and WebP exports still worked in my tests.

**Note**: I left OpenCL disabled (it can’t be enabled anyway).

![Affinity v2 Photos opened files](https://rabin.blog/_astro/affinity-v2-photos-opened-files-nixos.kUpAWYR4_ZaKpD9.webp)

## Declare Affinity V2 in the NixOS flake

Once the temporary test worked, I moved it into the actual NixOS configuration.

My configuration keeps shared desktop packages in `packages.nix` and passes external flake inputs through `specialArgs`. Adapt the file layout to your own configuration. There is no prize for reorganizing a working flake just to copy mine exactly.

### Add the flake input

flake.nix

```nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";


    affinity-nix.url = "github:mrshmllow/affinity-nix";
  };


  outputs = {
    nixpkgs,
    affinity-nix,
    ...
  }:
  {
    nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";


      specialArgs = {
        inherit affinity-nix;
      };


      modules = [
        ./configuration.nix
      ];
    };
  };
}
```

I did not force the external flake’s Nixpkgs input to follow mine. The revision is pinned in `flake.lock`.

### Apply the overlay and add the launchers

My package module applies its overlay in `affinity-nix`, then declares the three V2 applications:

packages.nix

```nix
{ pkgs, affinity-nix, ... }:


{
  nixpkgs.overlays = [ affinity-nix.overlays.default ];


  environment.systemPackages = with pkgs; [
    # Other applications


    affinity-photo
    affinity-designer
    affinity-publisher
  ];
}
```

The Launchers use the same prepared V2 prefix, so declaring the suite does not create three completely independent Wine environments.

If you only want Photo, this is also valid:

```nix
environment.systemPackages = with pkgs; [
  affinity-photo
];
```

The shared prefix still contains the V2 application sources used by upstream. This only controls which launcher package enters the system environment.

### Allow unfree packages declaratively

My system already had this setting:

configuration.nix

```nix
nixpkgs.config.allowUnfree = true;
```

After Affinity becomes part of the NixOS configuration, I no longer need `NIXPKGS_ALLOW_UNFREE=1` for normal launches.

### Pin and test it

Update the lock file:

```bash
nix flake update affinity-nix
```

Then check and test the configuration:

```bash
nix flake check --no-build
sudo nixos-rebuild test --flake .#nixos
sudo nixos-rebuild switch --flake .#nixos
```

**Warning**: Time Consuming During the initial build - this can take a long time. For my i7 12th gen 20 core processor and NVME drive, it still took **2 hours 7 minutes**. Depending on your CPU/RAM/Disk speed config - this can take much longer. Nix will be compiling the custom patched wine-wow64 required by Affinity.

Go out, touch the grass or something.

The first declarative build can still be large and time consuming. Applying the overlay builds the package against the Nixpkgs package set used by the system configuration, so **do not start it five minutes before shutting down the machine and then act surprised**.

The imported fixed-output Affinity installers remain reusable. In my dry run, Nix planned the Wine and runner build but did not plan another download of the three proprietary installers.

![Affinity Designer 2 Start screen nixos wine](https://rabin.blog/_astro/affinity-designer-2-start-screen-nixos-wine.e1_TIHV7_ZNjGeJ.webp)

## What belongs in Git and what belongs in backup

This is important, more than the final package list.

### Git

I keep these in the NixOS repository:

* the `affinity-nix` flake input;
* `flake.lock`;
* the overlay declaration;
* the selected application packages;
* installer filenames and expected hashes;
* recovery instructions.

### Backrest or another encrypted backup

I back up:

```text
/home/rabin/.local/share/affinity/
/home/rabin/installers/affinity-v2/
```

The first path contains mutable Wine, preference, and activation state. The second contains my official proprietary recovery media.

Neither belongs in Git.

The Nix store is also not a backup strategy. Garbage collection can remove paths that are no longer rooted. Keep the official installers somewhere you control if you want recovery to remain possible after an upstream archive disappears.

## Updating or removing it later

To update only the package source:

```bash
nix flake update affinity-nix
```

Review the lock-file change and test again. A newer upstream can change expected installers, Wine patches, etc.

To remove Affinity declaratively:

1. remove the packages and overlay;
2. remove the flake input if nothing else uses it;
3. update the lock file;
4. rebuild the system;
5. inspect `~/.local/share/affinity/` before deleting anything;
6. run normal Nix garbage collection only when you no longer need the previous closure.

Do not delete `/nix/store` paths manually. Nix will manage that area.

## What about Affinity V3?

The repository also packages Canva’s unified Affinity V3 application as:

```text
affinity-v3
```

It uses separate mutable state under:

```text
~/.local/share/affinity-v3/
```

I am transitioning toward V3 through a Canva account, but I deliberately kept that as a separate future test. The working, perpetual V2 Universal License is too useful as a fallback to mix both experiments into the same checkpoint.

One thing at a time. NixOS is very good at reproducibility.

I do not need to test my ability to create parallel problems.

## Final result

Affinity Photo 2 is now usable on my NixOS workstation, not merely able to draw a window.

The practical result is:

* repeatable Wine packaging through Nix;
* official V2 installer files reused locally;
* no manual writing inside `/nix/store`;
* persistent 144 DPI scaling;
* an activated V2 Universal License;
* working PSD, PNG, and WebP exports;
* NVIDIA rendering through Vulkan/VKD3D;
* mutable account and preference state protected separately from Git.

OpenCL compute acceleration remains the main limitation. For my current Photo workflow, it did not make an issue, yet!

That is a much better outcome than I expected from a Windows-only creative suite on NixOS.
