spinach-keyboard-framework

TypeScriptInfrastructureConfiguration ManagementCross-Platform
Image 1

Spinach Keyboard Framework - Cross-Platform Configuration as Code & System Integration

Situation

Managing keyboard configurations and system integration across multiple operating systems (macOS, Linux, and Windows) presented significant challenges. Each platform has fundamentally different input systems, window managers, and keyboard remapping tools, making it difficult to maintain a consistent user experience. Traditional approaches required manual configuration of platform-specific tools, leading to configuration drift, "works on my machine" issues, and time-consuming setup when moving between systems or setting up new machines.

The complexity was compounded by the need to support both firmware-level remapping (VIA) and OS-level recognition, handle edge cases like modifier key conflicts, integrate with different window managers (Yabai on macOS, Sway on Linux), and maintain consistency while respecting platform differences. Without a systematic approach, configurations would diverge across systems, making it impossible to replicate the same keyboard and window management experience reliably.

Task

The goal was to engineer a cross-platform configuration-as-code framework that would provide consistent system integration and keybinding automation across macOS, Linux, and Windows. The solution needed to:

  • Create a replicable infrastructure that could be version-controlled and deployed consistently across all three operating systems
  • Implement multi-layer system integration (firmware-level VIA + OS-level tools + window manager integration)
  • Define a consistent Hyper key concept (Ctrl+Alt+Super) that works across all platforms
  • Build a type-safe configuration generator using TypeScript to eliminate manual JSON editing errors
  • Support intelligent application toggle functionality across different window managers and application types
  • Enable infrastructure replicability through Git version control

Success criteria included: identical keyboard behavior across all platforms, zero manual configuration steps for new system setup, compile-time validation of configuration rules, and the ability to rebuild the entire configuration from source code.

Action

Multi-Layer Infrastructure Architecture

Implemented a layered infrastructure approach with firmware-level remapping (VIA) as the foundation and OS-level recognition as fallback/complement. The Hyper key was defined as a consistent modifier (Ctrl+Alt+Super) across all platforms, providing a conflict-free modifier for system-wide shortcuts.

Firmware-Level Foundation: Configured VIA firmware remapping to send Ctrl+Alt+Super directly, establishing the Hyper key at the lowest level. This ensures the key combination is recognized consistently regardless of OS-level configuration.

OS-Level Integration Layers: Created platform-specific integration layers maintaining conceptual consistency:

  • macOS: Karabiner-Elements configuration recognizing both CapsLock keycode and Ctrl+Alt+Cmd combination, handling dual recognition for firmware-remapped and standard CapsLock scenarios
  • Linux: keyd configuration using "overload" functionality where CapsLock acts as Hyper when held, Escape when tapped
  • Windows: AutoHotKey scripts with separate handling for firmware-remapped vs standard CapsLock

Window Manager Integration: Built abstraction layers via shell scripts for consistent window management operations:

  • yabai_functions.sh for macOS providing workspace navigation, window focus, move, resize, and send-to-workspace operations
  • Application toggle scripts for Linux using Sway IPC for similar functionality
  • Consistent keybinding patterns: Hyper + Q/W for workspace navigation, Hyper + Shift + Q/W for sending windows

TypeScript-Based Configuration Generator

Created a TypeScript-based configuration generator implementing configuration-as-code principles. The system includes:

  • Type Safety: Defined TypeScript types matching Karabiner JSON structure for compile-time validation, preventing runtime errors
  • Modular Architecture: Created rules.ts (969+ lines), utils.ts, and types.ts with utility functions for common patterns enabling code reuse
  • Automated Build Process: Implemented yarn run build command that generates karabiner.json from TypeScript source, eliminating manual JSON editing
  • Complex Rule Support: Handles sublayers, conditions, and command execution through type-safe definitions

Intelligent Application Toggle System

Implemented multi-method window detection system supporting:

  • Detection Methods: app_id, window class, case-insensitive matching
  • Application Launch Logic: Automatic detection of Flatpak apps and NixOS binaries
  • Toggle Behavior:
    • Focused + single instance → hide to scratchpad (preserves geometry)
    • Focused + multiple instances → cycle to next
    • Exists but not focused → focus
  • Application Type Handling: Different launch commands for native apps, Flatpak, and NixOS binaries

Cross-Platform Modifier Key Unification

Solved the challenge of unifying copy/paste modifier keys across platforms while maintaining physical key position consistency:

  • Swapped L_CTL to L_CMD in VIA firmware (affects all platforms)
  • On Linux/Windows: keep as-is (LWin / LAlt / LCtrl)
  • On macOS: switch back at OS level (LCtrl / LAlt / LWin) using Karabiner
  • Result: Same physical key position (rightmost modifier) for copy/paste across all platforms

Version Control and Replicability

All configurations are version-controlled in a Git repository with 53 commits showing framework evolution. The repository structure enables:

  • Complete system replication by cloning the repository
  • Consistent keyboard and window management experience across all systems
  • History tracking of configuration changes
  • Branch-based experimentation without affecting production configurations

Technical Implementation Details

Configuration Scale: 10+ source files (TypeScript, shell, Python, AutoHotKey), 969+ lines in main rules.ts, 596+ lines in yabai_functions.sh, 50+ keybinding definitions

Observability:

  • Yabai functions include optional logging (LOGGING_ENABLED flag)
  • Karabiner-Elements logs keybinding events (debug mode)
  • keyd logs configuration errors
  • AutoHotKey scripts can include debug output
  • TypeScript compilation validates configuration at build time

Result

Configuration as Code Achievement

The TypeScript-based configuration generator with type-safe definitions (969+ lines in rules.ts) and automated build process has eliminated manual JSON editing and reduced errors. The system provides compile-time validation preventing runtime configuration issues, and the modular architecture enables code reuse through utility functions.

Cross-Platform System Integration

Successfully supported 3 operating systems (macOS, Linux, Windows) with consistent infrastructure. The Hyper key concept provides a conflict-free modifier for system-wide shortcuts across all platforms, enabling identical keyboard behavior regardless of the operating system.

Multi-Layer Infrastructure Success

The firmware-level (VIA) + OS-level (Karabiner/keyd/AutoHotKey) + window manager (Yabai/Sway) integration enables a consistent experience regardless of platform or hardware. The layered approach ensures reliability: if one layer fails, others provide fallback functionality.

Intelligent Application Management

The multi-method window detection system (app_id, window class, case-insensitive matching) with automatic detection of Flatpak apps and NixOS binaries enables seamless application management. Window geometry is preserved for tiled windows, and the system handles different application types appropriately.

Infrastructure Replicability

All configurations are version-controlled in a Git repository (53 commits showing framework evolution), enabling replication across systems with consistent keyboard and window management experience. New system setup requires only cloning the repository and running the build process—zero manual configuration steps.

Technical Stack

TypeScript, Node.js, VIA firmware, Karabiner-Elements, keyd, AutoHotKey, Yabai, Sway/SwayFX, skhd, Git

Conclusion

The Spinach Keyboard Framework demonstrates replicable & resilient systems engineering through configuration-as-code principles. By treating keyboard and window management configurations as version-controlled software, the project eliminates "works on my machine" issues and enables instant system replication. The holistic "full-stack" infrastructure view is evident in the multi-layer integration spanning firmware, OS-level tools, and window managers, while the security-first approach ensures consistent, conflict-free keybindings across all platforms. This infrastructure investment—doing it right the first time—eliminates technical debt and accelerates future growth, showcasing how systematic infrastructure engineering can transform a complex, multi-platform challenge into a replicable, maintainable system.