Skip to content
01 / 02§ Case study

Resumind

An AI resume analyzer that scores a CV against a specific job description and returns structured, actionable feedback — running auth, file storage, and model inference entirely client-side.

Year

2025

Role

Design & build

Stack

React Router v7 · TypeScript · Puter.js · Zustand · Tailwind CSS · Vite

Fig. 01Resumind interface

Resumind interface

01 — Problem

Generic resume checkers grade you against nothing in particular. You get a number and no idea what to change. I wanted the opposite: paste the job you actually want, get feedback tied to that posting. The catch was cost — an AI tool with per-user file storage and inference normally means a server, a database, and a bill that grows with every visitor.

02 — Build

No backend, on purpose

Puter.js handles auth, file storage, and model inference from the browser, billed to the end user rather than to me. That removed the entire server tier: no API routes to secure, no keys to leak, no database to run. The whole app deploys as static output.

A scoring pipeline, not a single prompt

Feedback comes from structured prompts that return typed JSON — ATS compatibility, tone, content, structure, and skills, each with its own score and specific fixes. Parsing into a schema instead of rendering raw model prose is what makes the results renderable and comparable across runs.

A dashboard that survives real use

Uploads accumulate fast, so the tracker got search, sort, archive and restore, inline editing, and one-click export of feedback to a text file. Global state runs through Zustand — a small store beat prop-drilling across the upload, results, and dashboard routes.

Fig. 02Resumind — additional view

Resumind — additional view

03 — Decisions & tradeoffs

Client-side inference over a Node API layer
Kept hosting free and stateless. The tradeoff is a hard dependency on an external SDK and no server-side rate limiting — acceptable for a tool where each user brings their own quota.
Typed JSON responses over free-form model output
Made the UI deterministic. A malformed response fails one card instead of blanking the page.
React Router v7 over Next.js
The app is genuinely client-heavy — there is no SSR to gain when every operation happens in the browser. Less machinery for the same result.

Command palette

Jump to a section, open a case study, or change the theme