Project Info
Inspiration
We wanted interview prep that felt human, but safe. We pictured "AI in a bubble": a friendly face you can speak to, not just a chat window. For classmates (and ourselves) who are introverted or anxious, voice practice lowers the barrier to start, repeat, and improve. Mockly began as a way to put a virtual face to a name, and grew into a path for low-pressure conversational practice.
What it does
Mockly is a voice-enabled AI for coding interviews. A realistic interviewer presents a problem, listens to your reasoning, chats back, and runs your code in a live IDE (Python, JS/TS, C/C++, Java, Go, C#, Kotlin, Ruby, Perl). After a session, it summarizes performance across code cleanliness, communication, and efficiency.
How we built it
Frontend React + Vite + TypeScript, Monaco Editor for code, Zustand for state A "talking head" avatar via @met4citizen/talkinghead with real-time lipsync WebRTC mic streaming (user gesture to enable), and a resilient WS client for voice events Direct backend calls (bypassing dev proxy) to stabilize requests in Docker Lightweight Markdown renderer for assistant messages Backend FastAPI with CORS, Dockerized Anthropic Claude for interview logic and feedback text Deepgram for speech: prerecorded STT (Listen) and low-latency streaming TTS (Speak) Code execution service: subprocess compile/run for multiple languages Question management: YAML questions, examples, and per-language starter code WebRTC via aiortc for mic capture; sentence-chunking of model tokens → TTS frames for responsive audio
Challenges we ran into
Voice/TTS auth and streaming Deepgram Speak 401s surfaced only after the first WS write; added diagnostics, safe fallbacks, and a browser SpeechSynthesis fallback for silent turns. Voice/TTS auth and streaming Deepgram Speak 401s surfaced only after the first WS write; added diagnostics, safe fallbacks, and a browser SpeechSynthesis fallback for silent turns. WS handshake churn (localhost vs 127.0.0.1) in Docker/Windows; added multi-candidate WS URLs and backoff. WS handshake churn (localhost vs 127.0.0.1) in Docker/Windows; added multi-candidate WS URLs and backoff. Browser interaction rules getUserMedia without a click left the mic "busy" and the button disabled; we deferred mic warmup until user intent. Browser interaction rules getUserMedia without a click left the mic "busy" and the button disabled; we deferred mic warmup until user intent. Dev proxy vs direct origin Vite restarts caused intermittent 404/connection refused; we switched the client to call the backend origin directly. Dev proxy vs direct origin Vite restarts caused intermittent 404/connection refused; we switched the client to call the backend origin directly. Frontend gotchas JS automatic semicolon insertion (IIFE after state call) broke sending; fixed with explicit semicolons. Markdown showed raw asterisks; added a small, escaped renderer. Frontend gotchas JS automatic semicolon insertion (IIFE after state call) broke sending; fixed with explicit semicolons. Markdown showed raw asterisks; added a small, escaped renderer. Starter code and UX papercuts C++ examples missing headers (vector); Java lacking a Main entry; updated YAML for out-of-box runs. Starter code and UX papercuts C++ examples missing headers (vector); Java lacking a Main entry; updated YAML for out-of-box runs.
Accomplishments we're proud of
A cohesive voice + avatar + IDE loop that feels personal, not robotic A multi-language runner that lets candidates practice in their preferred stack Real-time token chunking → TTS streaming for responsive, conversational delivery Cleaner DX: robust WS reconnection, direct backend routing, and safer markdown
What we learned
Voice UX matters: short, sentence-aware streaming is miles better than long, monolithic replies WebRTC and WS in containers need pragmatic fallbacks (origin resolution, candidate lists) Getting a robust frontend-backend integration and communication with continuous, rigorous testing and validation Aligning the displayed question with the interviewer's prompt is critical for trust
What's next
Today, Mockly focuses on technical interviews with voice and live code execution. The same stack is well-suited to expand thoughtfully: Short-term: richer transcripts, rubric tuning, exportable reports, and typed-reply TTS Medium-term: scenario packs (behavioral rounds), pacing controls, and structured follow-ups Long-term: a supportive practice space for broader conversations that's designed for students, the socially anxious, the introverted, so confidence grows one conversation at a time
Mockly
Mockly is a full-stack coding-interview practice experience. The Vite/React frontend presents interview flows (landing → live editor → feedback), while the FastAPI backend powers problem distribution, structured feedback, and WebRTC signaling. This repo is a mono workspace that keeps both apps in sync.
Architecture
- Frontend (
mockly-frontend) – Vite + React + TypeScript UI with Tailwind and Zustand state. Callssrc/services/api.tsfor/api/*endpoints, manages the Monaco-like editor, and renders problems, execution results, and feedback. - Backend (
mockly-backend) – FastAPI service exposing:POST /api/questionsto fetch prompts (with embedded examples) backed byquestions.yaml.GET /api/feedbackfor canned structured feedback.POST /api/webrtc/offer,POST /api/webrtc/candidate,DELETE /api/webrtc/session/:idfor lightweight WebRTC signaling.POST /api/executeto compile/run Python, JavaScript, TypeScript, C++, and Java snippets inside an isolated temp workspace.
- Shared data –
questions.yamlstores multi-difficulty prompts consumed at startup by the backend. - Local proxying – The Vite dev server proxies
/apitolocalhost:8000, so browser calls reach FastAPI without manual CORS fiddling.
frontend (Vite dev server) --/api--> FastAPI -- question/feedback store
Repository layout
mockly/
├── mockly-frontend/ # React client
├── mockly-backend/ # FastAPI app (questions, feedback, WebRTC)
├── questions.yaml # Source of truth for prompts
├── environment.yml # Optional Python env descriptor
└── README.md # You are here
Quick start
Requirements
- Node 20+
- Python 3.11+
- (optional) Poetry for backend dependency management
One-command stack (Docker)
docker compose up --build
This builds the backend runner image (with Node, ts-node, g++, and the JDK installed) plus the frontend dev-server image, then exposes the apps on http://localhost:8000 (API) and http://localhost:5173 (Vite). Use this path if you want the code-execution endpoint to work without manually installing extra toolchains.
Backend
cd mockly-backend
poetry install # or pip install -r <generated>
poetry run uvicorn app.main:app --reload
This exposes FastAPI on http://localhost:8000.
Heads up:
/api/executeshells out topython3,node,ts-node,g++, andjavac. Install those locally or run the backend viadocker compose up backendso the containerized toolchain handles execution for you.
Frontend
cd mockly-frontend
npm install # or pnpm/yarn
npm run dev
The Vite dev server runs on http://localhost:5173 and proxies /api to the backend.
API surface (summary)
| Endpoint | Method | Description |
|---|---|---|
/api/questions | POST | Retrieve a random prompt for a given difficulty, including example IO. |
/api/feedback | GET | Fetch static structured interview feedback. |
/api/execute | POST | Run Python/JS/TS/C++/Java against optional stdin and return stdout/stderr/exit code. |
/api/webrtc/offer | POST | Create a signaling session (placeholder echo implementation). |
/api/webrtc/candidate | POST | Push ICE candidates into the session store. |
/api/webrtc/session/{id} | DELETE | Close an in-memory signaling session. |
/api/webrtc/session/{id} | GET | Inspect connection stats (audio frame count, last activity). |
Development workflow
- Start the FastAPI server (
uvicorn app.main:app --reload). - Start
npm run devinmockly-frontend. - The frontend issues relative
/apirequests which Vite forwards to FastAPI. Watch backend logs for request traces while verifying UI behavior.
See the per-app READMEs for deeper stack/command details.
Analysis
View
Metric
- 18
- 17
- 10
- 3
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- AnthropicIn code
- CSSIn code
- FastAPIIn code
- HTMLIn code
- JavaScriptIn code
- PythonIn code
- ReactIn code
- Tailwind CSSIn code
- TypeScriptIn code
- DockerClaimed
- Node.jsClaimed
9 of 11 appear in the indexed code. 2 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
No AI coding agent signals were found in this repository.
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
372 KB
Source files
80
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
to-ke/mockly
104 files · 4.3 MB · @ bae69af
Structure
Interface
44 files · 42%Screens, components and styles rendered to the user.
API & routing
6 files · 6%Request entry points: routes, handlers and controllers.
Application logic
24 files · 23%Domain rules, services and shared utilities.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- TypeScript42%
- Python40%
- Markdown9%
- YAML4%
- HTML3%
- CSS1%
- Other (1)1%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
mockly-frontend/package.json
npm · 29- @met4citizen/talkinghead
- @monaco-editor/react
- @radix-ui/react-icons
- @radix-ui/react-slot
- class-variance-authority
- clsx
- lucide-react
- monaco-editor
- react
- react-dom
- react-resizable
- tailwind-merge
- zustand
- +16 more
mockly-backend/pyproject.toml
pypi · 7- aiortc
- anthropic
- deepgram-sdk
- fastapi
- python-dotenv
- pyyaml
- uvicorn
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.