Lab

Building · 45%

ApplyOnce

A local-first Chrome extension that remembers job application answers and reuses them across different career websites, with optional AI-assisted profile setup.

Automation

Overview

Status
Building
Progress
45%
Difficulty
Challenging
Started
Aug 28, 2026

Stack & tools

Technologies
JavaScriptHTMLCSSChrome Extensions Manifest V3Chrome Active Tab APIChrome Scripting APIChrome Storage APIOpenAI Responses APINode.js test runner
Software
Google ChromeGitGitHubCodex

01 / MOTIVATION

Why I built this

Applying for jobs can become a form-filling exercise. Every company seems to use a different career website, and each system asks for the same information in a slightly different format. Copying answers from a CV or a previous application technically works, but it becomes exhausting when applying to many roles. The work is repetitive, easy to get wrong, and unrelated to the actual quality of the application. I built ApplyOnce around a simple idea: I should only need to answer the same question once. The browser can remember that answer and offer it again when a similar field appears somewhere else.

02 / QUESTION TO EXPLORE

What I wanted to understand or solve

There is no consistent format across job application platforms. One website may ask for an “email address,” another for “personal email,” while another uses an internal field name with little visible context. The challenge is not only filling text inputs. Forms can contain selects, radio groups, checkboxes, dynamically rendered components, and questions that look similar but require different answers. Automating too aggressively also creates risk. A wrong answer can be worse than leaving a field empty, especially for salary, work authorization, identity, demographic, or other sensitive questions. Submission should never happen without the user reviewing the form.

03 / APPROACH

How I turned the idea into something testable

ApplyOnce scans supported fields on the active page after the user opens the extension. It collects signals such as the visible label, field name, placeholder, autocomplete value, input type, and available options. Those signals are normalized and compared with answers stored in Chrome. Common variations such as “e-mail address” and “email” can resolve to the same remembered answer without requiring an AI request. When no suitable answer exists, the extension asks the user to answer the field. That answer is saved with several aliases so a similar question can be recognized on a later application. AI is optional. A user can provide an OpenAI API key and upload a CV or LinkedIn profile PDF or CSV. The extension asks the model to extract factual profile information and generate initial answer memories. AI can also suggest an answer for an ambiguous field, but the suggestion is not filled or saved until the user reviews it. The extension deliberately skips passwords, file uploads, and submit controls. Sensitive bulk-fill matches require additional confirmation, and the public repository contains no personal seed data.

04 / FIELD NOTES

The repetition was the actual problem

The initial frustration was not that job application forms were technically difficult. It was that the same administrative work kept returning.

Name, contact information, employment history, profile links, education, language proficiency, and notice period already existed somewhere. Yet every application system treated them as new information. During a period of applying to many roles, even simple copying and pasting became a noticeable amount of work.

Starting with deterministic matching

I did not want every field to require an AI request. Many form labels can be matched with simpler rules.

ApplyOnce normalizes labels and handles several common synonyms. A remembered answer can have multiple aliases, and the extension calculates a similarity score before treating a field as a match. The matching threshold can be adjusted when the default is either too strict or too permissive.

This makes the common path local, immediate, and free of API usage.

Building memory one answer at a time

When ApplyOnce finds an unfamiliar field, it does not silently guess. The popup shows the question and lets the user enter or select an answer.

Saving the answer also records useful signals from the field, including its label, name, placeholder, and autocomplete value. The next website may use different wording, but those aliases give the matcher more context.

Users can inspect, edit, delete, export, import, or completely clear this local memory.

Using AI as an optional interpreter

AI is most useful during initial setup and when a field cannot be understood through deterministic matching.

The profile importer accepts a user-selected CV or LinkedIn profile. It asks the model to extract factual information while explicitly avoiding unsupported assumptions about salary, identity, demographics, work authorization, and similar sensitive topics.

For ambiguous fields, AI receives the structured local profile, saved answers, field label, and available options. Its output is presented as a suggestion rather than an automatic decision.

This feature requires an OpenAI API key, not a ChatGPT login or session token. It consumes API tokens and does not have access to the user’s existing ChatGPT conversations.

Keeping the public build clean

I used my own CV and LinkedIn profile while developing the seeded personal version. That data could not be included in a public repository because extension source files are visible to anyone who downloads them.

The public build therefore starts with an empty profile and empty memory. Each user has to import or enter their own information.

The API key is kept in Chrome session storage instead of being bundled with the source or permanently saved by the extension. For a larger public release, I would still prefer a backend authentication and proxy layer over asking general users to manage their own API keys.

The browser is not a consistent environment

Native HTML inputs, text areas, select elements, checkboxes, and radio groups are supported by the current version.

The difficult part is that many recruitment platforms build their own form components. A control may visually look like a normal dropdown while behaving like a collection of nested elements managed by a JavaScript framework.

Workday, SuccessFactors, and similar platforms will need dedicated adapters and a larger compatibility test matrix. The current version should be treated as a working foundation rather than universal job-form automation.

LET'S TALK

Something worth talking about?

Product, systems, something you're building, or just an idea worth comparing notes on—feel free to reach out.