Introduction
PsychLab.IO Documentation
PsychLab.IO is a browser-based tool for building, running, and collecting data from psychology experiments - no programming required. Drag nodes onto a timeline canvas, configure their properties, and PsychLab.IO generates the experiment code for you.
Experiments run entirely in the participant's browser. Responses are saved to your PsychLab.IO account and counted against your monthly quota.
Quick start
Your first experiment
- 1
Create an experiment
Go to Dashboard → Experiments → New experiment. Choose a template or start from scratch.
- 2
Build your timeline
Drag nodes from the left palette onto the canvas. Arrange them into a sequence - instructions, fixation, stimulus, feedback, and so on.
- 3
Configure properties
Click any node to open its properties in the right panel. Change text, durations, keys, and conditions.
- 4
Save and run
Click Save experiment in the properties panel. Then open the experiment and click Run to test it yourself.
- 5
Activate to collect data
Set the experiment status to Active from the experiments list. Only active experiments accept responses from participants.
The builder
Builder overview
Node palette
Left panel. Lists all available node types grouped by category. Drag any node onto the canvas to add it.
Canvas
Centre panel. Your experiment timeline as a tree. Drag nodes to reorder them. Drop zones guide placement.
Properties panel
Right panel. Shows configuration for the selected node, a code preview, and the Save button.
Timeline strip
The horizontal strip at the bottom of the canvas shows a compact view of your experiment's top-level nodes. Click any segment to select that node.
Resizing panels
Drag the thin dividers between panels to resize them. The palette shrinks as low as 140 px; the properties panel as low as 200 px.
Node reference
All nodes
Every experiment is built from nodes. Nodes belong to one of four categories - structure, flow, display, and data.
Structure
Sequence
containerRuns its children one after another in order. The basic building block for grouping nodes.
No configurable properties.
Repeat
containerRuns its children a fixed number of times.
| Property | Description |
|---|---|
| repeatCount | Number of repetitions (default 2) |
For Trials
containerIterates over a list of trial conditions. On each iteration the current condition is available as _trial.
| Property | Description |
|---|---|
| trialSource | balanced_shuffle or manual |
| conditions | List of condition labels (balanced_shuffle mode) |
| trialCount | Total number of trials to run |
| trialsExpr | Custom expression returning an array (manual mode) |
Flow
If
containerRuns the "then" branch when the condition is true, and optionally the "else" branch otherwise. Supports else-if chains.
| Property | Description |
|---|---|
| conditionType | correct, incorrect, timeout, or expr |
| conditionExpr | Custom JS expression (when conditionType is expr) |
| hasElse | Whether to show an else branch |
Loop
containerRepeats its children as long as the condition remains true. Useful for re-showing a stimulus until the participant responds correctly.
| Property | Description |
|---|---|
| conditionType | correct, incorrect, timeout, or expr |
| conditionExpr | Custom JS expression (when conditionType is expr) |
| loopMaxIter | Safety cap - max iterations before the loop exits (default 50) |
Display
Instructions
Shows a text screen and waits for the participant to press Space to continue.
| Property | Description |
|---|---|
| text | Instruction text. Newlines are preserved. |
Fixation
Displays a white fixation cross (+) for a set duration.
| Property | Description |
|---|---|
| duration | Display time in milliseconds (default 500) |
Stimulus
Displays a stimulus and waits for a key response. Records the reaction time and whether the response matches the correct key.
| Property | Description |
|---|---|
| stim.content | Text to display. Supports expressions. Newlines are preserved. |
| stim.fontSize | Font size in pixels (default 48) |
| stim.color | CSS colour string, e.g. white, #ff0000 |
| keys | Accepted key codes, e.g. KeyF, KeyJ |
| correctKey | The key that counts as correct. Supports expressions. |
| timeout | Max wait time in ms before moving on (default 1500) |
Blank
A silent black screen - useful as an inter-stimulus or inter-trial interval.
| Property | Description |
|---|---|
| duration | Pause duration in ms (default 800) |
Feedback
Shows "Correct!" or "Incorrect." depending on the participant's last response, in green and red respectively.
| Property | Description |
|---|---|
| correctText | Text shown on a correct response (default "Correct!") |
| incorrectText | Text shown on an incorrect response (default "Incorrect.") |
| duration | Display time in ms (default 600) |
End Screen
A final thank-you or debrief screen. Automatically advances after the set duration.
| Property | Description |
|---|---|
| text | Message to display. Newlines are preserved. |
| duration | How long to show the screen in ms (default 3000) |
Data
Record
Appends a row of data to the in-memory trial log. Add fields by name and give each an expression that evaluates to the value you want to capture. Use a Save node later to flush the log to the server.
| Property | Description |
|---|---|
| fields | Array of { name, expr } pairs evaluated at runtime |
Save
POSTs all recorded trial rows to the server. Place this at the end of the experiment or after each block. A single Save at the very end is sufficient for most experiments.
Expressions
Dynamic values
Some node properties can be driven by an expression rather than a static value. Toggle the ƒ button next to a field to switch it to expression mode. Expressions are plain JavaScript evaluated at runtime.
| Variable | Type | Description |
|---|---|---|
| _trial | string | Current condition label from a ForTrials node (e.g. "left", "right") |
| _lastResp | string | null | Key code of the most recent response (e.g. "KeyF"), or null on timeout |
| _lastCorrect | boolean | Whether the last response was correct |
| _lastRt | number | null | Reaction time of the last response in milliseconds, or null on timeout |
Examples
Show the current condition as the stimulus text
_trialSet the correct key based on the trial condition
_trial === 'left' ? 'KeyF' : 'KeyJ'Loop while the participant keeps responding incorrectly
!_lastCorrectRecord reaction time in a Record node field
_lastRtRunning experiments
Running & data collection
Participant ID
When a participant runs an experiment they are prompted for a participant ID. This ID is attached to all data saved by that session. It is your responsibility to assign IDs - PsychLab.IO stores whatever string is entered.
Data flow
The experiment runs entirely in the browser. When a Save node executes it sends a JSON payload to /api/results containing a header object (experiment name and participant ID) and a trials array with one object per recorded row.
Statuses
| Status | Meaning |
|---|---|
| draft | In development. You can run it yourself to test. |
| active | Open for participants. Share the experiment link to start collecting data. |
| closed | No longer accepting responses. Existing data is preserved. |
Plans & limits
Free vs Pro
Free
- - Up to 3 experiments
- - 200 responses per month
- - All node types
- - All templates
Pro
$5 / month- ✓ Unlimited experiments
- ✓ Unlimited responses
- ✓ Everything in Free
Monthly response counts reset at the start of each calendar month. If a free account reaches 200 responses mid-month, subsequent Save requests will return a monthly_limit_reached error and no further data will be recorded until the next month.