๐Ÿ‘๏ธ Eye Lab

June 12, 2026 ยท View on GitHub

Eye Lab is an open-source tool for creating browser-based eye-tracking usability tests using Webcam + TensorFlow.js, without plugins or native installations.

Originally created by Karine Pistili as a graduation project, Eye Lab has evolved into a full calibration and gaze-tracking microservice used standalone or fully integrated into RUXAILAB.


๐Ÿงฉ Architecture Overview

Eye Lab has two repositories:

ComponentDescription
Frontend (this repo)Calibration UI + gaze tracking client (Vue.js)
BackendAPI handling calibration uploads and optional forwarding to RUXAILAB

Backend repository:
https://github.com/ruxailab/eye-tracker-api


๐Ÿ‘ฉโ€๐Ÿ’ป Local Setup

Prerequisites

  • Vue CLI 4.x
  • Node.js 14.x

1. Install dependencies

npm install

2. Run in development mode

npm run serve:development

3. Build

  • Build with development env vars:
npm run build:development
  • Build with production env vars:
npm run build:production
  • Standard production build:
npm run build

โ˜๏ธ Deploying to Firebase Hosting

  1. Create .env files for each environment. This project reads environment keys using a suffix of _DEV or _PROD.

.env.development

VUE_APP_ENV=dev
VUE_APP_FIREBASE_API_KEY_DEV='your-dev-api-key'
VUE_APP_FIREBASE_AUTH_DOMAIN_DEV='your-dev-auth-domain'
VUE_APP_FIREBASE_PROJECT_ID_DEV='your-dev-project-id'
VUE_APP_FIREBASE_STORAGE_BUCKET_DEV='your-dev-storage-bucket'
VUE_APP_FIREBASE_MESSAGING_SENDER_ID_DEV='your-dev-sender-id'
VUE_APP_FIREBASE_APP_ID_DEV='your-dev-app-id'
VUE_APP_FIREBASE_MEASUREMENT_ID_DEV='your-dev-measurement-id'
VUE_APP_API_BASE_URL_DEV='https://api-dev.example.com'
VUE_APP_RUXAILAB_URL_DEV='https://ruxailab-dev.example.com'

.env.production

VUE_APP_ENV=prod
VUE_APP_FIREBASE_API_KEY_PROD='your-prod-api-key'
VUE_APP_FIREBASE_AUTH_DOMAIN_PROD='your-prod-auth-domain'
VUE_APP_FIREBASE_PROJECT_ID_PROD='your-prod-project-id'
VUE_APP_FIREBASE_STORAGE_BUCKET_PROD='your-prod-storage-bucket'
VUE_APP_FIREBASE_MESSAGING_SENDER_ID_PROD='your-prod-sender-id'
VUE_APP_FIREBASE_APP_ID_PROD='your-prod-app-id'
VUE_APP_FIREBASE_MEASUREMENT_ID_PROD='your-prod-measurement-id'
VUE_APP_API_BASE_URL_PROD='https://api.example.com'
VUE_APP_RUXAILAB_URL_PROD='https://ruxailab.example.com'
  1. Deploy to the development hosting site:
npm run deploy:development
  1. Deploy to the production hosting site:
npm run deploy:production

deploy:development uses dev Firebase project alias and the eye-tracking-calib-dev hosting target. deploy:production uses prod Firebase project alias.


๐Ÿ”„ GitHub CI/CD

This project includes a Firebase Hosting workflow.
You can customize the settings inside:

.github/workflows/

๐Ÿš€ Eye Lab + RUXAILAB Integration

Eye Lab is used by RUXAILAB as an external calibration and gaze-tracking service.
The workflow below explains the exact communication pipeline.


๐Ÿ”— 1. Redirect From RUXAILAB โ†’ Eye Lab

During a usability test, RUXAILAB redirects the participant to the Eye Lab URL:

VUE_APP_EYE_LAB_FRONTEND_URL?auth=<userId>&test=<testId>

Eye Lab frontend then:

  • sets fromRuxailab = true
  • sets calibrationName = userId
  • loads DoubleCalibrationRecord.vue
  • calls getRuxailabConfig(auth, test)
    โ†’ makes a GET request to:
${VUE_APP_RUXAILAB_URL}/getCalibrationConfig

RUXAILAB returns the admin-defined calibration configuration, which is stored in the Eye Lab Vuex store.


๐ŸŽฏ 2. User Performs Calibration

Eye Lab shows the multi-point calibration interface, collecting:

  • iris positions
  • timestamps
  • fixed-point reference geometry

All data stays local in the browser until calibration is completed.


๐Ÿ“ก 3. Sending Calibration to Eye Lab Backend

When calibration finishes, Eye Lab calls:

POST /api/session/calib_validation

Payload includes (inside FormData):

  • from_ruxailab
  • file_name (userId)
  • fixed circle iris points
  • calibrated iris predictions
  • screen_height, screen_width
  • k (calibration factor)
  • full calibration model

๐Ÿ” 4. Forwarding Calibration to RUXAILAB

If from_ruxailab = true, the Eye Lab backend forwards the following JSON to RUXAILAB:

{
  "session_id": "<file_name>",
  "model": { ...calibrationData },
  "screen_height": 1080, 
  "screen_width": 1920,
  "k": number of points
}

Sent to the endpoint:

POST /receiveCalibration

RUXAILAB then stores this calibration inside the user object, making it available for future eye-tracking tests.


๐Ÿ“‹ Integration Diagram

alt text


๐Ÿ“Œ Notes

  • No webcam video is transmitted or stored in this project โ€” only numeric gaze-related data.
  • Accuracy depends on lighting, camera quality and user stability.
  • Fully browser-based using TensorFlow.js.

๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘ Contributing

Pull requests are welcome.
Found a bug? Open an issue.


๐Ÿ“„ License

MIT License
Copyright ยฉ Uramaki Lab