Why Mac Text Replacement Does Not Work in Every App

If Mac text replacement works in some apps but silently fails in others, you have not misconfigured anything. The built-in system hooks into NSTextView - Apple's native text input framework - and only fires in apps that use it. Apps built on Electron use Chromium text fields that bypass NSTextView entirely. This is a platform-level architectural gap, not a bug. The only fix is a tool that operates below the framework layer - like Charm.

Why does Mac text replacement fail in some apps but not others?

The answer requires a brief look at how macOS handles text input. When you type in a text field on Mac, your keystrokes are processed through a pipeline. For native Mac apps - those built using Apple's AppKit framework - that pipeline includes a component called NSTextView. This is the standard text editing component that Apple provides to developers, and it integrates tightly with macOS text services: autocorrect, spell check, grammar check, and text replacement.

When you type a trigger abbreviation in an NSTextView-based field, macOS text services intercept the event, check it against your replacement list in System Settings, and perform the substitution before the character is displayed. This is why text replacement works in Apple Mail, Apple Notes, Pages, Safari form fields, and Messages - they all use NSTextView.

The breakdown occurs with Electron apps. Electron is a framework developed by GitHub that allows developers to build desktop applications using web technologies (HTML, CSS, JavaScript). An Electron app is essentially a Chromium web browser window inside a native-looking shell. Electron apps render their text fields using Chromium's own rendering engine, Blink. Chromium has its own text input pipeline, which it manages entirely independently of macOS.

When you type in an Electron text field, your keystrokes go into Chromium's input handler. NSTextView - and by extension all macOS text services - never receives them. The replacement check never runs. The trigger abbreviation passes through as literal characters, unchanged. From macOS's perspective, the keystrokes went into an app and never returned.

Studies of Mac App Store download data show that over 30% of the most-used productivity apps in 2024 were Electron-based. For users whose workflows centre on these tools, macOS text replacement is unavailable for a significant portion of their daily typing - through no fault of their own configuration.

Is this a bug that Apple could fix?

No. macOS text replacement is working exactly as designed. Apple's text services layer is built to integrate with apps that use the native AppKit framework. Apple does not have a mechanism to reach inside third-party app frameworks and force them to use macOS text services.

Electron itself is not doing anything wrong either. It is a legitimately designed framework that gives developers a way to target multiple platforms with one codebase. The trade-off is that Electron apps opt out of the platform-native text services on every OS they run on - not just macOS. This is a known and accepted trade-off in the Electron development community.

The result is a gap that neither Apple nor the app developers are motivated or able to close unilaterally. Apple cannot reach into Electron. Electron developers would need to reimplement macOS text services from scratch inside their app to restore compatibility - a significant engineering investment for a feature that most users do not know they have lost.

For Mac users, this gap has existed since Electron apps became mainstream around 2015-2016. It is not new, and it is not going away. Understanding that it is architectural rather than configurable is the first step toward finding the right solution.

How can you tell if an app is causing the problem?

The quickest diagnostic test is to check whether your text replacement works in Apple Notes. Open Notes and type your trigger abbreviation followed by a space. If it expands correctly, your replacement is configured properly and the problem is specific to the other app.

If the replacement works in Notes but not in another app, that app is not using macOS text services for its text input. The app is almost certainly Electron-based or uses another non-AppKit rendering framework.

To confirm whether a specific app is Electron-based:

  1. Right-click the app icon in your Applications folder or Finder.
  2. Select Show Package Contents.
  3. Navigate to Contents/Frameworks or Contents/Resources.
  4. Look for folders named Electron Framework.framework, Chromium Embedded Framework.framework, or similar. If you find one, the app is Electron-based.

Alternatively, look in the app's Contents/MacOS folder. Electron apps typically have a binary with the same name as the app and a separate Electron Helper process. These are reliable indicators of the Electron framework.

What can you do to fix text replacement in every app?

There is no fix available through macOS System Settings. No toggle, no permission change, and no macOS update will make the built-in system reach into Electron apps. The limitation is at the architecture level - below the user settings layer entirely.

The solution is a tool that operates below the layer at which app frameworks diverge. Charm does this using CGEventTap, a macOS API that intercepts keyboard events at the OS kernel event level. CGEventTap receives keystrokes before any application framework - AppKit, Electron, Qt, or anything else - has a chance to process them.

Because Charm sits in the kernel event pipeline, it sees every keystroke typed anywhere on the Mac. It monitors the stream for trigger abbreviations, and when a match is found, it deletes the trigger characters and types the expansion instead - before the application receives any of the original input. The application only ever sees the expanded text.

This approach is architecture-agnostic. Electron apps, Qt apps, custom-framework apps, and native AppKit apps all receive keystrokes through the same kernel event pipeline. Charm's interception point is earlier than any of them. This is why Charm's text replacements work everywhere while the built-in system does not.

Step-by-step fix: using Charm for universal text replacement

  1. Confirm the diagnosis. Test your replacement in Apple Notes. If it works in Notes but not in your failing app, the diagnosis is confirmed: the app is not using macOS text services.
  2. Download and install Charm. Visit theodorehq.com/charm and download Charm. Move it to your Applications folder and launch it.
  3. Grant Accessibility permission. Charm will prompt you to grant Accessibility access in System Settings under Privacy and Security. This is required for CGEventTap to function. Click through the prompt, enable Charm in the list, and return to the app.
  4. Add your replacements in Charm. Click the Charm menu bar icon and open Text Replacements. Add the same triggers and expansions you use in macOS text replacements, or create new ones.
  5. Test in the previously failing app. Type your trigger in the app where macOS text replacement was failing. The expansion should fire immediately.

You do not need to disable macOS text replacements when using Charm. The two systems operate at different levels and do not interfere with each other. macOS replacements continue to fire in native apps; Charm covers everything else. Running both gives you the widest possible coverage with no configuration conflict.

Summary of why this happens: macOS text replacement hooks into NSTextView (AppKit layer). Electron apps use Chromium text fields (bypass NSTextView). There is no macOS setting that bridges this gap. The fix is CGEventTap - a kernel-level interception that runs below all app frameworks. That is what Charm uses.
Set up text replacements that work everywhere on Mac
Charm text replacements fire in every app. One-time purchase. No subscription.
Learn more about Charm Get Charm for Mac $9.99

Frequently asked questions

Why does Mac text replacement not work in some apps?

macOS text replacement hooks into NSTextView, the text input framework used by native AppKit apps. Apps built on Electron use Chromium text fields that manage their own input pipeline independently of macOS. When you type in an Electron text field, NSTextView never receives the keystrokes - so text replacement is never triggered. This is architectural, not a configuration problem.

Can I fix Mac text replacement not working in Electron apps?

Not with System Settings. There is no macOS preference that bridges the gap between the AppKit text services layer and Electron's Chromium text fields. The fix is a tool that operates at the kernel level, below all app frameworks. Charm uses CGEventTap for exactly this - it intercepts keystrokes before any framework sees them, so replacements fire in every app.

How do I know if an app is blocking my Mac text replacements?

Test in Apple Notes first. If your replacement works in Notes but not in another app, the other app is not using macOS text services. You can confirm it is Electron-based by right-clicking the app in Finder, selecting Show Package Contents, and looking for an Electron Framework or Chromium Embedded Framework folder inside.

Is it a Mac bug that text replacements do not work in all apps?

No. macOS text replacement works as designed - it integrates with the AppKit text services layer that native apps use. Electron and other non-AppKit frameworks simply opt out of that layer. Apple cannot force third-party apps to use macOS text services. This is a platform reality, not a defect in macOS or in the apps themselves.