惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
腾讯CDC
S
SegmentFault 最新的问题
D
DataBreaches.Net
Hugging Face - Blog
Hugging Face - Blog
L
LangChain Blog
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
N
Netflix TechBlog - Medium
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 三生石上(FineUI控件)
F
Fortinet All Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Martin Fowler
Martin Fowler
雷峰网
雷峰网
J
Java Code Geeks
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
云风的 BLOG
云风的 BLOG
T
Tailwind CSS Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
I rewrote the same CV bullet 30 times last quarter. So I ...
Hamza · 2026-05-15 · via DEV Community

Hamza

Last year I was applying to a mix of senior engineer, staff engineer, and engineering manager roles. Different role families, different keywords, different framing. Same five bullets at the top, rewritten thirty different ways across thirty different Google Docs.

Every recruiter call ended with "can you send the latest version" and a small panic about which version that actually was.

I tried the obvious tools first.

What existing builders kept doing wrong

Zety and Resume.io charge you to download the PDF, then nudge you toward an AI that rewrites your bullets into the same generic prose every other applicant is also generating. You end up paying monthly for a CV that sounds like everyone else's CV.

Canva and Word templates look fine until you try to maintain three versions in parallel. Edit a bullet in one, forget to copy it to the others, send the stale one to the recruiter. Ask me how I know.

Google Docs with branching folders works for a single career chapter. By the third role family you're keeping a mental map of which doc has the rewritten "led a team of 8" line vs the "shipped X to Y users" line.

The actual problem wasn't writing. I can write bullets. The problem was maintenance, version sprawl, and an AI layer that kept trying to write FOR me instead of helping me polish what I'd already written.

So I built Dossier.

The two design rules

Everything else falls out of these:

1. Separate content from presentation. You enter your career data once. Templates render it. Switching from a single-column ATS-friendly layout to a two-column modern one is a click, not a rewrite.

2. Your data lives in your browser. No cloud account required to use the tool. Zustand state, persisted to IndexedDB. The optional Supabase sync is opt-in, not the default.

The third rule, which I think matters more than people give it credit for: AI assists, never authors. You can ask the AI to tighten a bullet, suggest stronger verbs, or flag wordy sections. It will not generate a CV from scratch. The output stays yours.

The stack

Standard Next.js App Router. Nothing exotic.

  • State: Zustand, with a custom persistence middleware that writes to IndexedDB via idb. LocalStorage gets the small stuff (UI preferences), IDB gets the actual resume profiles.
  • PDF rendering: @react-pdf/renderer. Each template is just a React component. Adding a new template means writing JSX, not editing an opaque template engine.
  • UI: shadcn/ui on top of Tailwind. Boring, fast, easy to extend.
  • AI: optional, on-demand calls to OpenAI or Anthropic, scoped to a single bullet or section. No background "always improving your CV" loop. You hit a button, you get a suggestion, you accept or reject it.

The interesting part of the build wasn't any single piece. It was deciding what NOT to add.

No cloud-first architecture. No subscription. No required login. No AI auto-rewrite. No analytics on what bullets users edit. The product becomes radically smaller when you keep saying no.

What it looks like in use

The flow that finally killed my five-Google-Docs problem:

  1. Create a profile per role family. "Senior Engineer", "Staff Engineer", "EM". Each profile is a separate set of content data.
  2. Edit bullets per profile, switching profiles from a dropdown.
  3. Pick a template. ATS-friendly for keyword-matching applicant tracking systems, two-column modern for hiring managers who'll actually read it.
  4. Export the PDF. Done.

When a recruiter asks for "the latest version," I open the right profile, pick the template they probably want, click export. Maybe 30 seconds.

The AI assist sits next to each bullet. You write a draft. You can ask it for a stronger version, a shorter version, or a version that emphasises a specific keyword from the job description you're applying to. The model returns suggestions. You pick one or you keep yours.

There's no "generate my whole CV" button. There won't be one.

The tradeoffs I made

Local-first has real costs and I want to be honest about them.

  • No automatic cross-device sync unless you opt into the (free) Supabase account. Most users don't bother. They export their data to a JSON file if they need to move machines.
  • No "saved in the cloud" reassurance. If you clear your browser storage, the data is gone. Export to JSON is one click but the user has to remember to do it.
  • No analytics on individual edits. I can't tell you which bullets users delete most often, because I can't see them. Some product decisions get made on instinct instead of data.

These are the right tradeoffs for this product. People applying to jobs have a reasonable expectation that their employment history isn't sitting in a vendor's database forever. The product reflects that.

Where it is

About 200 active users. Eight templates. Growing without ads.

If you're applying to multiple roles and tired of maintaining parallel CVs, or you've bounced off a builder that kept trying to write for you, give it a look: https://your-dossier.xyz

It's free. No account required to start. Data stays on your machine.