# Pupil eye tracking setup, APIs, plugins, and source builds

> Pupil is an open source eye tracking platform with packaged Capture, Player, and Service applications, a network API, a plugin system, and a Python source build. It suits researchers and developers working with Pupil Core hardware, but source installation and platform-specific camera access add operational constraints.

**pupil-labs/pupil** — Open source eye tracking 

- Repository: https://github.com/pupil-labs/pupil
- Website: https://pupil-labs.com
- Stars: 1,744 · Forks: 707
- Language: Python
- License: LGPL-3.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/pupil-labs-pupil

## Pupil Core for researchers and application developers

Pupil addresses a specific category of work: collecting and working with eye tracking data from Pupil Core mobile eye tracking hardware. Its users range from people who want to run an eye tracking experiment without writing code to developers connecting an application to a running Pupil instance or modifying the software through plugins. The README describes the hardware as accessible, hackable, and affordable, but it does not publish device specifications beyond its identification as Pupil Core hardware.

The project separates common user access from deeper integration. Non-programmers are directed to downloadable application bundles for Pupil Capture, Pupil Player, and Pupil Service. Developers can use the network-based real-time API, load a plugin at runtime, or run the applications from source. This makes Pupil a platform rather than a single command-line tracker. It is most directly relevant to teams already using Pupil Core hardware or willing to work within its application and extension model.

## Capture, Player, and Service roles in the Pupil workflow

The repository identifies three principal applications, but the README does not document their complete internal workflow. Pupil Capture is started to capture eye tracking operation, Pupil Player accepts a recording path, and Pupil Service exposes the service process for Pupil Remote connections. Based on those interfaces, they form distinct entry points rather than interchangeable names for one executable.

The command dispatcher lives in `pupil_src` and accepts `capture`, `player`, or `service` after `main.py`. Player is also given a `<recording>` path. Capture and Service accept a port for Pupil Remote, which is useful when another process needs to connect over the network. They can also hide their startup interface with `--hide-ui`. This is concrete evidence of a multi-application architecture, although the README does not describe calibration steps, recording formats, message fields, synchronization behavior, or how Camera Capture events are transformed into gaze estimates.

Because those data-path details are absent from the README, an engineer should consult the linked developer documentation before designing a dependent system. Pupil's public extension points are clearer than its internal processing pipeline.

## Network API and runtime plugins as integration points

Pupil offers two documented developer integration routes. The first is its network-based real-time API, which communicates with Pupil over the network. Capture and Service expose a configurable Pupil Remote port through `-P PORT` or `--port PORT`. This approach suits applications that need live communication and should remain separate from the Pupil process rather than depending on internal Python modules.

The second route is the plugin API. Plugins are loaded at runtime from the application bundle. That distinction has a direct operational consequence. If a plugin needs Python libraries absent from the bundle, the README says it must run from source. A team with an ordinary third-party dependency should therefore compare the plugin's dependency list with the application bundle before assuming it can use the packaged applications.

The README does not list API endpoints, message schemas, plugin lifecycle hooks, supported plugin versions, or failure behavior. It is therefore insufficient for implementing a production client or judging compatibility with an existing application. Those details must be verified in the linked API and plugin documentation before the integration design is fixed.

## Install from the develop branch for a first source run

The simplest documented route is to download the latest Capture, Player, and Service bundles from the repository releases. That route does not require readers to know Python, according to the README. For source work, the repository requires Python 3.7 or newer, recommends a virtual environment, and says Python 3.11 is the target for newer bundles. The documented installation selects the `develop` branch before installing `requirements.txt`.

Use a virtual environment for the source checkout, then execute these commands:

```bash
git clone https://github.com/pupil-labs/pupil.git
cd pupil
git checkout develop
python -m pip install -r requirements.txt
```

The dependency file combines numerical and imaging packages such as `numpy`, `opencv-python`, and `scipy` with messaging and interface packages including `pyzmq`, `glfw`, and `pyglui`. It also contains platform-specific entries such as `cysignals` outside Windows and `win_inet_pton` on Windows. Source users must accept the full dependency installation rather than a small standard-library-only setup.

On arm64 Macs, the README specifically recommends creating the virtual environment with a `python3.*-intel64` binary because arm64-native wheels are not yet provided for the dependencies. This is a compatibility warning, not a general Apple Silicon installation guarantee.

## Grant Linux camera and audio permissions before launching Pupil

Linux installation has two explicit system-level prerequisites. Pupil Core applications need permission to access cameras through the USB device rule shown below. After adding the rule, the current user must also belong to the `plugdev` group.

```bash
echo 'SUBSYSTEM=="usb",  ENV{DEVTYPE}=="usb_device", GROUP="plugdev", MODE="0664"' | sudo tee /etc/udev/rules.d/10-libuvc.rules > /dev/null
sudo udevadm trigger
```

The second command adds the current user to the camera-access group:

```bash
sudo usermod -a -G plugdev $USER
```

Group membership may require a new login session before it becomes effective, although the README does not spell out that detail. Audio also depends on the system `libportaudio2` library required by `sounddevice`:

```bash
sudo apt install libportaudio2
```

These are Linux instructions. They should not be copied onto macOS or Windows. The Linux path modifies system access rules and group membership, so a managed workstation may require administrator coordination.

## Start Capture and inspect its command-line controls

Once dependencies and operating-system access are in place, launch an application from the repository's `pupil_src` directory. The following command starts Pupil Capture:

```bash
cd pupil_src
python main.py capture
```

Capture and Service expose a port selection argument, while Player takes a recording path. The CLI also supports `--version`, `--debug`, `--profile`, and `--hide-ui`. The README does not give a sample recording workflow for Player, so the first verifiable step here is only that Capture starts with the expected source installation and hardware access. No success output or device-detection result is documented.

On macOS 12 Monterey and newer, Pupil Capture and Pupil Service may require administrator privileges for camera feeds because of a cited `libusb` limitation. The documented launch form then changes:

```bash
sudo python main.py capture
```

This applies to Capture and Service, not every platform or every Pupil command. It also means a macOS deployment must account for a privileged process rather than treating camera access as an ordinary user permission.

## Maintenance signals and the cost of choosing source deployment

The repository is not archived, and its last push was on 2026-10-12. That is a recent repository activity signal based on the stated last-push date, but it does not establish that each application has a matching recent release. The listed releases are v3.5 from 2021-11-29, v3.4 from 2021-07-13, and v3.3 from 2021-05-12, so engineers should not assume that a recent source commit and a recent packaged application release are the same thing.

The README calls Pupil a project in active, community-driven development. The upgrade choice still matters. Packaged application users avoid managing the repository dependency set, while source users install packages from `requirements.txt` and may need platform fixes. Plugins that depend on libraries outside the application bundle force the source route, increasing responsibility for Python packages, native wheels, operating-system libraries, and hardware permissions.

Pupil Labs source is covered by the GNU Lesser General Public License v3.0. The repository includes `COPYING` and `COPYING.LESSER`. The README permits use, modification, and forks under its terms and asks contributors to share work with the community. This is a project-level licensing note, not legal advice about a particular distribution model.

## Where Pupil differs from a standalone gaze library

Pupil's main alternative is a standalone Python library that exposes a narrow gaze-estimation interface and leaves acquisition, recording, application interface, and network control to the caller. That approach can produce a smaller integration surface when data already comes from another camera system. Pupil instead centers the workflow around Pupil Core applications and hardware, with Capture, Player, Service, a network API, plugins, and source-level access.

That difference can also be a drawback. A library that only computes or exposes gaze data is easier to embed in an existing acquisition service if it has no dedicated application bundle or hardware-access model. Pupil requires decisions about which application runs, how Pupil Remote is reached, which port is used, and whether plugin dependencies are available inside the bundle. Its additional runtime components provide more control paths, but they also create more operating-system and compatibility concerns.

The repository is therefore a closer fit to experimentation and research workflows centered on Pupil Core than to applications that merely need a small gaze function inside an unrelated vision pipeline. This is an architectural comparison based on the documented interfaces, not a claim about performance or accuracy, neither of which is specified in the README.

## Conclusion

Adopt Pupil when the project depends on Pupil Core hardware and benefits from an inspectable Python and C++ codebase. Do not choose it solely as a quick, portable eye tracking library or assume that its plugin runtime can load arbitrary external Python dependencies. Before adoption, verify hardware access on the target operating system, confirm that Python 3.11 works with the intended integrations, and check the plugin API and source-build instructions for the exact deployment.

## FAQ

### Can non-programmers use Pupil without installing it from source?

Yes. The README says users can download the latest application bundles for Pupil Capture, Pupil Player, and Pupil Service without knowing how to write code.

### Which Python version does Pupil support for source development?

The source build requires Python 3.7 or newer. The README recommends Python 3.11 because that is the target for newer application bundles.

### Why might a Pupil plugin require running from source?

Plugins normally load from the application bundle, but a plugin that needs Python libraries absent from that bundle must run from source according to the README.

## Sources

- [License: LGPL-3.0](https://github.com/pupil-labs/pupil/blob/master/LICENSE)
- [Project website](https://pupil-labs.com)
- [pupil-labs/pupil on GitHub](https://github.com/pupil-labs/pupil)
- [README](https://github.com/pupil-labs/pupil/blob/master/README.md)
- [Releases](https://github.com/pupil-labs/pupil/releases)

---

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