Skip to content

feat(tvos): run on Apple TV through @solidtv/nativescript - #7

Merged
chiefcll merged 1 commit into
mainfrom
apple-tv
Sep 18, 2026
Merged

chiefcll merged 1 commit into
mainfrom
apple-tv

Conversation

@chiefcll

Copy link
Copy Markdown
Contributor

What

The demo on Apple TV, without a browser, from the same src/ as the web build. NativeScript is the runtime, its canvas plugin the WebGL surface, and @solidtv/nativescript the host between them and SolidTV. This is phase 4 of that repository's integration plan.

  • nativescript/, its own pnpm root, holds only the host: app/app.ts (the boot file), webpack.config.js (bundles ../src as it is, with the hex-colour transform and the theme alias from vite.config.js, and copies public/fonts and public/assets into the bundle), nativescript.config.ts, App_Resources, the simulator scripts, and a stand-in for a canvas plugin package that has no tvOS build. shaka-player and the Firebolt SDK are aliased to an empty module, since their pages are out of scope there but their chunks must bundle.
  • The boot file imports the web entry, src/index.tsx, unchanged. The HashRouter, the focus manager on document, fetch, the relative asset URLs, import.meta.env.BASE_URL and loadFonts all work through the host's shims and platform.
  • src/ gains one rule, in LeftNavWrapper: Back from the open nav drawer on the start page is left unhandled. A platform that hands the system what the app leaves unhandled, Apple TV's Menu button, leaves the app there and nowhere else. A browser never notices: walking history back from the start page did nothing before. Checked in Chrome: Back opens the nav, Back again walks history back, and at the start page's nav it does nothing.
  • README: an Apple TV section with the prerequisites, the commands and what is out of scope. .gitignore: the tvOS project's workspace file and lockfile are tracked.

The root package.json and lockfile are untouched.

Depends on

Three pull requests, to be released before this merges; nativescript/package.json links the sibling checkouts until then, and the pins are the last commit here:

  • solid-tv/renderer#202: a default platform, a settings hook, the platform's target lookup, font URL resolution.
  • solid-tv/solid#64: Config.preventDefaultOnHandledKeys, and a second useFocusManager argument that cannot listen is ignored again. App.tsx passes the removed hold options there, which 1.6.3 takes for the event target and throws on.
  • solid-tv/nativescript#2: the shims, the platform, the bridge target, the console mirror, the webpack helper's options.

Results

On the Apple TV 4K simulator: Browse with TMDB data and posters, an entity page from its lazy chunk, KeepAlive back to Browse, the examples portal, the remote through the harness's XCUITest driver, Menu leaving from the start page only, and a suspend and resume with the render loop stopped within half a second.

On an Apple TV HD (A8, 1080p), cold, from the first line of the bundle: entry evaluated at 0.6 s, first frame at 1.3 s, first idle with 21 posters in at 2.4 s, 60 fps within a second of the first frame, 46 MB of textures against the 200 MB critical threshold. nativescript/results/ has the logs and two screenshots; the full record is phase4-results.md. The exit test by hand on the device is the remaining step.

Out of scope on tvOS: the player, Firebolt, the renderer versions page, texture compression (ETC2 assets, PVRTC GPU), the mouse states, and the Destroy example's SVG.

Note

Unrelated to this change, and not touched here: against SolidTV 1.6 or later the production web build fails, because src/pages/Tags.tsx imports createTag, which SolidTV removed with the renderer 1.9 upgrade. The pins at main (1.5.2) still build. It will surface when the root package.json moves to a current SolidTV.

🤖 Generated with Claude Code

The app runs on tvOS without a browser: NativeScript is the runtime, its
canvas plugin the WebGL surface, and @solidtv/nativescript the host
between them and SolidTV. `nativescript/` is that project, its own pnpm
root, and holds only the host: the boot file, the webpack config that
bundles `../src` as it is, the App_Resources, the simulator scripts and a
stand-in for a plugin package with no tvOS build. It imports the web
entry, `src/index.tsx`, unchanged: the HashRouter, the focus manager on
`document`, `fetch`, the relative asset URLs, `import.meta.env.BASE_URL`
and `loadFonts` all work through the host's shims and platform.

`src/` gains one rule. Back from the open nav drawer on the start page is
left unhandled, so a platform that hands the system what the app leaves
unhandled, Apple TV's Menu button, leaves the app there and nowhere else.
A browser never notices: walking history back from the start page did
nothing before.

The three SolidTV packages are linked from sibling checkouts in
`nativescript/package.json` until their next releases; the pins follow.
The root package.json is untouched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant