I Built a macOS App Without Knowing Swift

I Built a macOS App Without Knowing Swift

Getting a MacBook, and the Korean Input Key

The first wall I hit when I started using a MacBook was switching between Korean and English input. On Windows, a single right Alt key had always handled it automatically. On macOS, you're suddenly dealing with Caps Lock or Fn + Globe — unfamiliar combinations that never feel natural.

Search around and everyone recommends Karabiner-Elements. It's a great tool, but loading a kernel extension and writing a JSON config file just to remap one key felt like overkill. What I needed was "a lightweight app that maps just the Right Command key to the Korean/English toggle."

That app didn't exist. So I built it.

Swift? Not a Single Line

The problem was I knew absolutely nothing about Swift. No experience with native macOS app development either. I had no idea what hidutil was, what a CGEvent tap was, or what a LaunchAgent was.

In the past, I'd have stopped right there. I'd have spiraled into "do I need to learn Swift first?" or "maybe I should just use Karabiner" until I'd procrastinated my way into never making it at all.

But this is the era of vibe coding. The LLM guides me through the APIs I don't know, and I just need to hold onto the direction — "this is how it needs to behave." Even without knowing Swift syntax, even approaching macOS's key mapping system for the first time, all you need is the core idea and the app emerges.

What I Learned While Building It

That's how Hangul Key Changer was born. It uses hidutil for key remapping and automatically adjusts system shortcut settings — a simple utility. The features are minimal:

  • Set any key as your Korean/English toggle
  • One click to Enable — key mapping + system settings applied automatically
  • LaunchAgent keeps it running after reboots
  • Quick control from the menu bar

From the initial commit to v2.3.0, it was refined through 28 commits. What started as Right Command-only expanded to support any key you want, then picked up dark mode support, Homebrew Cask distribution, and notarization.

What I found interesting through this process was that I didn't really "learn" Swift — it was closer to "having used" it. I never studied the syntax systematically. I found the APIs I needed as I went, implemented things through conversation with an LLM, confirmed the behavior, and moved to the next feature. I still couldn't explain Swift's protocols or generics today. But I can build an app that intercepts key events on macOS.

If It's Convenient for Me, It's Convenient for Others

At first, the app was purely for myself. But once I'd built it, my thinking shifted. I'm not the only person who's found the Korean input key frustrating after switching to macOS. Anyone who moved from Windows to Mac as a Korean speaker has probably felt the same pain.

So I put it on GitHub and made it installable via Homebrew Cask.

brew install --cask hulryung/tap/hangulkeychanger

One line and you're done. That's the moment when "something I built for myself" becomes "something that's also convenient for people with the same problem."

That Feeling from College

Something strange is coming back lately. A hunger for building things I used to feel in college.

Back then, I wanted to build everything. Even if the technical execution was rough, even if the result was unpolished — the fact that it ran was just exciting. The raw, primal joy of the act of programming itself. A feeling I'd somehow lost somewhere along the way of working professionally.

Vibe coding is bringing it back. The feeling that if an idea comes to mind, I can try building it right now. The confidence that it's okay not to know the language. The experience of "this sounds fun to build" not getting killed by "how long would this even take?"

Hangul Key Changer is the first thing that came out of that feeling. I started without knowing Swift, and now it's an app you can install from Homebrew. I have no idea what I'll build next. But I know I want to build a lot of things right now.

And that feels good.