Pupil eye tracking setup, APIs, plugins, and source builds
Open source eye tracking
At a glance
- What is it?
- 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.
- Who is it for?
- 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.
- Can I use it commercially?
- Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
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:
git clone https://github.com/pupil-labs/pupil.git
cd pupil
git checkout develop
python -m pip install -r requirements.txtThe 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.
echo 'SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", GROUP="plugdev", MODE="0664"' | sudo tee /etc/udev/rules.d/10-libuvc.rules > /dev/null
sudo udevadm triggerThe second command adds the current user to the camera-access group:
sudo usermod -a -G plugdev $USERGroup 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`:
sudo apt install libportaudio2These 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:
cd pupil_src
python main.py captureCapture 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:
sudo python main.py captureThis 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.
Editorial 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.
Frequently asked questions
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.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pupil-labs-pupil)Was this useful?