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.

Try the live demo

Work in progress

uproot is in initial development. Breaking changes may occur between releases. The announcements shown in the admin interface will tell you when action is needed.

  • 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

  • AI-assisted development


    Build experiments faster with Claude Code, Codex, and other agentic coding tools.

    Set up AI tooling

Why uproot?

  • Reproducible experiments: Your project folder plus uv recreates the exact software environment of your study, years later.
  • 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.

The full case for uproot

Quick example

Here is 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 group.players:
            other = player.other_in_group

            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):
    pass

page_order = [GroupPlease, Dilemma, Sync, Results]

Browse the complete example including HTML templates

Getting in touch

uproot is developed by Max Grossmann and Holger Gerhardt. Click here for more information.

Source code: github.com/mrpg/uproot
Examples: github.com/mrpg/uproot-examples