Skip to content

uproot

uproot is a modern, open-source framework for developing and conducting browser-based behavioral experiments. Build studies with hundreds of participants, from simple surveys to complex real-time multiplayer games.

Work in progress

uproot is in pre-alpha. Breaking changes are made with reckless abandon. We are working towards the first alpha (0.0.1) and invite you to join us.

  • Get started in minutes


    Install uproot with a single command and create your first experiment.

    Installation

  • Learn by doing


    Follow the tutorial to build a complete prisoner's dilemma experiment.

    Tutorial

  • Built for multiplayer


    Group participants, synchronize progress, and enable real-time interaction.

    Multiplayer experiments

  • Explore examples


    Ready-to-use experiments covering common paradigms and techniques.

    Example apps

Why uproot?

  • Real-time multiplayer — Built-in support for grouping participants, synchronization, and live interactions
  • Flexible data storage — Append-only log ensures data persistence and supports arbitrary data types
  • Modern stack — Built on FastAPI for performance and reliability
  • 100% open source — LGPL-licensed with no vendor lock-in

Quick example

Here's the core logic of a prisoner's dilemma experiment:

from uproot.fields import *
from uproot.smithereens import *

class GroupPlease(GroupCreatingWait):
    group_size = 2

class Dilemma(Page):
    fields = dict(
        cooperate=RadioField(
            label="Do you wish to cooperate?",
            choices=[(True, "Yes"), (False, "No")],
        ),
    )

class Sync(SynchronizingWait):
    @classmethod
    def all_here(page, group):
        for player in players(group):
            other = other_in_group(player)

            match player.cooperate, other.cooperate:
                case True, True: player.payoff = 10
                case True, False: player.payoff = 0
                case False, True: player.payoff = 15
                case False, False: player.payoff = 3

class Results(Page):
    @classmethod
    def context(page, player):
        return dict(other=other_in_group(player))

page_order = [GroupPlease, Dilemma, Sync, Results]

Browse the complete example including HTML templates

Getting in touch

uproot is developed by Max R. P. Grossmann and Holger Gerhardt.