CLI tool
fcitx/fcitx5-macos avatar
fcitx/fcitx5-macos

fcitx5-macos ports the Fcitx5 input method framework to macOS

Fcitx5 macOS edition 小企鹅输入法 https://t.me/fcitx5macos qq: 874450150

530 stars33 forksSwiftGPL-3.0

At a glance

What is it?
fcitx5-macos is a Swift and C++ port of the Fcitx5 input method framework to macOS 13.3 and later, built with CMake rather than Xcode, packaged as a macOS input method with a plugin manager for engines and tables. It is GPL-3.0 licensed, ships nightly builds alongside 0.4.1, and the documentation covers building, code signing, debugging and translation workflows.
Who is it for?
fcitx5-macos suits a macOS user who wants the Rime or Mozc engines and the Fcitx5 configuration workflow rather than the built-in macOS input methods, and a developer who wants to work on a cross-platform input method framework in one tree rather than two separate codebases.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Swift, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the port is, and what it is not

Fcitx5 input method framework ported to macOS 13.3 or later, in Swift and C++, and the description names it as the Fcitx5 macOS edition.

The lineage is Fcitx5 itself, which is a framework rather than an input method. That distinction is the first thing to understand. Fcitx5 provides the container, the configuration layer, the add-on mechanism and the user interface, while the actual language engines are separate packages. The macOS port is the same framework, rebuilt for a platform whose input method system works quite differently from the X11 and Wayland world the original was designed for.

The README is explicit about what the port includes and what it does not. Fcitx5 only packages keyboard engine. To install other engines or tables, use the built-in Plugin Manager.

So the deliverable is the framework, the UI, and the plugin manager, and the engines are pulled in afterwards. That is why the topics list names both mozc and rime, since those are the engines people typically want and neither is bundled.

The installation path is documented as: please download the installer and read the documentation, with the installer at a separate fcitx5-macos-installer repository under the fcitx-contrib organisation and the documentation hosted at fcitx-contrib.github.io. Recommending a separate installer project rather than a build-from-source path is a reasonable choice for an input method, since getting the input method registered with the system is the fiddly part and it is easier to hand someone a working package than to document every step.

The project is GPL-3.0 licensed, the last push was on 2026-10-19, and the release history shows a nightly build on the same date alongside 0.4.1 from 2026-10-18 and 0.4.0 from 2026-09-22, so the project is shipping both stable tags and nightly builds.

Building it, which is not an Xcode project

The build section has a line that makes the whole approach clear: this is NOT an Xcode project, but Xcode 26.4 or later is needed for the Swift 6.3 compiler, and native and cross build on macOS 26.2 is supported.

So the build system is CMake, the compiler is Swift, and the toolchain requirements are recent. The dependencies come from Homebrew and the project scripts:

sh
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
brew install cmake ninja extra-cmake-modules gettext librsvg qpdf
./scripts/install-deps.sh
npm i -g pnpm
pnpm --prefix=fcitx5-webview i

The node and pnpm steps are there for the webview component, the panel that renders the Fcitx5 configuration interface, and the per-directory install is scoped to that package.

The build itself is a patch step followed by two CMake commands:

sh
./scripts/patch.sh
cmake -B build/$(uname -m) -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build build/$(uname -m)
sudo cmake --install build/$(uname -m)

The patch script is a normal part of a port, since the upstream code has to be adjusted for the platform. The build directory is named after the machine architecture, which is what makes a cross build and a native build coexist in one tree.

After the first cmake --install you have to log out and log back in, and then add Fcitx5 in System Settings, then Keyboard, then Input Sources, then Chinese Simplified. For installations after that, clicking Restart in the Fcitx5 menu suffices.

That last detail is the difference between a build tool and a deployment tool. The first install changes how macOS knows about the input method, and the macOS session caches that list, which is why a logout is required once and a restart of the app is enough thereafter.

The documentation also mentions that you can use Cmd+Shift+B in VSCode to execute a task, which is a convenience for developers working on the project inside an editor.

Code signing, which is a real deployment step

One short section covers the thing that most port documentation glosses over. Some features, such as notifications and core dump, require the app bundle to be code-signed after installation:

sh
./scripts/code-sign.sh

That matters because of how macOS treats unsigned or differently signed code. Notifications from an input method are how you get told about candidate windows and about your own status, and the platform will not deliver them from an app bundle that has not been signed. The core dump feature is more of a convenience than a feature, since the crash reporter on macOS does not produce a usable core dump for an unsigned binary.

The section is short but it changes the picture of what this project is. It is not a set of scripts that produce a binary you drop anywhere; it is something that has to be signed and installed into the system input method directory, and then registered with the operating system.

The repository layout reflects that. There are directories for the frontend, the notifications, the webview, the web panel, the keycode handling, the logging, the assets, the translations in po/, the patches, the cmake modules and the scripts, plus fcitx5, fcitx5-beast and fcitx5-webview as separate components, src/ and cache/ for the build, and an appium/ directory for the end-to-end tests.

There is also a version.jsonl at the root, which is where the nightly build numbers are tracked, and a .opencode/ directory and an opencode.jsonc at the top level, which suggests the project has started using an AI coding assistant configuration.

Debugging a native input method

The debug section is the part of the documentation that tells you the project is used by people who are not the author, because it covers the awkward cases.

For the log, there are two sources. The file /tmp/Fcitx5.log contains all the log output that Console.app captures, plus those written to stderr by engines, for example rime. And in Console.app you check Include Info Messages and Include Debug Messages in the Action menu, and put FcitxLog in the Search field.

For the debugger, you attach to the running process from another machine over SSH:

sh
$ /usr/bin/lldb
(lldb) process attach --name Fcitx5

The core dump section is the most specific, and it is written for the case where the input method has already crashed:

sh
sudo chmod 1777 /cores
sudo sysctl kern.coredump=1
ulimit -c unlimited  # only works for current shell
pkill Fcitx5; /Library/Input\ Methods/Fcitx5.app/Contents/MacOS/Fcitx5

There is a warning that matters in practice. When Fcitx5 crashes, it creates a roughly 10GB core file under /cores, and the ulimit note says it only works for the current shell. A 10GB file per crash on a developer laptop is the kind of detail that gets discovered the hard way, and the fact that it is written down here saves a disk-space incident.

The crash file is then opened with lldb and a backtrace taken:

sh
/usr/bin/lldb -c /cores/core.XXXX
(lldb) bt

The final piece of the debugging story is the test suite. The unit tests run through ctest:

sh
ctest --test-dir build/$(uname -m) --output-on-failure

And the end-to-end tests are driven by Appium:

sh
npm i -g appium
appium driver install mac2
pip install -r appium/requirements.txt
pytest appium

with a note to use the Accessibility Inspector app in the Xcode bundle to check the identifier of UI elements. That is an admission that the tests are driven through the accessibility layer, which is how you test an input method at all.

Translation and the credits

The translation section has two halves because the project has two source languages in it, and each needs a different toolchain.

For the Swift sources, updating the .strings files for each supported locale runs a CMake target:

sh
cmake --build build/$(uname -m) --target GenerateStrings

That will, for example, update assets/zh-Hans/Localizable.strings, and then the translator can work on it. The flow is generate, then translate, and the target does the extraction.

For the C++ sources, the first step is to create the assets/po/base.pot file:

sh
cmake --build build/$(uname -m) --target pot

Then adding a new language means running msginit in the po directory, using a PO file editor to translate the strings, and finally merging the new strings back into the PO files with msgmerge:

sh
cd po && msginit -l <locale>
sh
cd po && msgmerge -U <locale>.po base.pot

The two paths exist because Swift uses the Apple .strings format and gettext, and the C++ core of Fcitx5 already uses gettext. The repository holds a po/ directory and the gettext dependency in the Homebrew list, which fits.

The credits section is where the licence situation becomes visible, and it is a good illustration of why a port's licence is not just the port's licence. The project is GPL-3.0, and it incorporates fcitx5 and fcitx5-android under LGPL-2.1-or-later, swift-cmake-examples under Apache-2.0, AlertToast under MIT, the Linux input event codes header under GPL-2.0-only with the Linux syscall note, and webview under MIT.

That list is the LGPL and GPL interaction in practice. Fcitx5 itself is LGPL, the Linux header is GPL-2.0-only, and the port is GPL-3.0, so the combined distribution is GPL-3.0. Anyone who wants to reuse the Fcitx5 core on its own keeps the LGPL terms, and anyone shipping the macOS port is on GPL-3.0.

The repository also carries a README.zh-CN.md alongside the English one, and the project description links a Telegram channel and a QQ group number, which is how the project communicates with its users.

Editorial conclusion

fcitx5-macos suits a macOS user who wants the Rime or Mozc engines and the Fcitx5 configuration workflow rather than the built-in macOS input methods, and a developer who wants to work on a cross-platform input method framework in one tree rather than two separate codebases. It is the wrong tool if you only need a Chinese or Japanese input method, since macOS ships one, and it is the wrong tool if you cannot meet the build requirements, because the current toolchain needs Xcode 26.4 for the Swift 6.3 compiler and macOS 26.2 for building. Before you start, read the installer documentation at fcitx-contrib.github.io/docs, because the recommended path is the separate installer project rather than building the tree yourself.

Frequently asked questions

What is fcitx5-macos?

It is the Fcitx5 input method framework ported to macOS 13.3 or later, written in Swift and C++ and licensed under GPL-3.0. The repository also ships a Chinese README and links a Telegram channel and a QQ group for users.

Does fcitx5-macos include input method engines?

No. Fcitx5 only packages keyboard engine. To install other engines or tables you use the built-in Plugin Manager, and the engines such as rime and mozc come from separate plugin packages.

How do I install fcitx5-macos?

The recommended route is to download the installer from the separate fcitx5-macos-installer repository and read the documentation at fcitx-contrib.github.io/docs. Building from source is supported on macOS 26.2 and later and requires Xcode 26.4 or later for the Swift 6.3 compiler, though the project is not an Xcode project and uses CMake.

What are the build requirements for fcitx5-macos?

Native and cross build on macOS 26.2 or later is supported, with Xcode 26.4 or later needed for the Swift 6.3 compiler. The dependency step installs cmake, ninja, extra-cmake-modules, gettext, librsvg and qpdf through Homebrew, runs scripts/install-deps.sh and installs pnpm for the webview component.

Why does fcitx5-macos need to be code signed?

Some features, such as notifications and core dump, require the app bundle to be code-signed after installation, which the code-sign.sh script handles. The debug section also notes that a crash produces a core file of roughly 10GB under /cores.

How do you translate fcitx5-macos into another language?

For the Swift sources, run the GenerateStrings CMake target to update the .strings files for each locale, then edit them. For the C++ sources, run the pot target to create assets/po/base.pot, use msginit to add a locale and msgmerge to merge the new strings into the PO files.

Official sources

  1. fcitx/fcitx5-macos on GitHub
  2. Issues
  3. License: GPL-3.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/fcitx-fcitx5-macos.svg)](https://hysenlabs.com/projects/fcitx-fcitx5-macos)

Was this useful?