# PrepMate: Practice Interviews While Gemma 4 Does the Prep Work

> Source: <https://dev.to/rahultapase/prepmate-practice-interviews-while-gemma-4-does-the-prep-work-3icj>
> Published: 2026-10-25 19:09:41+00:00

*This is a submission for the [Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady](https://dev.to/challenges/hacktoberfest-week3-2026-10-19)*

**PrepMate** is a mock interviewer that runs on your own laptop. You drop in your resume PDF, paste the job description, pick Technical, HR or Managerial, and then you just talk. Gemma 4 reads your background, asks you tailored questions out loud, listens to your spoken answers, and when you end the session it hands you a scorecard: a communication score and a technical (or behavioral) score for every answer, a written comment on each one, an overall score, and a short list of things to work on.

Interview prep is the task everyone puts off. Doing it properly means hunting for question lists that match your role, rehearsing answers alone in your head with no idea whether they're any good, or convincing a friend to play interviewer for an hour and then give you honest feedback. PrepMate does all three jobs. The only effort left for you is showing up and speaking.

The lazy parts it handles for you:

I'm a student heading into interview season, so I'm the first lazy person this was built for.

*The home page. One button and you're in.*

*Setting up a session: fill in the role, paste the job description, and upload your resume as a PDF. That's all the typing you'll do.*

Practice interviews with a local AI interviewer, answer by voice, and get scored feedback on every session.

PrepMate runs a full mock interview on your own machine. It reads your resume and the job description, asks tailored questions out loud, records your spoken answers, and then scores each answer with written feedback. The AI model (Gemma 4) runs locally through Ollama, and all data is stored in a local SQLite file.

```
Browser (React + TypeScript + Vite)
   │  /api/*
   ▼
Express on 127.0.0.1:3001
   ├── auth  → SQLite users + sessions
   ├── data  → SQLite profiles, interviews, ratings
   └── ai    → Ollama at 127.0.0.1:11434 (gemma4:e2b)
```

The server only listens on `127.0.0.1`, and the resume PDF never leaves the browser: pdf.js extracts the text client-side, and only that text goes into the prompt.

The whole AI layer is one call to Ollama's chat API:

``` js
const res = await fetch(`${url}/api/chat`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  signal: controller.signal,
  body: JSON.stringify({
    model,                       // gemma4:e2b by default
    messages: [{ role: 'user', content: prompt }],
    stream: false,
    think: false,                // skip the reasoning trace, it only adds latency here
    ...(format ? { format } : {}), // JSON schema for feedback
    options: { num_ctx: numCtx },  // 16384
  }),
});
```

Three settings did most of the work:

`think: false`.` num_ctx: 16384`.` format`, and Gemma's output is constrained to that shape. HR and Behavioral interviews get a behavioral score; Technical and Managerial get a technical score:

``` js
const perQuestion = softSkillsInterview
  ? { question: str, answer: str, communicationScore: scoreInt, fluencyComment: str, behavioralComment: str }
  : { question: str, answer: str, communicationScore: scoreInt, technicalScore: scoreInt, fluencyComment: str, techComment: str };
```

`gemma4:e2b` is small enough to run on an ordinary laptop, so the prompts are explicit about format: one question per line, no headings, no labels, nothing else. A tolerant parser then keeps lines that end in a question mark, so a stray intro sentence from the model doesn't end up as "question 1".

Before an interview starts, a system check calls `/api/health`, which asks Ollama whether it's running and whether the model is installed. If either is missing, the Start button stays locked and the page shows the exact command to fix it (`ollama serve` or `ollama pull gemma4:e2b`).

Local generation is slower than a cloud API. On `gemma4:e2b`, questions take roughly 20 to 60 seconds and feedback 10 to 30 seconds, depending on the machine. The app says so up front instead of pretending otherwise. For a week themed on sloths, a short wait in exchange for keeping everything on your own disk felt like a fair trade.

A mock interview is personal data. Your resume carries your phone number, email, college and grades, and your answers include things like "tell me about a time you failed." The resume text, questions, answers and scores live in one SQLite file on your disk, and the API isn't reachable from outside your machine.

Where the open approach worked better than the closed one:

`ollama pull`, and nothing expires.` OLLAMA_MODEL=gemma4:e4b` gives better questions and feedback if your machine has the memory for it. Nothing else changes.
One honest caveat: speech-to-text still uses the browser's Web Speech API, and Chrome sends that audio to Google's speech service. So PrepMate isn't fully offline yet. The AI, the data and your resume are local, but live transcription needs a connection. Moving transcription to a local Whisper model is the next step to close that gap.

`gemma4:e2b`) runs locally through Ollama and generates every interview question, the follow-up rounds, and all scored feedback, with schema-constrained JSON output for the scorecards.
<!-- Only keep the line below if you embed or link a DevRelay agent session above -->
<!-- - Thanks for reading. If you try it, I'd like to hear how it scored you.
