Building Ezzi: My Journey Creating an Invisible Tech Interview Assistant (Now Open Source)



This content originally appeared on Level Up Coding – Medium and was authored by Dmitry Khorev

From backend engineering to interview survival tools — reflections on shipping my first desktop AI app.

TL;DR — I built a desktop app called Ezzi (pronounced like “easy”) that acts as an invisible overlay during coding interviews. It gives you AI-generated solutions (even in your native language) without the interviewer noticing. I forked an early version of Interview Coder to my create my own spin on the idea. I’m excited to open-source Ezzi so others can use it and contribute to its future.

The Problem with Interviews

Many developers get burnt out by the broken hiring process. Technical job searches drag on with endless coding tests and whiteboard sessions, which can chip away at your confidence.

I often felt that acing these interviews was as much about endurance and luck. Even after countless evenings on LeetCode, we’d still get blindsided by questions under pressure. It struck me that the process is, frankly, broken – and I wasn’t alone in feeling this. I started wondering: What if I had a “coach” by my side during these interviews? Not a person, but an AI assistant that could hint or even show a solution if I got stuck.

That’s when I discovered Interview Coder, an open source project that had blown up online in April 2025. It was vibe coded and honestly a mess, but it worked. The concept was brilliant: an invisible overlay that only the candidate can see (not the interviewer). However, the project soon went closed source and development stagnated. I decided to fork one of the earlier open source versions and build my own take on the idea.

This concept was proof of how flawed the system is: if people are resorting to stealth tools to get through interviews, maybe the interviews need to change. But until they do, why not level the playing field a bit?

Building Ezzi

I set out to build a desktop app that could help with live interview support: If you choose, use it during a real interview (even while screen sharing) for undetectable assistance – a little safety net that only you can see.

The current version focuses on the core interview assistance functionality, with additional features like hint-only mode, LeetCode practice, and learning tools planned for the future.

I also had some personal motivations: after years as a backend engineer, I was itching to build a desktop application and learn something new. I’d never built an Electron app or done cross-platform UI work before. Plus, I was curious about the new wave of AI coding tools like Cursor, Claude, Codex, Junie. This project felt like the perfect sandbox to play with those while creating something potentially useful (or at least interesting!).

What is Ezzi?

In a nutshell, Ezzi (pronounced like “easy”) is an invisible overlay UI for coding interviews. It runs as a desktop app on your computer, sitting on top of your coding environment. When activated (via a hotkey), it shows an assistive panel only on your screen, not on the shared screen. The interviewer sees nothing unusual – just your coding window – while you see an extra panel with helpful info.

You typical screen share while doing an online DSA interview — that’s what interviewer would see.
You typical screen share while doing an online DSA interview — that’s what interviewer would see.

Under the hood, Ezzi uses AI (Claude 4 for now) to analyze the coding question you’re working on. It can give you a step-by-step thought process, explain which DSA pattern or algorithm might apply, and generate a complete solution.

That’s what you actually see with Ezzi.

Key Features

Invisible UI: The overlay window is designed to be 99% invisible to screen-sharing tools.

It won’t show up on Zoom, Google Meet, or common interview platforms (they’ll just capture your code editor, not the Ezzi window). This “stealth mode” means you can use it in live interviews without the tool itself being detected.

AI-Generated Solutions: Ezzi connects to AI models to provide context-aware help.

Multi-language Support: Delivers thoughts and hints in your preferred spoken language to reduce cognitive load during interviews.

Minimal Footprint & Undetectability: It doesn’t inject anything into the browser or interfere with the code editor; it’s a separate floating window. You toggle it with a hotkey, and it can overlay on top of any browser, IDE or coding pad. When off, it’s completely out of the way. Hotkeys look like a no-op to your coding environment.

Demo of Ezzi in action.
Demo of Ezzi in action.

In short, Ezzi turns those nerve-racking DSA interviews into a (slightly) more open-book experience. It’s like having an expert whispering hints in your ear, or a safety net ready to catch you if you get stuck. And since Ezzi is open source, you can build and customize this assistant yourself, or even run your own AI backend for it.

Building a Desktop App as a Backend Engineer

Building Ezzi was as much a personal learning journey as it was a software project. I spend most of my days in backend land – databases, APIs, cloud services – not building UIs. So, choosing Electron + React for a desktop app was me stepping out of my comfort zone.

Electron allowed me to write cross-platform desktop software in TypeScript (essentially creating a mini web app that runs on Windows, Mac, or Linux). With this, I could ensure anyone can use Ezzi regardless of their OS.

Tech Stack at a Glance

Electron & React: Electron provides the container (Chromium + Node runtime) to create the desktop app, and React + Tailwind CSS makes it easier to build a dynamic UI. The overlay’s interface (the hints panel, etc.) is just a web page rendered in a transparent Electron window.

Node.js backend: I built a companion backend service with NestJS. This handles things like processing the screenshots, communicating with the AI models, and any heavy logic that I didn’t want to run in the client for security. NestJS gives a structured way to build out a REST API. For example, when you hit “Solve” in Ezzi, the app sends the data to a NestJS API which then calls an AI service to retrieve hints or solutions, and sends it back to the app.

Infrastructure: the rest of the iceberg is here – databases, GitHub actions, deploy pipelines, Stripe integration, AI integration and so on.

High-level overview of Ezzi’s architecture.
High-level overview of Ezzi’s architecture.

How It Works

The Electron + React frontend communicates with a backend, which interacts with external AI APIs (like OpenAI’s GPT or Anthropic’s Claude).

In self-hosted mode, the user runs his own backend server; in cloud mode, Ezzi’s app talks to a managed server.

I made the overlay window click-through in solution mode by default. This way, you’re not accidentally selecting text on the overlay when you mean to code. Clicks in the app area are never attributed to the Ezzi window, so your browser or IDE never loses focus. And when hidden, the app is truly hidden (not just minimized – it doesn’t appear on the taskbar or Dock).

Development Journey (Forking, Fixing, and Learning)

Ezzi’s development began as a fork of the Interview Coder codebase. Interview Coder, for context, was a closed-source (initially) app that went viral in late 2024 for offering undetectable AI help in interviews. Its creator eventually put the code on GitHub (with an open-source license) and even encouraged folks to fork it.

However, diving into that code was quite an eye-opener. The project was functional, but the internals were… let’s say rough around the edges. It felt like large parts had been generated by an AI (the original dev likely used Cursor or something similar). There were huge files with little structure, minimal comments, and some very quirky code paths. My first challenge was simply getting the code to run properly and understanding how everything connected.

The lack of clear structure meant I had to do a lot of refactoring from day one. Functions had names that didn’t always make sense, there were unused variables and dead code branches, and TypeScript types were applied loosely (with plenty of any types floating around). I spent a good amount of time enforcing type safety – enabling stricter TypeScript config, adding interfaces for data objects (like the shape of a captured “problem” or a “solution” response), and removing redundant code. This process flushed out many hidden bugs.

// "any" typehints everywhere
function getProblemInfo(): any { // !!!
return state.problemInfo
}

function setProblemInfo(problemInfo: any): void { // !!!
state.problemInfo = problemInfo
}

// or no types at all
app.on("open-url", (event, url) => { // !!!
console.log("open-url event received:", url)
event.preventDefault()
if (url.startsWith("interview-coder://")) {
handleAuthCallback(url, state.mainWindow)
}
})

// auth token is stored in the window object of the browser
const checkExistingSession = async () => {
const { data: { session } } = await supabase.auth.getSession()
if (session?.access_token) {
window.__AUTH_TOKEN__ = session.access_token // !!!
setUser(session.user)
setLoading(false)
}
}

I also took the opportunity to try out AI coding assistants during development. I alternated between using Cursor, JetBrains Junie and Claude Code as I untangled the codebase and built new features (“vibe coding” kinda but with prior software engineering experience).

However, it wasn’t all magic – the AI sometimes produced messy or buggy code. It’s a bittersweet feeling when an AI speeds you to a solution that almost works, and then you dig for some time fixing edge cases. This was a big part of the development journey: embracing these tools for speed, but then stabilizing and refactoring the code to ensure Ezzi runs reliably.

Git is your friend.

Security and Privacy Enhancements

One alarming discovery was that the original app used Supabase endpoints without row security and hard-coded secrets that were never meant for production. It was possible to dump user data without proper auth. To get solutions without subscription or to generate subscription for yourself all without any authentication.

// App.tsx - subtracting user credits on the client
const { data: updatedSubscription, error } = await supabase
.from("subscriptions")
.update({ credits: currentSubscription.credits - 1 })
.eq("user_id", user.id)
.select("credits")
.single()
// App.tsx - checking user subscriptions
// removing ".eq("user_id", user.id)" allowed to fetch all the users
setSubscriptionLoading(true)
try {
const { data: subscription } = await supabase
.from("subscriptions")
.select("*, credits, preferred_language")
.eq("user_id", user.id)
.maybeSingle()

setIsSubscribed(!!subscription)
setCredits(subscription?.credits ?? 0)
if (subscription?.preferred_language) {
setCurrentLanguage(subscription.preferred_language)
window.__LANGUAGE__ = subscription.preferred_language
}
} finally {
setSubscriptionLoading(false)
}

Knowing this, I prioritized security fixes: I stripped out any “must be backend” endpoints, secured the remaining ones with proper authentication, and moved all variables to .env files not tracked in git.

The bottom line is that no personal data or API keys are ever exposed in the repo or in network calls. This was a non-negotiable improvement for me after seeing what happened with the original.

I even considered the threat of the app itself being detected by anti-cheat measures, so I made it possible to change window title, process name, and other identifiable strings during build time.

Learning Desktop Packaging

As a backend/web guy, one of the steepest learning curves for me was packaging and distributing a desktop application. During development I was running Ezzi in dev mode with npm run dev command.

But to share it with others, I needed installers. I learned to use Electron Builder to create an installer for Windows (which packages the app and the Node runtime), a DMG for macOS, and even AppImage for Linux. Each had its quirks.

For Windows, I went through code signing – a process where you need a certificate to sign your executable so Windows will trust it.

For macOS, I navigated notarization (Apple’s security checks for distributed apps) and dealing with the screen recording permission pop-up (which is critical for the user to accept, otherwise the app can’t see the screen). These were all new concepts to me.

Seeing friends download the app and have it “just work” felt like magic – it’s easy to take for granted how much packaging work goes into software until you do it yourself!

Right now I do not provide packaged versions, instead the user can download the code and build for their own OS, modifying app title and/or icon for extra invisibility. This eliminates the problem with any signing, you can run anything you build locally without worrying about code signing.

Self-Hosting vs Cloud: Choose Your Own Adventure

One big decision I made was to keep Ezzi’s core functionality free and open-source, while offering a convenient managed cloud service as well. The entire frontend (Electron app) code is open for anyone to inspect, build, and deploy on their own. If you value privacy or just like to tinker, you can run Ezzi 100% self-hosted – no subscription needed, just your own API keys for the AI services. On the other hand, if you don’t want to deal with setting up servers or managing API quotas, you can opt to use the Ezzi Cloud (a hosted backend that I run). Both modes give you the same Ezzi app experience, but there are trade-offs.

Self-Hosted Mode (DIY)

You compile the open-source Ezzi app, and point it to your own backend. This could be a server you run at home or on AWS, or even your local machine. You’ll need to set up the backend (your favorite stack) and get API keys from AI provider.

The upside is it’s free (aside from any API costs you incur) and fully in your control. You can even modify the code – want to integrate a new model or change the UI? Go for it. The downside is the initial setup effort.

By my estimates, it takes around an hour to get everything configured and tested if you’re starting from scratch.

I’ve written detailed docs to guide you, but yes, self-hosting is for the more tech-savvy or motivated users.

Ezzi Cloud (Managed Backend)

This is the “plug and play” option. I run the backend for you in the cloud. All you do is build the Ezzi frontend, you sign in to the app, and it uses cloud servers. You get access to the premium AI model (Claude 4) without needing your own backend.

The cloud service is how I plan to cover server costs: it’s a paid subscription model, but you can just pay for a short period if you only need it for a couple of interviews. If that’s not your cup of tea, no worries – stick to self-hosted, and you’ll still have full access to all of Ezzi’s features.

Ultimately, the existence of the cloud option doesn’t change the open-source nature of Ezzi. The frontend is MIT-licensed. I want users to trust this tool, and part of that trust is knowing exactly what the code is doing.

What I’ve Learned (and What’s Next)

Writing Ezzi has been a wild ride. On the technical side, I went from 0 to 100 with desktop app dev, grappling with packaging Electron apps for three OSes, dealing with weird bugs, and integrating everything from database listeners to AI APIs.

I also learned that AI coding assistants are not a replacement for understanding your own codebase – they’re tools, not teammates. I had to rewrite large chunks of AI-generated code to make it maintainable. In a way, cleaning up the codebase was cathartic and made me a better developer.

From the perspective of the tech industry, building (and now releasing) Ezzi has reinforced my belief that technical interviews need reform. When tools like this exist – and people feel compelled to use them – it’s a sign that the interview format isn’t working. My stance is that learning and cheating often use the same tools; the difference is intent.

I built Ezzi primarily as a learning aid and confidence booster. Yes, it can be used to cheat in an interview – and I’m not here to moralize or encourage that – but I know realistically some will use it that way.

My hope is that interviewers and companies will focus more on practical assessments and maybe even embrace AI assistance as a positive (after all, a developer who can effectively use AI tools might be more productive on the job). If Ezzi sparks that conversation, I’d consider it a success beyond just the software.

On a lighter note, I also got a crash course in what not to do when launching a side project. Don’t leave keys in your repo 😅, don’t assume “no one will ever try X” because someone will, and definitely do invest in good documentation early. I spent some extra time writing docs so that new users and contributors can get onboarded easily, and that has already paid off.

So, what’s next for Ezzi? Now that it’s open source, I’m inviting the community to help shape its future. The roadmap includes several exciting features: hint-only mode for gradual assistance, LeetCode crusher for focused practice sessions, quiz mode for quick multiple-choice questions, and take-home algorithm support.

I’m sure the community will have even more creative ideas. If you’re an engineer who finds this project interesting, check out the GitHub repo.

How to Get Ezzi

# Build & run Ezzi in dev mode (Mac / Linux)

git clone https://github.com/GetEzzi/ezzi-app.git

cd ezzi-app && npm i && npm run dev

Ezzi’s source code is available on GitHub, and the README has instructions for both using the managed backend and running your own.

To try it out:

  • Download the Ezzi app source code from the GitHub. It’s an Electron app, so one build works on your OS.
  • Decide on self-hosted vs cloud – If self-hosting, follow the docs to deploy the backend (choose your favorite stack). If using cloud, simply create a free account via the app.
  • Launch the app and log in or connect – On self-host, you’ll enter the URL of your backend and your API key. On cloud, just log in and choose a plan (there’s a free trial mode as well).
  • Start a practice session – maybe open a LeetCode problem or some coding prompt, and hit the hotkeys to capture it. Play around with getting hints and solutions. The UI has tooltips explaining each button and shortcut.

I’m both excited and nervous to see Ezzi out in the wild. Excited because I truly believe it can help people learn faster and feel more confident in interviews.

Nervous because, well, anything touching the interview-cheating topic can be controversial. But open-sourcing it is the right move – it brings transparency and opens it up for improvement.

In closing, if you’ve ever felt that knot in your stomach before a technical interview, or found yourself blanking on a binary tree problem you know you studied, Ezzi might be the kind of backup you’d want. It’s like an AI pair-programmer for your interviews – there if you need it. I built it out of frustration, curiosity, and a desire to make the tech interview grind a little more human (ironically, by using AI).

GitHub: github.com/GetEzzi/ezzi-app

Website: getezzi.com

I hope this was helpful. Good luck, and happy engineering!


Building Ezzi: My Journey Creating an Invisible Tech Interview Assistant (Now Open Source) was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding – Medium and was authored by Dmitry Khorev