We fill forms every day.
Signups.
Checkout pages.
Job applications.
Contact forms.
And every time, we type:
- Name
- Phone number
- Address
Over and over again.
So I built a Chrome extension called TypeLess to solve exactly that.
This post isn’t just about the idea—I'll walk you through how it actually works under the hood, what I learned, and the technical challenges I faced.
The Core Idea
The concept is simple:
Save your personal details once → Autofill forms anywhere with one click.
- No backend.
- No accounts.
- No external APIs.
Everything runs locally inside the browser.
But implementing that required understanding how Chrome extensions really work.
Understanding Chrome Extension Architecture (Manifest V3)
A Chrome extension isn’t a normal web app.
It has multiple isolated environments:
- Popup – The UI when you click the extension icon
- Background Service Worker – Runs in the background and handles events
- Content Script – Injected into web pages
- Options Page – Full settings page Each environment runs separately and communicates using message passing.
This separation is powerful—but it changes how you structure logic.
How TypeLess Is Structured
Here’s the simplified architecture:
User Action (Shortcut / Click)
↓
Background Service Worker
↓
Send Message to Active Tab
↓
Content Script
↓
Detect & Fill Form Fields
1️⃣ Storing User Data
User data (name, email, phone, etc.) is stored using:
chrome.storage.local.set({ userData: formValues });
Why chrome.storage.local?
- It’s asynchronous
- It’s extension-scoped
- Data never leaves the browser
One thing to note: unlike localStorage, Chrome storage is async, so you must handle it properly:
chrome.storage.local.get("userData", (result) => {
const data = result.userData;
});
If you forget the async nature, things break quickly.
2️⃣ Triggering Autofill
I added keyboard shortcuts using the chrome.commands API:
chrome.commands.onCommand.addListener((command) => {
if (command === "autofill_form") {
// Send message to active tab
}
});
The background service worker listens for this event and sends a message to the active tab:
chrome.tabs.sendMessage(tabId, { action: "FILL_FORM" });
3️⃣ The Hard Part: Detecting Form Fields
This is where things get interesting.
Forms are inconsistent across websites.
You’ll see inputs like:
<input name="email" />
<input id="user_email" />
<input placeholder="Enter your email" />
Some frameworks:
- Don’t use traditional labels
- Wrap inputs in custom components
- Manage state internally (React, Vue)
So I built multiple detection strategies:
- Match by name
- Match by id
- Match by placeholder
- Check associated
- Fuzzy matching
Example approach:
const inputs = document.querySelectorAll("input, textarea");
inputs.forEach((input) => {
const fieldName = input.name || input.id || input.placeholder;
if (fieldName?.toLowerCase().includes("email")) {
input.value = userData.email;
// Trigger proper event for React/Vue forms
input.dispatchEvent(new Event("input", { bubbles: true }));
}
});
Important: React Forms
Just setting input.value isn’t enough for React apps.
You must dispatch the input event so React updates its internal state.
This was one of the biggest “aha” moments during debugging.
Content Security Policy (CSP) Gotcha
Chrome extensions have strict CSP rules.
- No inline scripts
- No inline event handlers
So things like this won’t work:
<button onclick="fillForm()">Fill</button>
Instead, you must attach event listeners in JS files.
This forced me to structure code more cleanly—which was actually a good thing.
Injection Limitations
Extensions cannot run on:
- chrome:// pages
- Chrome Web Store pages
Also, permissions must be clearly defined in manifest.json.
For example:
"permissions": [
"storage",
"activeTab",
"scripting",
"commands"
]
If permissions don’t match usage, the extension won’t work — or worse, it won’t pass review.
Why I Didn’t Use a Backend
I intentionally avoided:
- Remote databases
- Analytics tracking
- User accounts
Everything is local.
This simplified:
- Architecture
- Privacy compliance
- Chrome Web Store approval
Sometimes less infrastructure = better product.
What I Learned Building TypeLess
Here are some practical takeaways if you're thinking about building a Chrome extension:
1️⃣ Think in Isolated Contexts
Popup ≠ Background ≠ Content Script.
2️⃣ Chrome APIs Are Event-Driven
Everything revolves around listeners and messaging.
3️⃣ Modern Forms Are Tricky
React/Vue require event dispatching.
4️⃣ Async Storage Changes Logic Flow
Don’t assume synchronous reads.
5️⃣ Small Tools Still Require Good Architecture
Even “simple” ideas can get complex quickly.
What’s Next
I’m currently experimenting with:
- AI-based smart field inference
- Auto-splitting full name into first/last
- Generating age from DOB
- Optional cross-device sync
But the core philosophy stays the same:
- Keep it lightweight.
- Keep it private.
- Keep it useful.
If you’ve been thinking about building a Chrome extension — I highly recommend trying it.
It forces you to understand the browser at a deeper level.
And you might end up solving a problem you personally face every day.
If you have questions about Chrome extension development, feel free to ask. 👇
https://chromewebstore.google.com/detail/lhcafeinbeaaingfhamcdpgnmafnpoic?utm_source=item-share-cb

Top comments (0)