A native macOS client for GeForce NOW — built for Mac, built for controllers.
⬇ Download the latest release · What's new · Build from source
MacForce Now is written in SwiftUI from the ground up and driven by the same WebRTC and NVST streaming protocols the official desktop app uses — not a web view in a wrapper. The pitch is simple: treat a Mac like a Mac, and treat a controller like a controller. Browse your library and launch in seconds, stream at up to 5K, record the runs you want to keep, and play with a Steam Controller 2026 without ever installing Steam.
GeForce NOW works on a Mac, but the official client leaves a lot on the table — a mouse-and-keyboard web view, pillarbox bars baked into every ultrawide stream, and no love for the controllers people actually game with. MacForce Now fills those gaps with a real Mac app, and then keeps going.
| 🎮 Steam Controller 2026 support | Wired, Bluetooth LE, and both 2.4 GHz dongles. Full HID parsing, haptics, back grips, trackpads, custom mappings — no Steam required. |
| 🖥️ Built for ultrawide | 21:9 up to 5120×2160 and 32:9 up to 5120×1440, HEVC and AV1, MetalFX upscaling, and six ways to kill the black bars. More ↓ |
| ⚡ Native NVST transport | Stream over NVIDIA's own Geronimo/Bifrost engine — the same runtime the official client uses — instead of WebRTC. More ↓ |
| ⏺️ Record your sessions | One keystroke (⌘R) captures gameplay locally, with a browsable library and opt-in trim/crop/export editor. |
| 📚 Your whole catalog | Hero rotation, game rails, search and filters, store ownership picker, persistent Library and Favorites — plus a live banner that drops you straight back into an active session. |
| 🌐 Remote Co-Op | Invite a friend from a browser link and hand them a player slot in your session — signed invites, host-approved, native input path. |
| ⌨️ On-screen keyboard in-stream | Steam + X summons a Steam Deck-style keyboard right over the game — dual trackpads aim, L2/R2 or a pad click types. Tap the ⬍ key to flip it to the top of the screen when it overlaps something important. Works on any controller. |
| 💬 Discord Rich Presence | Your friends see what you're playing, automatically. |
| 🕹️ Full controller navigation | Drive the entire app — catalog, details, settings — from the pad. Never reach for the mouse. |
| 📊 Real diagnostics | Live stream HUD, session timers, network stats, and exportable logs when something goes wrong. |
- Download
MacForceNow.dmgfrom the Releases page. - Open it and drag MacForce Now to Applications.
- Launch from Spotlight. If macOS blocks it, right-click the app → Open.
Requires macOS 15.6 or later and your own GeForce NOW account.
Runs alongside upstream OpenNOW. MacForce Now uses its own bundle ID, URL scheme, keychain services, and preferences — install both, no conflicts, no overwritten logins.
Pick your shape, then your resolution — 16:9, 16:10, 21:9, or 32:9. The wide end tops out at 5120×2160 on 21:9 and 5120×1440 on 32:9, all at 30/60/120/240 fps. HEVC carries true 5K streams where H.264 hardware decode runs out of headroom, and AV1 leans in whenever bandwidth is the bottleneck, decoded in hardware on M3-and-later Apple silicon. 10-bit 4:2:0/4:4:4 colour is there when the codec supports it, and any codec your Mac can't decode greys itself out instead of failing mid-session.
GeForce NOW bakes pillarbox columns into 16:9-only titles — real black pixels, not window padding, so a wide monitor is stuck with them. MacForce Now detects those bars in the incoming frames and lets you decide what fills them:
| Mode | What you get |
|---|---|
| Black | Leave the encoded bars alone. Zero cost, default. |
| Colour | Flat fill in any colour you pick. |
| Blur Mirror | Mirrors the picture edge outward, blurred. Seamless, no distortion. |
| Blur Zoom | Blown-up blurred copy of the frame behind the sharp image. |
| Stretch | Fills the full width, pushing distortion to the edges so the centre stays true. |
| Crop | Scales to fill and trims top and bottom. No bars, no warping — costs vertical view. |
Blur modes take an adjustable dim. Everything but Black runs through the custom Metal render path.
WebRTC is the default, but it isn't the only way in. MacForce Now also speaks NVST — NVIDIA's native streaming protocol — by loading the same Geronimo/Bifrost runtime the official GeForce NOW app ships, and driving it through the exact session lifecycle the native client uses.
- Vendor runtime, not a reimplementation —
libGeronimo,libBifrost2,libGsAudioWebRTC, andSDL2are embedded in the app bundle, hash- and UUID-pinned by a runtime manifest, and validated byte-for-byte in CI. - Full native lifecycle — prepare, start, resume, pause, and stop all go through Geronimo's
GridApp, with Swift state driven by native callbacks — never inferred from a successful start call. - Native video and input — decoded frames (H.264, HEVC, and AV1) present into an embedded SDL/Metal surface, and keyboard, mouse, text, and gamepad input use the verified
NvstInputEvent_tABI directly. - Live native telemetry — latency, jitter, bitrate, packet and frame loss in the in-stream stats HUD, plus a network governor that adapts bitrate to path conditions.
Enable it in Settings → Stream Transport → Native/NVST Transport. Off keeps the default WebRTC session path. Session recording is not yet available on the NVST path — use WebRTC if you want ⌘R captures.
The ABI notes and integration plan behind this work live in docs/NVST/, and the two-transport architecture is documented in docs/StreamTransportArchitecture.md.
MacForce Now talks to Valve's controllers directly over HID, so you get the pad in your GeForce NOW stream without Steam running in the background.
- Every 2026 variant — wired, BLE, and both dongles — plus the original 2015 controller.
- Haptics, grips, trackpads — rumble feedback, four back grips, and both pads parsed and bindable client-side.
- Visual mapping editor — click any control on the controller diagram and bind it to a gamepad button, a key, a mouse action, or nothing at all.
- Combos on any control — bind a back grip to
B + R2; the modifier lands first, the press follows a beat later, so games read it as a real combo. - Profiles — save as many as you like and switch between them.
- Built-in tester — Settings → Steam Controller Test shows every button, axis, and pad live.
- Lizard mode off — the firmware's keyboard/mouse emulation is suppressed so nothing leaks to the desktop.
A Steam Deck-style overlay for logins, chat, and search fields in any GeForce NOW title. The keyboard works on both the WebRTC and native NVST streaming paths and sends keys exactly the way a physical keyboard does — UTF-8 text for characters, macOS keycodes for Return/Backspace.
- Dual trackpads each own one half of the grid. Touch a pad to aim, click it (or pull L2/R2) to type the aimed key.
- No trackpads? D-pad or left stick moves the grid cursor; A types, B is Backspace, X is Space, Y toggles Shift, Start presses Enter.
- Overlapping game UI? Tap the ⬍ position key in the bottom bar to flip the keyboard to the top of the screen.
- Steam alone still works as the local-cursor modifier — hold Steam to drive the Mac cursor with the right pad, same as before.
Steam grabs the controller exclusively while it's running. Quit Steam first.
Supported hardware and report formats
| Product ID | Device |
|---|---|
0x1102 |
Steam Controller (2015), wired |
0x1142 |
Steam Controller (2015) wireless dongle |
0x1302 |
Steam Controller (2026, "Triton"), wired |
0x1303 |
Steam Controller (2026), Bluetooth LE |
0x1304 |
Steam Controller (2026) 2.4 GHz dongle ("Proteus") |
0x1305 |
Steam Controller (2026) dongle variant ("Nereid") |
Pipeline
OPN/Stream/SteamControllerHIDMonitor.swiftmatches devices by vendor ID0x28deand the product IDs above, opens them via IOKit HID, disables lizard mode with periodic heartbeats, and streams raw input reports.OPN/Stream/SteamControllerReport.swiftparses each report into aSteamControllerInputSnapshot(buttons, triggers, sticks, trackpads).- Snapshots feed the in-app test screen and, during streaming,
NativeWebRTCGamepadMonitor, which forwards a standard gamepad subset to the GeForce NOW session. Steam/QAM, back grips, and trackpads are parsed and bindable client-side but not forwarded as raw stream input.
Report layouts — bit/byte mappings verified against Valve's contributions to SDL's HIDAPI drivers:
- Legacy (2015) —
ValveInReport_t-framed packets; buttons across three bytes, trackpads double as stick/D-pad emulation. Reference:SDL_hidapi_steam.c. - Triton (2026) — report IDs
0x42(wired/dongle state),0x45(BLE state), and0x47(timestamped state; inserts a 16-bit trackpad timestamp before the pad fields, shifting them by 2 bytes). A 32-bit button mask includes the Steam button (0x0001_0000), Quick Access (0x0000_0010), four back grips, trackpad touch/click bits, and per-pad X/Y plus pressure. Reference:SDL_hidapi_steam_triton.c. - Deck state — report ID
0x09, the Steam Deck-style 64-bit button mask with pads at fixed offsets; used when a device speaks the deck packet format. Reference:SDL_hidapi_steamdeck.c.
Struct layouts for all three formats are documented in SDL's controller_structs.h. Axis values normalize to -1...1 (Int16 full scale), triggers and pad pressure to 0...1. Parsing is covered by Tests/Stream/SteamControllerReportTests.swift.
xcodebuild build -project MacForceNow.xcodeproj -scheme MacForceNow -configuration Debug -destination platform=macOS CODE_SIGNING_ALLOWED=NORun the package tests from the repository root so SwiftPM uses one shared .build graph:
swift test --scratch-path .build/sharedProject layout, packages, and tooling
Layout
Model— persisted SwiftData models, DTOs, stream value types, Twitch realtime models, and catalog value objectsMacForceNowApp.swift— macOS app entry point and application delegateResources— bundled images, fonts, and store icon assetsView— SwiftUI/AppKit views, stream host views, design primitives, and asset catalogsViewModel— observable UI state for login, catalog, controller catalog, and recordingsOPN— authentication, catalog/session services, native WebRTC, telemetry, Twitch, preferences, logging, and app infrastructureGFN— protocol-specific GeForce NOW clients and wire types (CloudMatch, GDN, Jarvis, LCARS, NesAuth, NetworkTest, NVST, Starfleet, UDS)RemoteCoOp— browser Remote Co-Op reference stack (signaling broker, guest page, TURN launcher, control panel)Tests— root SwiftPM test target covering the package-exposed production logic
Packages
The root Package.swift exposes a testable MacForceNow library target over non-app-entry production logic from Model, OPN, and GFN. The Xcode app target compiles all five production directories, including View and ViewModel.
Focused test runs
swift test --scratch-path .build/shared --filter WebRTCStreamRecording
swift test --scratch-path .build/shared --filter MacForceNowGameServicesTestsAvoid package-local build directories during normal development. Use the root package and shared scratch path so generated SwiftPM state stays in one place and large binary artifacts such as sentry-cocoa are not duplicated.
scripts/report-spm-build-size.sh # audit generated SwiftPM disk usage
scripts/clean-spm-builds.sh # reclaim disk spacePull requests welcome. Use conventional commit prefixes (fix:, feat:, docs:, test:, refactor:, style:, chore:), keep changes focused, and verify the relevant package tests or app build before submitting.
MacForce Now is a fork of OpenNOW-Mac, extended with Steam Controller 2026 support and renamed so it can live alongside upstream on the same Mac. Licensed under MIT.
Independent community project. Not affiliated with, endorsed by, or sponsored by NVIDIA. NVIDIA and GeForce NOW are trademarks of NVIDIA Corporation. Use your own GeForce NOW account and comply with the GeForce NOW Terms of Use.



