A small, self-hosted web application for collecting students' names, photographs, biographies, and name-pronunciation recordings — and organising them by department, degree programme, course, and class.
Every institution holds a roster of its students — but rarely in a form that puts a name, a face, a voice, and a few words together. This application does exactly that. It gathers each student's name, spelled and pronounced as the student themselves would have it, alongside an optional photograph and a short biography; and it lets that information be browsed by the groups a student belongs to — their department and degree programme, and the courses, classes, and seminars they take.
It began as a tool for one narrow problem — getting names right when they are read aloud at a graduation ceremony — and it still does that particularly well. But the same collection of names, faces, voices, and groupings is useful wherever an institution wants to put a name to a face, or a voice to a name.
The application is deliberately small and self-contained: one modest server, no third-party services, no accounts to administer, nothing for students to install. This document walks through every feature, from the points of view that use it — the student, the reader, and the administrator.
Every screenshot in this document uses invented sample data — the names, photographs, and biographies shown are not those of real students.
"A person's name is to that person the sweetest and most important sound in any language." — Dale Carnegie
The application began with a single, concrete problem. Graduation ceremonies involve reading hundreds of names aloud, from many linguistic backgrounds, and the person at the lectern usually meets most of those names cold. A mispronounced name, on the day it most matters, stings — for the graduate and for their family in the audience. So the first thing the application does is let every student record their own name, and give the reader a private place to practise from those recordings beforehand.
But a name is rarely wanted on its own. Around it, the application collects the things that place a student: a photograph, a short biography, and — from the institution's own roster — their department, their degree programme, and the courses and classes they take. The result is a small, flexible record of the student body — names, faces, voices, and a few words — that can be browsed whole, a single class at a time, or filtered down to one department or one degree. There is no social feature, no messaging, no analytics: the application collects this information, organises it, presents it, and does nothing else with it.
Anyone arriving at the site's front page is told, plainly, how it works and what to do next.
Each student has a personal page, reached through a unique private link of the form /s/<token>. The institution sends that link to the student — typically by mail-merge to their university email address. The token in the link is a long, unguessable string; it is the student's only credential, so there are no passwords to set or accounts to create.
The page is pre-filled with the student's name from the roster. From one screen, the student can:
Everything can be revisited and changed at the same link, at any time up to the ceremony. A student who re-records, or decides against a photo, simply opens their link again.
A student may, if they wish, share their page with others. The "Share your page" section gives them a read-only link — a different address from their private editing link — to copy and paste into an email or an email signature. Anyone who opens it sees a tidy card with the student's name, photograph, recording, and biography, but cannot change anything: the editing link stays private to the student.
When that link is posted somewhere that shows link previews — a chat application, a social network, a mail client — it unfurls into a preview card automatically, showing the student's name, photograph, and a short description, rather than appearing as a bare web address.
The reader — the person who will read names at the ceremony — has a single page that lists every student, grouped alphabetically by surname. Each entry shows the student's photograph (or their initials, where there is no photo), their name, the phonetic spelling, and an inline audio player. A search box at the top filters the list as the reader types.
The page is built to stay responsive even with a very large roster: a graduation with many thousands of students scrolls smoothly.
Reading through the entire roster is right for the ceremony itself, but for preparing in smaller pieces — or for a smaller event, such as a departmental prize-giving — the reader can work through one teaching group at a time. Every lecture, class, and seminar has its own page at /g/<code> listing just its members, in the same style as the reader's page, with each student's biography shown as well.
A course usually has several teaching groups: a lecture, a number of classes, perhaps some seminars. The course page, at /c/<courseCode>, gathers all of them onto a single page. Each group is a collapsible section, closed by default — so a course with many groups stays easy to scan — and opened with a click, or all at once with the "Expand all" control.
The administrator's page, at /admin.html, is protected by a password. It shows the whole student roster in a searchable, sortable table that — like the reader's page — stays responsive with many thousands of students. Rows can be sorted by any column, searched by name, student ID, programme, or department, and selected in bulk for deletion. Searching for a department or a degree programme is the simplest way to view the roster one department, or one degree, at a time.
Selecting a student opens a detail panel. From it, an administrator can correct any field of the student's record — including their biography, in the same formatting editor the student uses — listen to the recording, see the photograph, and copy the student's personal link to send on. A student's whole record, with its recording and photo, can also be deleted from here.
Rather than waiting for every student to act, an administrator can pre-load the roster from a spreadsheet. On the admin page, uploading an .xlsx or .csv file creates one student per row; columns are matched to fields by their header name — student ID, given name, surname, email, programme, department, and so on. Students are matched by student ID, so re-uploading a corrected sheet updates existing records rather than duplicating them, and a blank cell never overwrites data already held — an administrative re-upload cannot erase a student's recording or contributed content.
Every student's personal link can be exported as a CSV file, ready for the institution to send out by mail-merge. The application does not send email itself — it produces the links and leaves their distribution to the institution's existing systems.
The group and course pages described above are populated by an administrator, from the admin page. Groups are defined in a small .json file: each entry names a teaching group — its type (lecture, class, or seminar), its course code, a number for classes and seminars, an optional course title — and lists the students in it by student ID.
Uploading that file is all it takes. The application works out each group's page address from its course code and type (so a file describing PH426 produces pages such as /g/PH426class1 and the course page /c/PH426), and reports what it did: how many groups were added, how many updated, and whether any listed student IDs were not found in the roster. Re-uploading a file updates the groups it contains and leaves any others untouched, so the roster of groups can be corrected incrementally.
As with personal links, every group's page link can be exported as a CSV for distribution, and a single action clears all groups for a fresh start.
A group's pronunciation list can also be placed directly inside another of the institution's own web pages — a departmental page, a course handbook, a staff intranet. Each group has an address (/api/groups/<code>/embed.html) that returns the group as a small, self-contained block of HTML: the list of students with their photographs, names, phonetic spellings, and recordings, carrying its own styling and nothing else. An institution can drop that block into a page of its own, and it will look at home there.
The application processes voice recordings, photographs, and short written biographies of identifiable individuals — all personal data under UK GDPR. The points below are the ones an institution's data protection officer will want to consider; they are described more fully in the project's technical documentation.
All data — the roster, the recordings, the photographs — stays on the single server the institution deploys the application to. There are no third-party services, no analytics, no content-delivery network, and no external APIs. If data is required to remain within a particular jurisdiction, hosting on an appropriate server satisfies that.
Consent is the natural lawful basis: students choose to record themselves, for a narrow and obvious purpose. The student-facing page should state that purpose, the retention period, and how to request deletion. Recordings should be deleted shortly after the ceremony — a window of two to four weeks is typical — and the admin page can delete records individually or in bulk to that end.
Three things are worth an institution's attention before a real deployment:
/s/<token>) are each protected by a long, unguessable token; a leaked link exposes only that one student.PH426class1, PH426) are short and predictable rather than secret. Before deployment, these pages should be restricted to the people who need them — for example through the institution's single sign-on, or a simple password at the web-server level. This is a deliberate decision left to the institution./p/<token>) carries an unguessable token and is the student's own to share or withhold; a group embedded in another page shows the same data as the public group page. Both should be weighed alongside the pages above.How the reader, group, and course pages are protected, and on what lawful basis a roster is pre-loaded before any student has acted, are decisions for the LSE and its data protection officer. The application is built to make either choice straightforward to implement.
Students retain the right to access, correct, or delete their recording. Correction is self-service through their personal link; deletion through the admin page takes a few seconds. A contact address on the student page is the simplest way to receive such requests.
The application is a single small program — a Node.js server, with a SQLite database for the roster and ordinary files on disk for the recordings and photographs. It is light enough to run on the cheapest tier of any cloud provider.
A typical deployment runs the program as a managed service on a modest Linux virtual machine, behind an nginx web server with a free Let's Encrypt certificate for HTTPS. HTTPS is not optional: browsers refuse microphone access on insecure connections, so the student page cannot record without a valid certificate.
Backing the application up means copying three things — the database file, the recordings folder, and the photographs folder — to a second location; a nightly copy is enough. There is nothing else to maintain: no external accounts, no licence fees, no subscriptions.