Easy enough for teaching, precise enough for psychophysics, flexible enough for everything else — now native on HarmonyOS.
Sub-millisecond timing, OpenGL ES 3.2 rendering, full Python runtime, distributed multi-device sync — packaged as a native HAP.
PsychoPy-OH is a faithful reimplementation of the PsychoPy toolkit for HarmonyOS. It preserves the API surface that researchers around the world rely on, while integrating with the distributed capabilities of OHOS.
Every stimulus parameter is logged. Every trial timestamp is recorded to microsecond precision. The experiment you design on your laptop is the experiment that runs on a fleet of OHOS tablets — bit-for-bit, frame-for-frame.
Packaged as a HAP, signed with HarmonyOS developer certificates, distributable through AppGallery. Uses ArkUI for chrome and Electron for the Python runtime.
Frame-locked presentation on OHOS displays, vsync-accurate flips, and a real-time priority path for time-critical loops.
Apache 2.0 (template) + GPLv3 (PsychoPy upstream), hosted on GitCode and GitHub. The v0.1.3 debug record (2026-06-25) is openly documented.
A complete psychophysics toolkit, with the additional superpowers of a distributed operating system.
visual, core, data, event, gui, hardware, sound, logging — every submodule, every class, every method.
Vsync-locked flips, real-time priority threads, and a frame-interval monitor. Trigger jitter <1ms — critical for ERP research.
GPU-accelerated shaders for gratings, gabors, drifting stimuli, and dynamic masks — at 120Hz on supported displays.
Embedded CPython 3.11 runtime. Run existing .py experiment scripts unchanged.
Package experiments as HarmonyOS Ability Packages. Install on tablets, phones, headunits.
The drag-and-drop Builder interface for non-programmers, and the full Coder IDE for power users — both ported.
Run synchronized stimuli across multiple OHOS devices via DDS. Perfect for dual-subject paradigms or classroom cohort studies.
Eye trackers (Tobii Pro 5, Eyelink), EEG triggers (BrainProducts via USB-HID), MRI pulses, joysticks — with OHOS-native drivers.
Four canonical paradigms from cognitive neuroscience and psycholinguistics — the same primitives that power PsychoPy-OH on HarmonyOS.
The fundamental stimulus of vision science. A sinusoidal grating windowed by a Gaussian envelope — used in thousands of contrast sensitivity, orientation discrimination, and attention studies.
A cornerstone of psycholinguistics. A briefly presented prime word is masked, rendering it invisible — yet it still influences lexical access to the target.
In ERP research, every stimulus must be marked in the EEG stream with a trigger code. PsychoPy-OH sends triggers via USB-HID on OHOS, synchronized to vsync with <1ms jitter.
Eye movements reveal moment-by-moment cognitive processing during reading. Click on the text to simulate fixation points, or play a sample scanpath.
From the OHOS kernel up to your experiment script, each layer is a clean abstraction — debuggable, replaceable, and documented.
The interfaces researchers touch: Builder's drag-and-drop experiment designer, Coder's full IDE, and your own .py scripts.
The full psychopy package, with platform-specific backends swapped for OHOS: pyglet → EGL, pygame → Oboe, serial → OHOS USB HAL.
Electron hosts the Python interpreter and Chromium surface. Node.js handles IPC, file I/O, and HAP lifecycle events.
HarmonyOS 5.0+ kernel, ArkUI for system chrome, OpenGL ES 3.2 for stimulus rendering, Oboe for low-latency audio.
# === HarmonyOS ARM64 Native Build === # Step 1: Environment Setup # Install harmonybrew Node.js v26.3.1 (ARM64 native) $ harmonybrew install node@26.3.1 $ export PATH="$HOME/.harmonybrew/node/26.3.1/bin:$PATH" $ node --version # v26.3.1 # Step 2: Frontend Build $ cd web_engine/src/main/resources/resfile/resources/app/ # Remove os restriction from package.json $ node -e "const p=require('./package.json');delete p.os;require('fs').writeFileSync('./package.json',JSON.stringify(p,null,2))" $ npm install # Sign native .node bindings (rolldown) $ find node_modules -name "*.node" -exec binary-sign-tool sign {} \; # Replace lightningcss with WASM version $ node -e "const p=require('./package.json');p.dependencies.lightningcss='^1.29.3';require('fs').writeFileSync('./package.json',JSON.stringify(p,null,2))" $ npm install lightningcss@1.29.3 $ npx vite build # Step 3: Package & Install $ cd ../../../../../../.. $ hvigorw clean --no-daemon $ hvigorw assembleHap --mode module -p product=default -p buildMode=release --no-daemon $ hdc install entry/build/default/outputs/default/entry-default-signed.hap
30+ Python IPC handlers live. liaison_shim.py WebSocket JSON-RPC server. Tiered Python setup (system Python →venv →harmonybrew). Auto-diagnose & auto-install. Verified on Kirin X90a with psychopy-lib 2026.2.0.
Experiment runs in system browser via IIFE bridge: local jQuery/jQuery UI/PIXI/PreloadJS, dialog skip, error overlay, Scheduler-based flow. Windows-verified.
First successful self-build on HarmonyOS ARM64 device. Fixed SVG icon rendering issues, Components panel now displays correctly, native binding signing completed. Full build pipeline documented in BUILD_ON_ARM64.md.
x86 cross-compilation stabilized. Directory structure flattened for cleaner project layout. Complete build pipeline documented with step-by-step instructions.
Stability milestone: frame-timing audit on HarmonyOS 5.0.1 tablets, EGL context-loss race patched, Tobii Pro 5 eye-tracker handshake stabilised. Full debug record published on the project page.
All psychopy.visual primitives rendering correctly. TrialHandler and StairHandler produce correct data. HAP packaging verified.
First successful draw of a GratingStim on HarmonyOS. OpenGL ES 3.2 backend operational.
Electron 28 cross-compiled for arm64-linux-ohos. Python 3.11 embedded. Custom N-API bridge stub created.
Full iohub device abstraction. Tobii Pro SDK OHOS port. EEG trigger support via OHOS USB HID.
Multi-device stimulus sync via DDS. Run a single experiment across a tablet and phone, or a wall of tablets.
Every feature, every backend, every plugin. AppGallery listing. Long-term support release.
| Capability | PsychoPy Desktop | PsychoPy.js Web | PsychoPy·OH HarmonyOS |
|---|---|---|---|
| Windows / macOS / Linux | ✓ | ✓ | — |
| HarmonyOS native | — | ~ | ✓ |
| HAP distribution | — | — | ✓ |
| Full Python runtime | ✓ | — | ✓ |
| Sub-millisecond timing | ✓ | ~ | ✓ |
| Builder GUI | ✓ | ~ | ✓ |
| Distributed multi-device sync | — | — | ✓ |
| Offline execution | ✓ | ~ | ✓ |
| Native eye tracker support | ✓ | — | ~ |
| Open source | ✓ | ✓ | ✓ |
In the vast majority of cases, yes. If your script uses psychopy.visual, psychopy.core, psychopy.data, and psychopy.event, it should run unmodified.
HarmonyOS 5.0 and later, on ARM64 devices. Tablets preferred for stimulus presentation, phones for response collection.
Three mechanisms: (1) vsync-locked flips via EGL; (2) real-time priority thread via SCHED_FIFO; (3) onboard frame-interval monitor flagging >1ms deviations.
Yes. Trigger codes are sent via USB-HID on OHOS, synchronized to screen flips via win.callOnFlip() with measured jitter <1ms. Sufficient for N400, P300, and MMN.
Tobii Pro 5 is verified working in v0.1.3 via OHOS USB driver and ioHub. Eyelink support requires porting Pylink SDK — in progress for v0.2.0.
On 60Hz displays: 16.6ms ±1ms per frame. On 120Hz: 8.3ms ±0.5ms. Frame-interval monitor logs every flip; deviations >2ms are flagged.
Technical foundations, API documentation, development guides, testing methodology, and the full story behind PsychoPy-OH.
CHROMIUM 120 · NODE.JS 20
The desktop application framework that hosts both the PsychoPy Builder/Coder UI and the embedded Python runtime. Cross-compiled for arm64-linux-ohos with custom patches for OHOS window management and EGL context handling.
EMBEDDED · STATIC BUILD
The complete CPython interpreter, statically linked and embedded within the HAP. Ships with pip, numpy, scipy, Pillow, and the full psychopy package.
GPU SHADERS · VSYNC LOCKED
The rendering backend for all psychopy.visual stimuli. Custom GLSL shaders implement sinusoidal gratings, Gaussian masks, and drifting textures. Frame-locked to the display's vsync.
ARKUI · DDS · USB-HID
The native platform layer. ArkUI provides the system chrome and lifecycle management. Distributed Data Service enables multi-device stimulus sync. USB-HID API connects to EEG trigger boxes and eye trackers.
Window, GratingStim, ImageStim, TextStim, ShapeStim, ElementArrayStim, DotStim, NoiseStim. All rendering via OpenGL ES 3.2 shaders.
Clock, Countdown, wait(), getTime(), quit(). Frame-accurate timing via vsync-locked flips and real-time priority threads.
TrialHandler, StairHandler, ExperimentHandler, saveAsWideText, saveAsPickle. Identical output format to desktop PsychoPy.
waitKeys, getKeys, Mouse, getMouse. Touch input on OHOS tablets maps to mouse events for backward compatibility.
parallel.ParallelPort (USB-HID on OHOS), keyboard.Keyboard, serial.Serial (via OHOS USB HAL). For EEG triggers and device communication.
EyeTrackerDevice, EventEmitter, fixation detection. Tobii Pro 5 verified, Eyelink in progress. Device abstraction layer with OHOS-native drivers.
A transparent log of the ARM64 native self-build milestone — 6 core issues identified, analyzed, and resolved.
Node.js crashes immediately on ARM64 OHOS due to missing __errno_location symbol in standard builds. Switched to harmonybrew Node.js v26.3.1 which includes the required symbol.
Native .node bindings (rolldown) fail to load due to OHOS mandatory code signing. Used binary-sign-tool to sign all .node files before loading.
Native lightningcss binary links against libgcc_s.so.1 which is absent on OHOS. Replaced with WASM-based lightningcss@1.29.3 that runs in Node.js without native dependencies.
SVG icons rendered blank because CSS custom properties are not resolved in SVG <use> references. Fixed by fetching SVG content and inline rendering with Svelte {@html} directive.
Builder Components panel showed infinite loading spinner because Python IPC stub did not respond to component list requests. Patched the stub to return an empty component list gracefully.
npm install rejected the platform because package.json "os" field restricted installation to linux/darwin/win32. Removed the os field to allow OHOS ARM64 installation.
When the OHOS compositor reclaimed the EGL surface during background transitions, the Electron GPU process crashed silently. Fixed by wrapping eglSwapBuffers in a recovery loop with context recreation.
The iohub eye-tracker handshake failed on first connect, requiring a manual restart. Root cause: OHOS USB permission dialog timing. Fixed by adding a 500ms retry delay after USB device enumeration.
On HarmonyOS 5.0.0 tablets, frame intervals showed occasional 33ms spikes. Root cause: background thermal throttling. Mitigated by requesting SCHED_FIFO priority and disabling CPU frequency scaling during experiments.
# Prerequisites $ sudo apt install build-essential cmake ninja-build $ pip install meson pytest # Clone with submodules $ git clone --recursive https://gitcode.com/A9iska/psychopy-oh.git $ cd psychopy-oh # Download OHOS NDK (arm64-linux-ohos) $ ./scripts/fetch-ndk.sh --version=5.0 # Build CPython for OHOS $ cd cpython-build $ ./configure --host=aarch64-linux-ohos --enable-shared --with-ensurepip=install $ make -j$(nproc) && make install # Bundle Python + psychopy into HAP resources $ cd ../electron_runtime $ python bundle.py --python-dir=../cpython-build/install --target=arm64-linux-ohos --include=psychopy,numpy,scipy,Pillow
Ubuntu 22.04+ or macOS 14+. 16GB RAM recommended for Electron cross-compilation. OHOS NDK 5.0+ required.
CPython is cross-compiled for arm64-linux-ohos using the OHOS NDK toolchain. The resulting libpython3.11.so is bundled into the HAP.
Electron 28 is patched with 3 custom commits for OHOS: EGL surface recovery, USB-HID enumeration, and ArkUI lifecycle integration.
The final HAP is assembled by hvigorw, combining the Electron binary, Python bundle, ArkUI shell, and psychopy resources into a signed .hap file.
Run python -m pytest tests/ for unit tests, and ./scripts/timing-audit.sh for frame-precision benchmarks on a connected device.
Port eye trackers, EEG amplifiers, or response boxes to OHOS USB-HID. We especially need Eyelink (Pylink), BrainProducts, and SR-Research drivers.
Write integration tests that verify API parity with desktop PsychoPy. Each test runs a stimulus on both platforms and compares frame-by-frame output.
Translate the README, write tutorials, or document OHOS-specific quirks. We welcome contributions in Chinese, Japanese, Korean, and European languages.
OPEN SCIENCE TOOLS
The original toolkit by Jon Peirce and Maciej Horyń. Without their work, this port would not exist.
OPENJS FOUNDATION
The cross-platform framework that makes embedding Chromium + Node.js + Python possible on OHOS.
PYTHON SOFTWARE FOUNDATION
The reference implementation of the Python programming language. Statically linked and embedded.
OPENATOM FOUNDATION
The open-source operating system that powers HarmonyOS. Its distributed architecture enables new experiment paradigms.