32
92 Comments

I built a browser extension for the thing that was eating my day

The most time-consuming part of my work isn't the hard stuff. It's retyping the same sentences.

When I write product listings, it's the same phrases over and over — "Durable and lightweight, perfect for daily use." When I answer support emails, half the sentences are identical: apologies, shipping delays, return policies.

I started with a text file and copy-paste. Then OS-level snippets — but they fall apart the moment I switch languages, and I work across English, Japanese and Chinese every day.

I tried TextExpander and Magical. Both are powerful. Both are subscriptions starting around $10/month. I just wanted something dumb and simple: no account, no cloud sync, no update popups. Pay once.

Couldn't find it, so I built it. A browser extension — type a short code you define, hit space, it expands into full text. Works in any input field on any site. Fully local, nothing leaves your machine.

Free tier holds 5 shortcuts. Pro is $9.90 one-time. It's on the Edge add-ons store: https://microsoftedge.microsoft.com/addons/detail/jfhfkebcjclljnbphhbpihcohnpobloa

I'm not here to sell you anything though. I want to ask: how do you handle repetitive typing? Am I missing some obvious tool that everyone else is already using?

on September 28, 2026
  1. 2

    A tiny usage counter per shortcut could help users see which five earn their slots; people usually remember what they want to automate, not what they actually repeat. I’m building MP5 so people can talk ideas through and get them into something real fast — if you have 20 minutes as a guest, try it and tell me if it’s useful: https://mp5-production.up.railway.app/

    1. 1

      "People remember what they want to automate, not what they actually repeat" — that's the sharpest version of this anyone's given me. It's also the argument for showing users where their memory and reality disagree, which is more useful than either one alone.
      The counter keeps coming up today. It's on the list.

  2. 2

    "Pay once, no cloud sync" resonates. A chunk of my own users just want the repetitive part automated without another subscription. Did dropping the subscription model change who buys, compared to when the $10/month tools were your competitors?

    1. 2

      Honest answer: I don't know yet. I have zero paying users, so there's no before-and-after to compare. What I can say is that a one-time price isn't a growth strategy, it's a positioning choice, and it only works if people find me some other way. That's the part I'm still failing at.

  3. 1

    Building for your own biggest time sink is such a good filter. How did you decide it was worth turning into a product for other people?

    1. 2

      Honest answer: I didn't decide — I got pushed. Someone watched me use it and said "I want that" without me pitching. That's a weaker signal than it sounds: saying it is free, and I still have zero paying users. So the filter you're describing only runs one way — it tells you what to build, not whether anyone will pay for it.

  4. 1

    The full-width Chinese IME trigger bug you mentioned is exactly the sort of edge case that makes "works in any input field" hard to promise. Keeping expansion local and simple is a good boundary, but I'd test the trigger in the actual English, Japanese and Chinese fields you use for listings and support, not only in a plain text box. Which editor or input method has been the hardest one to make reliable so far?

    1. 1

      The hardest one isn't an IME — it's rich-text editors. Google Docs and anything on contenteditable keep their own cursor model and swallow key events before we ever see them; inside shadow DOM the event target gets retargeted to the host, so the original code silently did nothing. That cost me a fix. On IMEs, full-width Chinese is the one that bit me — fixed now. Your suggestion is the part I've done least well: I only test in the fields I personally type in, which is much narrower than real English + Japanese + Chinese support work.

  5. 1

    Identifying what's eating your day and building the solution is underrated. Most people complain about friction but don't measure how much time it's actually costing them. By identifying it, building a tool, and now sharing it, you've already captured the essence of what makes a good product - you solved your own problem first.

    1. 1

      Fair — and I'll take the hit on the part I skipped: I never measured it either. I knew the retyping was annoying; I never counted the minutes. So I built the fix before I had the number, which is exactly why I still can't tell anyone what it's worth. "Solved my own problem" is a real signal — just not one about the market.

  6. 1

    I feel this! I run a small home bakery and send the same messages all day: order confirmations, pickup times, "thank you for your order." And I switch between English, Arabic, and French, so the language problem is very real.
    On my iPhone I use the built-in Text Replacement (Settings → General → Keyboard). It's free, but it's phone only and hard to manage when you have a lot.
    Love the pay-once price. $9.90 one time is much easier to say yes to than another monthly bill. Good luck!

    1. 1

      Three languages in a bakery is exactly the case that made me build this — I was switching between English and Japanese all day and OS-level tools kept losing one of them.

      Worth knowing before you get interested: this doesn't overlap with Text Replacement on your iPhone. Mine is desktop-browser only, so it covers the order messages you type on a laptop, not the ones you send from your phone. If most of your messages go out from the phone, this won't help you at all, and I'd rather say that now than have you install it and find out.

      Which half is it for you — laptop or phone?

  7. 1

    Sounds like a great shortcut for a problem. Don't know your workflow, but maybe there might be other aspects to the workflow that would allow you to reduce your total time commitment even more. Maybe pre-categorization for support emails or something like that.

    1. 1

      Pre-categorisation is the interesting one, because the categories are exactly the part people can't articulate until they've seen their own history. Someone else in this thread suggested a per-shortcut counter for the same reason — you're both pointing at the same missing thing: I don't show people their own patterns.
      Have you seen that work anywhere? My worry is that any categorisation I ship is just my guess about someone else's inbox.

  8. 1

    The "no account, no cloud sync, pay once" part is what got me. Most tools in this space feel like they're built for the vendor's MRR, not for the person typing. Curious how you're getting people to find it on the Edge store. Is it mostly search or are you sending traffic there yourself?

    1. 1

      Honest answer: neither. The Edge store gives a brand-new extension with zero installs no search weight at all — I can't find it by typing its own name, and the impressions count is literally zero. So right now the answer is "nobody finds it," and I'm the one sending the traffic.
      Which means the thing you're really asking — does the store surface you — has a specific answer: not until you already have installs. That's the loop I'm trying to break, and it's why I'm here instead of optimising my listing keywords.

      1. 1

        yeah that's the classic bootstrap problem, store won't rank you till you have installs but you can't get installs without ranking. pretty much every channel pulls this on you

  9. 1

    That's actually pretty useful... nice one

  10. 1

    Honest answer: no usage data, so this is a guess. I'd bet the repeat-use winners aren't the ones that save the most keystrokes — they're the ones where getting the wording wrong has a cost. Support replies, canned answers, anything you've already written once and don't want to reconstruct.

  11. 1

    The insight here is that TextExpander and Magical are solving a much bigger problem than what you actually needed. Both assume you want 'templating' - a general system for storing and recalling snippets. Your problem was narrower: same phrase, different language context, same day. You didn't need the UI, the sync, the subscriptions. You just needed the mechanics. Building your own tool 10x simpler because you removed everything that wasn't your actual problem.

    1. 1

      You've described the design more clearly than I did. The honest version of "removed everything that wasn't your problem" is that I removed everything I couldn't build alone — narrow was a constraint before it was a strategy. It just happened to land on something you could also use.
      The part I'm unsure about: narrow also means that if your problem is 20% different from mine, the tool is useless to you. How do you tell the difference between scope that's focused and scope that's just small?

  12. 1

    For support replies I keep a small "reply library": one row per scenario (shipping delay, return window, refund issued) with a short code each, and once a month anything I typed by hand 3+ times gets promoted to a snippet. The multi-language angle feels like your real edge. Naming codes by scenario plus language (;ship-en, ;ship-ja, ;ship-zh) keeps the same reply grouped across languages instead of three separate lists to maintain. One thing that usually pushes people back to manual typing is per-customer details, so placeholders for name/order number inside a snippet would go a long way. Does Pro support variables like that yet?

    1. 1

      No variables yet, and your reason is the one that convinces me — per-customer details are exactly why people fall back to typing. Right now a snippet is literal text, so there's nothing to fill in.
      Two things I'd want to get right before shipping it: what happens when a placeholder is left empty (does it type the braces, or nothing?), and whether the cursor should land inside the first one after expanding. How do you handle that today — fill them in as you go, or paste first and edit after?

  13. 1

    "Really appreciate the local-first approach and one-time pricing model [source: 1]. Subscription fatigue is definitely real for simple productivity utilities, and handling multi-language snippets without sync bloat solves a genuine pain point [source: 1]. Great build, will give it a spin!"

  14. 1

    The five-shortcut cap turns a support-inbox week into the test: whichever sentences get retyped most are the ones that earn a slot, and that only shows up by counting. Does the popup keep a tally of how often each shortcut fires, so the five can be swapped on evidence instead of from memory?

    1. 1

      No tally today — the popup shows which shortcuts exist, not how often each fires. You're the second person to ask, which is usually my signal to build it.

  15. 1

    Great idea. I used to do the same thing: I kept frequently used phrases in Windows Sticky Notes and copy-pasted them whenever I needed. I don’t know any other obvious tool beyond the ones you mentioned. So your extension sounds exactly like the simple, local solution I’d want.

    1. 1

      Sticky Notes plus copy-paste is basically the workflow I built this for — except my version was a text file I kept emailing to myself.

      Honest caveat before you get interested: I have zero users, so "exactly what I'd want" is currently a sample size of you and me. And it's Edge-only right now — Chrome is blocked on a $5 developer registration my card won't pay. If you're on Windows, Edge is probably already installed:

      https://microsoftedge.microsoft.com/addons/detail/jfhfkebcjclljnbphhbpihcohnpobloa

      If you try it and it's not what you pictured, I'd rather hear that than not.

      1. 1

        Installed it — I’ll try it over the next day or two and share how it goes.

        1. 1

          Thanks for actually installing it. You may literally be user #1 — the store still shows zero installs.
          One thing worth poking at while you have it: expand a code, then hit Backspace right after. Someone further up this thread said my undo story is the weak spot, and I think they're right — I want to know if it actually bites in real use.
          No rush on the follow-up. If you don't reach for it again after a day or two, that's honestly the more useful signal for me.

  16. 1

    "Fully local, nothing leaves your machine" is doing a lot of work in your pitch, and I think it's underrated. With extensions, people's first question isn't "is it useful?", it's "what does it have access to?"

    I'm learning that the hard way with our own Chrome extension: the setup step where people have to trust it is exactly where most of them stop. You answered that question in one line before anyone asked it. I'd put it even higher, right next to the install button.

    1. 1

      Your point about the install step is the one I can't answer honestly, because you just walked me into a contradiction in my own pitch: I lead with "nothing leaves your machine," and then the browser presents a permission warning that reads nothing like that. Whatever I write in the copy, the warning is the sentence the user actually reads. I haven't solved it — I've been hoping the one-liner outshouts it.

      Which I think is your point: it has to land before the warning, not after. Noted.

      What does your setup step look like — a permissions prompt, an account, something else?

  17. 1

    The IME point is the one worth taking seriously, because it is not a bug you can fix with a better list. You chose a trigger that is also a character the user legitimately types, and the only reason it works most of the time is that composition produces it in a distinguishable way for some input methods and not others.

    That is a protocol design problem rather than a matching problem. When an abbreviation and a real word are identified by the same signal, every guard you add is a guess about intent that has to be right in an unbounded number of contexts: a code editor, a URL field, a CRM with an unusual form element, a chat box where the user pasted something. Each new exclusion is a patch on an ambiguity that never goes away. The fix that actually removes the class is to stop sharing the trigger: a distinct entry channel, an explicit prefix, or a key that no human types as prose. Then an accidental expansion stops being possible rather than merely unlikely.

    There is a second-order cost you are already paying. Because the trigger can misfire, every expansion has to be reversible, and undo has to be fast enough to beat the moment the user notices. That is a permanent tax on the interaction, and it exists only because the trigger is ambiguous. Remove the ambiguity and the undo affordance becomes optional instead of load-bearing.

    On my own account, since it bears on how you read the above: Piramyd is mine, and expansion triggers sit in exactly the class of problem it was meant to handle.

    So here is the choice I keep circling: give up the space-bar trigger, or give up expanding plain text into any field? Whichever survives tells you what your users actually came for.

    1. 1

      Your undo point is the one that actually landed, because it's true and I hadn't said it out loud: I fixed the IME case this week, but that only covers composition. Type ";;" by accident in a code editor and there's no quick way back — you delete it by hand. That's the permanent tax you're describing, and I'm paying it without having priced it.

      I'd push back on one thing though. The space-bar trigger is the product. I left TextExpander because every alternative asked me to remember a syntax or reach for an extra key, and the only reason this thing feels different is that your hands never leave the sentence. A dedicated key would make misfires impossible and make the tool something I wouldn't use myself. So I think it's a real trade rather than a design oversight — but you've made me think the price is higher than I'd accounted for, and the honest move might be to pay it down (a fast undo) instead of walking away from the trigger.

      Your last question is the one I can't answer yet. I have no users to ask, so both branches are still guesses. Noted as the thing to come back to.

  18. 1

    The local-first choice and one-time pricing feel like a clear response to subscription fatigue. I’d be curious which shortcut categories become repeat-use fastest.

    1. 1

      Honest answer: no usage data, so this is a guess. I'd bet the repeat-use winners aren't the ones that save the most keystrokes — they're the ones where getting the wording wrong has a cost. Support replies, canned answers, anything you've already written once and don't want to reconstruct. Saving keystrokes is a side effect; the real pull is not having to remember how you said it last time.

      I half expect to be wrong once real users show up. The boring mechanical ones (addresses, order numbers, signatures) might win instead precisely because they never change. No way to know until someone other than me is using it.

    2. 1

      Honest answer: no usage data, so this is a guess. I'd bet the repeat-use winners aren't the ones that save the most keystrokes — they're the ones where getting the wording wrong has a cost. Support replies, canned answers, anything you've already written once and don't want to reconstruct. Saving keystrokes is a side effect; the real pull is not having to remember how you said it last time.

      I half expect to be wrong once real users show up. The boring mechanical ones (addresses, order numbers, signatures) might win instead precisely because they never change. No way to know until someone other than me is using it.

  19. 1

    building a browser extension for the thing eating your day is the purest form of scratching your own itch - you feel the pain daily so the feedback loop is instant. we built swapfile.live the same way for file conversion (in-browser, nothing uploaded). did you start with the extension for yourself and realize others wanted it, or was it always meant to ship?

    1. 1

      Started for myself, out of pure irritation. I'd been paying for TextExpander for years and watched it grow into a platform; I wanted one thing — type ";;", get the text. Building it was the easy part.

      The half I got wrong is the "others wanted it" half. Zero paying users so far, so that's still an unverified guess rather than a finding. Posting this was partly an attempt to test it.

      Same question back at you for swapfile.live: did the first stranger arrive because of the tool, or because you happened to be standing where the right person was already complaining?

  20. 1

    The IME normalization story is a nice peek at how many of these bugs only exist in real users' hands — which is also the argument for finding strangers fast even at zero users. One behavior worth deciding before more people install: plain-text expansion fired anywhere means it will eventually fire in the places where it hurts — a ;; shortcut inside a code editor, a chat box, a CRM's URL field — and the user will blame the extension. The usual fix is an exclusion list (inputs marked code/URL/password and the backstage of specific sites) plus a dramatic undo (a quick ctrl+z right after expansion reverts it), which also softens every future misfire. It's cheap to ship now and much more annoying to retrofit once the first "your tool mangled my gist" complaint arrives. And since import/export is already on your list: version the export file from day one, even as {"v":1, "shortcuts":[…]} — it costs nothing today and saves a migration headache the day the format changes.

    1. 1

      Versioning: already done, and your timing is funny — export/import shipped a few hours ago as {format, version, exportedAt, count, shortcuts}. The version field is in there exactly because I could picture the migration problem you're describing, and I'd rather detect an old file than guess at one.

      The exclusion list and the dramatic undo are the two I haven't built, and your framing is what makes them make sense to me: they aren't features, they're the price of choosing an ambiguous trigger. Right now a misfire in a code editor costs the user a manual delete, which is worse than I'd been telling myself.

      Genuine question, since you clearly have the scar tissue: would you ship the exclusion list before you have users, or wait for a real complaint? I have zero paying users, so I can't tell whether I'd be defending against a real failure or inventing one.

  21. 1

    The local-only approach is appealing, especially for support text. The tricky part for me is accidental expansion while switching languages; a quick language toggle or per-language shortcut sets could make the workflow safer.

    1. 1

      That's the exact failure mode I shipped a fix for this week. Space belongs to the IME mid-composition, so the trigger shouldn't be evaluated at all while composing — an isComposing / keyCode 229 guard, checked before anything else runs. Your second half I haven't solved: shortcut sets scoped per language. Right now codes are global, and I can see the same code wanting different meanings in EN and JA. Filing it.

  22. 1

    The "no account, no cloud sync, pay once" bit is actually pretty appealing for something this small. There are a lot of simple tools where the subscription is more annoying than the product itself.

    1. 1

      Thanks — that's the bet exactly. The subscription tools beat mine feature-for-feature; what they can't offer is not being a subscription. Whether that's enough to make someone switch is the part I don't know yet, and I'd rather find that out with real users than guess.

  23. 1

    Since everything is stored locally, can users export and restore their shortcuts? Losing a library of support replies after switching computers would be a painful moment.

    1. 1

      Yes — and the timing is almost funny. You're the third person to raise it today, and I finished building it a few hours ago: JSON export/import, no new permissions, the file stays on your machine. It's in the build that went into review today. The free tier still caps at 5 shortcuts on import, otherwise it'd just be a backdoor around the paid version.

  24. 1

    I think you're right to emphasize the one-time advantage, and the pricing seems pretty solid as well. It did take me a minute to think of my own personal examples of potential phrases/applications (and everybody has some; it's just that it's not always intuitive). It might be something where visual examples (showing instances where a macro-ed phrase would slot right it) in everyday application could help people "get" it. Good luck!

    1. 1

      You're right that it isn't intuitive until you see it, and a screenshot can't show a trigger. I'm shooting a short screen recording of a real expansion — typed against a Japanese IME, so the composition case is visible instead of just claimed in the copy.

  25. 1

    Edge-only is leaving most of your market on the table given the manifest is nearly identical, though the real question for a local-first expander is IME handling — expanding on space is ambiguous when someone's mid-composition in Japanese or Chinese, which is exactly the case TextExpander handles badly.

    1. 1

      Both points land.

      On IME: this is the bug I shipped a fix for this week, and I'd have shipped it blind if someone hadn't flagged it. The fix isn't "ignore space while composing" — space belongs to the IME mid-composition, so the trigger shouldn't be evaluated at all: an isComposing plus legacy keyCode === 229 guard, checked before anything else runs.

      What made me actually trust it: I rolled the fix back and re-ran the suite. Exactly the two new IME tests failed — 8/10 — so they're catching the real thing rather than passing by coincidence.

      On Edge-only: you're right, and it's the same bundle — the manifest is nearly identical. The blocker is the $5 Chrome developer registration; it won't take my card. If you know a way around that, I'm listening.

  26. 1

    Totally agree. It's easy to get distracted by premature scaling when the real bottleneck is distribution.

    1. 1

      Agreed. The version of premature scaling I keep catching myself in is adding features while the honest blocker is that nobody knows the thing exists. Spent this week on distribution instead of code — which for me means finding threads where the problem is already being described out loud, rather than improving anything on my side of the screen.

  27. 1

    No account, no cloud sync, no update popups — you described the exact segment TextExpander abandoned. One distribution thought from building browser-based tools: the expansion trigger (short code + space) is the feature people demo to each other, so a 15-second GIF of exactly that on the store listing will do more than any copy. Also curious how you handle the multilingual part — switching between EN/JP/CN mid-snippet is where OS-level tools break, and if your expansion survives IME composition that is a real moat worth shouting about on the listing.

    1. 1

      Taking the GIF advice — the trigger is the entire demo and a screenshot can't show it. I'm going to shoot it against a Japanese IME so the composition case is visible rather than just claimed in copy.

      On multilingual: handled as of the build in review this week (isComposing / keyCode === 229 guard, and reading the caret through ShadowRoot.getSelection() for editors that live inside a shadow root).

      One correction to your last question, though: the listing isn't the binding constraint yet. I can't find my own extension on Edge by typing its exact name — a listing with zero installs gets no search weight, so better copy has almost no surface to work on. That's the part I haven't solved, and it's why I'm asking strangers here instead of optimizing screenshots.

  28. 1

    You are not missing an obvious tool. OS-level snippets, TextExpander and Magical are the real options, and the gap you named (no account, no sync, works offline) is genuine, so local-first is the right call. It is also the easier path through extension review, since Chrome and Edge both prohibit remotely hosted code. Everything the expansion needs has to ship in the bundle, and each permission needs a justification in the listing that matches what the extension actually does. A single-purpose tool that reads and writes text in input fields is easy to argue for.

    The part I would watch is where expansion fails silently. Inputs inside iframes, inputs inside shadow DOM, and rich text editors that are contenteditable rather than textarea. Those are the fields where a sniffer that works on a plain form does nothing, and they sit on exactly the sites where people type the most.

    On the pricing shape: pay once at $9.90 is defensible for something with no server cost, but nothing in it funds the next version. The structure that keeps the no-account promise and still pays for updates is a local unlock key pasted into settings, with the free cap set low enough that a real user hits it in days rather than weeks. Five shortcuts sounds workable; check it against a support-inbox week.

    For the first strangers, the store listing is the one channel you can edit without an audience, so treat the title and the first two screenshots as copy rather than as documentation. I am curious whether anyone outside your own contacts has installed it from search yet.

    1. 2

      This is the most useful comment I've gotten, and I went and checked my code against all four of your points.

      • contenteditable: handled, four separate branches.
      • iframes: handled — all_frames: true in the manifest.
      • shadow DOM: not handled, and you're right about why it fails silently. My listener sits on document in the capture phase, so the keydown does reach me — but the event is retargeted at the shadow host on the way out, so e.target is the host, not the input, and my isEditable() check bails. Any site rendering its composer inside a shadow root just does nothing.
      • The unlock-key-into-settings structure you describe is what I actually shipped: key pasted into the popup, verified once against Payhip, then fully offline.

      On your last question — no. Zero installs from people I don't know, and zero from search. Edge gives a new extension with no installs essentially no search weight; I can't find my own extension by typing its exact name. So the listing-copy advice is right, but I'm not sure copy is the binding constraint yet.

      Five shortcuts against a support-inbox week — I'll run that test.

    2. 2

      This is the most useful comment I've gotten, and I went and checked my code against all four of your points.
      contenteditable: handled, four separate branches.
      iframes: handled — all_frames: true in the manifest.
      shadow DOM: not handled, and you're right about why it fails silently. My listener sits on document in the capture phase, so the keydown does reach me — but the event is retargeted at the shadow host on the way out, so e.target is the host, not the input, and my isEditable() check bails. Any site rendering its composer inside a shadow root just does nothing.
      The unlock-key-into-settings structure you describe is what I actually shipped: key pasted into the popup, verified once against Payhip, then fully offline.
      On your last question — no. Zero installs from people I don't know, and zero from search. Edge gives a new extension with no installs essentially no search weight; I can't find my own extension by typing its exact name. So the listing-copy advice is right, but I'm not sure copy is the binding constraint yet.Five shortcuts against a support-inbox week — I'll run that test.

  29. 1

    Working across English, Japanese and Chinese is exactly where OS-level snippets fall apart, so building for that case makes a lot of sense. Fully local with a one-time price is a refreshing combination next to the subscription tools, and support replies are the perfect first use case.

    1. 1

      Thanks — the multilingual case is exactly why I built this. OS-level snippets kept breaking for me across English, Japanese and Chinese, and that specific friction is what pushed me to write my own. Support replies were the first thing I automated too.

  30. 1

    The space trigger is the thing I'd test hardest, specifically for your Japanese and Chinese work. With an IME on, space is what converts kana or pinyin into characters, so "type code, hit space" can fight the input method. Listening for compositionend, or offering a different trigger key per language, would save you some confusing bug reports.

    We run UtilitySEO in 7 languages, and the bugs that cost us most were the ones that only showed up outside English.

    On your question: our most repetitive writing is community comments (about 400 so far), and we deliberately avoid snippets there because identical phrasing reads as spam. Support replies and product listings are where expanders earn their keep.

    $9.90 once vs $10 a month is a strong line, I'd put it first in the store listing. Has anyone typing in Japanese hit the space clash yet?

    1. 1

      You're right, and I checked my code after reading this. You found a real bug.

      My keydown handler never checked isComposing, so on a Chinese or Japanese IME, hitting space to commit characters could fire the trigger mid-typing. English users would never hit it. CJK users would hit it constantly.

      I fixed it and added a regression test: the handler now bails on isComposing (and keyCode 229), and the test asserts the trigger does not fire mid-composition. I verified the test actually catches it by reverting the fix - it fails without the guard, passes with it.

      Your point about a per-language trigger key is the better long-term answer. A trigger that collides with the IME's commit key is a bad default for exactly the users I built this for.

      Thank you. This was the most useful thing anyone told me today.

  31. 1

    i suggest making it for free for a few days instead

    1. 1

      i still the idea tho

  32. 1

    Have you looked at whether the extension could also go on the Chrome Web Store? I'm not sure how the two stores work, but if Chrome users can't install from Edge's add-on store, that might be a lot of strangers you're not reaching yet.

    You said everyone who tried it wanted expansion without an account. Do you know yet whether strangers care about that too?

    1. 1

      Chrome is the right call and it's on my list. I'm currently blocked on the $5 developer registration — it doesn't accept my card — so Edge was the only door I could open. And no, I genuinely don't know yet whether strangers care about the no-account part. The honest state of things: the only people who've installed it are people I already know.

  33. 1

    For truly repetitive work, snippets are hard to beat. The gap is the in-between stuff, where the wording is similar but not quite the same. Think of a support reply that needs one sentence tailored to the customer. I built DictaFlow for that kind of work. Hold a hotkey, say what you mean, and clean up the transcript instead of typing the whole thing again. Your local-first, one-time-purchase approach makes sense for people who mostly want predictable expansions.

  34. 1

    Honestly, I think the “simple and local” angle is what makes this interesting. A lot of productivity tools keep adding accounts, cloud sync, integrations, and subscriptions when the actual problem is just expanding a few repetitive phrases.
    I also like that you considered multilingual workflows. One thing I'd be curious about is how you handle shortcuts across different keyboard layouts and languages. If it stays reliable without adding complexity, that could be a pretty compelling advantage over heavier text-expansion tools.

    1. 1

      Good question, and the honest answer today is "partially". Expansion output is plain text, so any layout works — but the trigger itself needs a full-width normalization pass, otherwise a Chinese IME's ;; never matches the ;; you actually typed. That one I had to fix specifically. Other layouts I haven't tested — if you use a non-US layout I'd genuinely like to know where it breaks.

      1. 1

        “That’s actually a useful edge case to catch. Full-width vs half-width punctuation is the kind of thing that works perfectly in testing and then breaks the moment someone uses a different IME or keyboard layout.
        I’d be curious whether you’re planning to normalize other common input variations too, or keep it intentionally limited to the trigger characters for now.

        1. 1

          For now, deliberately limited to the trigger. Normalizing every other input variation means guessing which one the user meant, and a text expander that expands the wrong thing is worse than one that misses. The trigger is different: it's a fixed token the user chose, so normalizing it is unambiguous. If you hit a variation that breaks, tell me and I'll widen it case by case.

          1. 1

            That seems like a reasonable tradeoff. False expansions are usually far more frustrating than missed expansions because they break trust in the tool.
            I also like the distinction you're making between user-defined triggers and general text input. With the trigger, you know exactly what the user intended, so normalization is relatively safe. Once you start normalizing arbitrary input, you're making assumptions on the user's behalf, which can get messy very quickly across different languages, layouts, and IMEs.
            The case-by-case approach sounds sensible at this stage. Real-world edge cases from users will probably tell you where normalization adds value much faster than trying to anticipate every possible input variation upfront.

            1. 1

              That last line is the one that stings: "real-world edge cases from users" assumes I have users. I don't yet — so I can't wait for them to tell me, and I can't guess my way there either. That gap is the actual problem, more than any input variation.
              If you ever hit a layout that breaks it, that one data point is worth more to me than this entire thread.

  35. 1

    Nice — building for a problem that was eating your own day is exactly why I made my camera app. Did you get your first users from the communities you personally belong to?

    1. 1

      Not yet — no users at all so far, which is the honest reason this post exists. The only people who've installed it are people I know. That's the part I'm worst at. How did you get the first strangers onto your camera app? That's the exact wall I'm stuck on.

      1. 1

        Honestly, we're at the same wall — launch day today and the first strangers are trickling in one by one. What felt least spammy so far: going to the exact subreddit where people complain about the chore my app removes, and describing the fix plainly instead of pitching. If a mod approves, those few installs mean more than any number from a broad post. Keep going — the zero-to-one step is the slowest.

        1. 1

          That's genuinely useful, thank you. Going to the exact subreddit where people already complain about the chore, and describing the fix plainly instead of pitching — that reframes it as helping rather than advertising, which is the part I keep getting wrong. Going to try it this week.

  36. 1

    The local-first approach is what caught my attention. A lot of productivity tools seem to add accounts, syncing, subscriptions, and extra features when the core problem is actually very simple. Keeping the workflow fast and offline makes a lot of sense, especially for repetitive support and product-description work.

    1. 1

      That's the whole bet — the core problem is simple, and everything the bigger tools pile on top is cost the user didn't ask for. Support replies and product descriptions are exactly my two use cases, so it's good to hear that's where it reads as useful.

  37. 1

    Solving multilingual expansion without relying on OS-level snippets or cloud subscriptions is a fantastic sweet spot. The friction of constant language-switching is real.

    Also, as Luca mentioned, adding a simple local JSON import/export early on will give users peace of mind without compromising the local-first philosophy. Great build!

    1. 1

      That's the second mention of JSON export/import today, so I'm treating it as a real signal rather than a nice-to-have. The tension is that I promised no cloud and no sync, and import/export is the honest way to keep that promise when someone switches machines. It's on the list.

  38. 1

    Most founders building alongside a day job focus entirely on non-compete clauses, but corporate legal teams usually catch engineers through environment configuration leaks, not contract disputes: Global Git Email Stamping: If you don't use directory-scoped configs (⁠[includeIf]⁠), ⁠git⁠ defaults to your global ⁠.gitconfig⁠. Committing to a personal repo with a work email header gives enterprise legal instant ownership grounds. Shared Router DNS Traffic: Working on a personal side-project while connected to enterprise VPN/Zscaler routes your dev traffic straight through corporate log collectors. EDR Process Isolation: Enterprise agents (CrowdStrike, SentinelOne) log local ⁠npm⁠ installs and CLI commands on monitored networks. I put together a step-by-step air-gap checklist and template config on my profile if you want to inspect your own setup.

  39. 1

    Have early users shown that the local, one-time model is what makes them switch, or is the main pull simply having text expansion without the complexity of bigger tools?

    1. 1

      Honest answer: I don't have paying users yet. Zero sales so far. So I can't tell you which reason wins — that's exactly what I'm trying to find out. What I can say is that everyone who's tried it so far said the same thing unprompted: they wanted expansion without an account. Small sample, take it with salt.

      1. 1

        That’s a useful early signal, especially since it’s coming up unprompted. If you’re open to it, what’s the best email to reach you on?

        1. 1

          Glad it landed — happy to keep talking. Best address is xintiao1230@outlook.com. What are you working on?

          1. 1

            Thanks! I’ve just sent it over.

            Looking forward to hearing your thoughts whenever you have a chance.

  40. 1

    Relatable. Support is where this hurts most. The other half of the fix is on the intake side: if the contact form asks the right questions up front (order number, what happened), a lot of those repeated "can you send me X?" replies disappear. That's what we work on at chatform.in (I work on it). Nice build, multilingual snippets without an account is a real gap.

  41. 1

    The local-first, one-time-price positioning is strong, especially for multilingual users. I’d add simple JSON export/import early—“no cloud” is a benefit until someone changes browsers or devices and worries about losing years of shortcuts.

    1. 1

      That's the second time someone's raised JSON export/import today, which is probably a signal. My hesitation: I promised myself no cloud and no sync, and import/export is the honest way to keep that promise when people switch machines. It's going on the list.

      1. 1

        That makes sense—keeping it local while adding import/export feels like a good balance.

        1. 1

          Quick update, since you're the reason: it's built and submitted — about twelve hours after you said it. Export writes {format, version, exportedAt, count, shortcuts}, versioned from day one so a file from a later build can't silently break. Import merges instead of overwriting, and it needed no new permissions.
          It's in Edge review now. "no cloud" only stays honest if the file is the user's to keep — that line is yours, I just wrote it down.