The Blog.

My experience developing a web-based experiment with jsPsych on Node.js

These last couple of months, I’ve been very, very busy.

At the start, I didn't know much about web development. I had some experience with Java and Python, but I was new to the world of JavaScript and the common pitfalls one has to avoid to develop well functioning, if not beautiful, JavaScript applications. But I had to program a batch of web-based cognitive tasks for my masters thesis, so I pulled up my sleeves and got to work. My first task was to learn how to work with jsPsych - a JavaScript library for creating web-based experiments, a rather recent work by Josh de Leeuw (you can fork the jsPsych repository here). JsPsych comes with a number of ready-built plugins for creating different kinds of tasks. I used them with some modifications for my Flanker and Tower of London tasks and a couple of questionnaires, built a new plugin for my mental rotation task, and also programmed one independent cognitive test that didn't utilize jsPsych (the Spatial Span task). If you're interested in the source code, check out the GitHub repo for my test battery.

Once I had programmed all of the experiments and as I tested them locally - they worked perfectly, outputting flawless JSON with all the things I wanted to collect from the responses and more - I prematurely patted myself on the back as I'd read that web-experiments required 'only some back end considerations' and so I thought that the hard part was over. How hard could it possibly be to deploy something this simple? Since I felt rather competent with my Python at this point, what followed was two weeks of scrutiny over Python-based web frameworks and their tutorials (TurboGears and Django) and a head-ache over considering what of the utilities I'd really need, and what appeared to be excessive. There was a lot of crud in the Python-based solutions and a bunch of things I really, really did not need, but that seemed integral parts of the system. Most frameworks simply seem to be best-equipped for creating more 'typical' sites, with a landing page, maybe some dynamic content, some links for redirecting the user to other parts of the site, or to other sites. In this case, the basic utilities in the not-so-parsimonious minimal packages come in handy.

Typical web-experiments look very different. You may have a landing page with an informed consent that the participant has to accept before proceeding. Then you'd have an instruction screen that would tell the participant what they have to do during the trial, after which there would be a set of training tasks. During the tasks, a stimulus is presented on the screen, and the user processes the stimulus and responds with key presses or mouse clicks according to the instructions. After the training set is completed, an intermittent instruction screen may appear announcing that the experiment is about to start, followed by the experiment itself, with tasks similar to those in the training section. Depending on the experiment, after that particular test, another one may occur, with again an instruction screen, a training section and then the experiment with its tasks. Simple web-based experiments like this are extremely linear and require very minimal utilities. You simply post data to the database after each experiment is complete, and get the next page in the experimental sequence. Of course you can use different utilities if you wish to add elegance or features to the design (e.g. you could add an option to log in onto a site, then access the experiment, and the user could always come back to a feedback page to view how their results scale with other participants), but the MVP of a web-based experiment is, indeed, very minimal.

After a talk with a friend of mine, who develops full stack JavaScript, I decided to start looking at solutions in JS instead. I started with Node.js and I was thrilled when the Hello World tutorial took me merely ten minutes, with installation and all. I was even more excited to find out exactly how modular the system is - I could just pick and add things that I found useful on the fly. So I built my web-experiment on Node.js with Express and Sequelize (although I will probably experiment with some other database than MySQL next time around) and deployed it to DigitalOcean. With some advice and tutoring from a very good friend, I launched the experiment in a couple of weeks. So in the end, in all reality, it wasn't that difficult. It was a very, very steep learning curve but I learned a lot, and I'd be confident building another app now that I've finished with my first one.

I can even genuinely say I enjoyed the process, and I can recognize some things I'd do differently next time to add some elegance. But I also think that the extra features you can add to your web-based experiments can offer your participants some convenience over laboratory participation. If you manage to acquire intrinsically motivated participants who wish to take part in more than one study, a login system that stores demographic variables really makes sense. That way your participant can simply complete the task every time, without having to re-enter their data every time. This also makes a results feedback page more feasible and allows the participant access to their own data.