How We Built a Self-Hosted AI Interviewer with Next.js, Supabase, and WebSockets

Most interview software helps someone schedule, record, or score a conversation. We wanted to build the interviewer itself: a system that could generate a structured interview, conduct it over voice, chat, or video, ask follow-up questions when an answer was vague, and turn the result into a useful report. That became Aural, which we have released under the MIT license. A useful AI interviewer needs more than a list of questions. It must: turn a plain-language brief into a coherent interview str
Most interview software helps someone schedule, record, or score a conversation. We wanted to build the interviewer itself: a system that could generate a structured interview, conduct it over voice, chat, or video, ask follow-up questions when an answer was vague, and turn the result into a useful report.
That became Aural, which we have released under the MIT license.
What the system needs to do
A useful AI interviewer needs more than a list of questions. It must:
- turn a plain-language brief into a coherent interview structure;
- keep state across a real-time conversation;
- decide when an answer needs a contextual follow-up;
- support text, audio, and video without splitting the product into separate workflows;
- produce transcripts, evidence, scores, and summaries that a human can inspect;
- give teams control over their data and model provider.
The last point is why open source matters here. Interviews can contain resumes, personal information, recordings, and evaluations. Teams should be able to inspect how that data moves through the system and, when needed, run the entire stack on their own infrastructure.
Architecture
Aural is a TypeScript application built with Next.js 14 and the App Router. Supabase provides PostgreSQL, authentication, storage, and real-time subscriptions. tRPC keeps client and server calls type-safe, while Tailwind CSS, shadcn/ui, and Radix primitives provide the UI layer.
For technical interviews, Monaco powers the code editor and Excalidraw provides a collaborative whiteboard.
The core separation is between the interview definition, the live session, and the assessment result.
- The definition describes competencies, questions, timing, modality, and evaluation criteria.
- The session records the live conversation, current state, follow-up decisions, and integrity events.
- The assessment transforms session evidence into per-competency scores, summaries, themes, and engagement metrics.
Keeping these concerns separate lets the same interview run over chat, voice, or video while preserving one reporting model.
Adaptive follow-ups
A scripted questionnaire advances after every response. An interviewer needs another decision: did the answer actually provide enough evidence?
After each response, Aural evaluates the answer against the active question and its criteria. The model can ask a focused follow-up, clarify ambiguity, or continue to the next question. The goal is not to make the model talk more; it is to collect comparable evidence without forcing every participant through an identical conversational path.
We also store the resulting transcript and question context. That makes a score traceable to what was asked and answered instead of leaving users with an unexplained number.
Real-time voice and video
Audio and video add failure modes that do not exist in chat: connection drops, partial transcripts, device permission errors, silence, and out-of-order events. We use persistent session state and WebSocket relays so the interface can recover without losing the interview's position.
The UI treats the transcript as a first-class artifact. Live speech events update the conversation, but the durable session record remains the source of truth for assessment and reporting.
Self-hosting
The repository includes the complete application rather than a limited community edition. A local setup follows the familiar Next.js workflow: clone the repository, copy .env.example to .env.local, install dependencies, and run the development server.
You configure Supabase credentials, model-provider keys, and the integrations you want. Production options include Docker, Vercel, and conventional server deployment. Supabase can be managed or self-hosted.
The model layer supports OpenAI-compatible providers so a deployment is not tied to one vendor. That is useful for cost control, data residency, and teams that already operate an internal model gateway.
What is included
The open-source release contains the interview designer, adaptive chat/voice/video sessions, automated assessment, candidate and session management, Monaco coding interviews, Excalidraw whiteboards, integrity controls, multilingual support, organizations, projects, and role-based access.
We kept the hosted product as an option for teams that do not want to manage infrastructure. Both paths use the same codebase: self-host when data sovereignty and customization matter, or use the managed service when operational simplicity matters more.
What we learned
The hardest part was not generating questions. It was building a reliable loop around the model: durable session state, bounded follow-ups, modality-independent reporting, observable evidence, and recovery when real-time media fails.
An AI interviewer should not be a black box that emits a confident recommendation. The useful output is the evidence trail: what was asked, what the participant said, how criteria were applied, and where a human should review the result.
The source is available on GitHub. Feedback on the self-hosting experience, scoring transparency, and real-time interview flow is especially welcome.
Originally published on the Aural blog.




