{"id":1019,"date":"2026-05-09T00:46:47","date_gmt":"2026-05-08T15:46:47","guid":{"rendered":"https:\/\/blogs.igalia.com\/gyuyoung\/?p=1019"},"modified":"2026-05-09T00:46:47","modified_gmt":"2026-05-08T15:46:47","slug":"introduce-blink-for-apple-tvos","status":"publish","type":"post","link":"https:\/\/blogs.igalia.com\/gyuyoung\/2026\/05\/09\/introduce-blink-for-apple-tvos\/","title":{"rendered":"Introduce Blink for Apple tvOS"},"content":{"rendered":"\n<p>At BlinkOn 20 in 2025, I gave a short lightning talk about an experimental project called <em><a href=\"https:\/\/youtu.be\/MpOxNPeWf6I?t=75\">Blink for Apple tvOS<\/a><\/em>. Although the presentation took place about a year ago, I wanted to take some time to provide more context on why we started this work, what challenges we encountered along the way, and where the project stands today in this blog again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Motivation<\/h2>\n\n\n\n<p>Apple TV runs tvOS, which is based on iOS, but it differs in some important ways. One of the most notable differences is that tvOS does not provide a WebKit WebView for third-party applications. This limitation has significant implications, as applications that need web functionality must embed their own web engine.<\/p>\n\n\n\n<p>A well-known example is the YouTube app on Apple TV, which uses a custom web engine called <em>Cobalt<\/em>. This engine is based on an outdated Chromium fork, and maintaining such a fork becomes increasingly difficult over time, especially as the web platform continues to evolve.<\/p>\n\n\n\n<p>At the same time, the Chromium community has been exploring Blink-based implementations on Apple platforms, including the experimental Blink for iOS project. As that work progressed, it naturally led to a new question: whether Blink could also be brought to tvOS. Beyond that, we also started wondering if it would be possible to eventually upstream Blink support for tvOS. These questions became the starting point of this project.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Challenges<\/h2>\n\n\n\n<p>Although tvOS is derived from iOS, porting Blink to this platform turned out to be far from straightforward. One of the biggest challenges comes from the lack of support for the multi-process architecture that Chromium relies on. Several low-level system APIs, such as <code>fork()<\/code>, <code>mach_msg()<\/code>, and <code>posix_spawn_*()<\/code>, are not available on tvOS, which makes it impossible to adopt the standard process model.<\/p>\n\n\n\n<p>Another major limitation is the absence of BrowserEngineKit, which the Blink port on iOS uses for process management and integration. Without this framework, alternative approaches are required to make the system work on tvOS.<\/p>\n\n\n\n<p>In addition, tvOS does not allow JIT compilation due to platform restrictions, which directly affects the execution model of V8. This requires running JavaScript in a more restricted mode compared to other platforms.<\/p>\n\n\n\n<p>The input model also differs significantly. Apple TV primarily relies on a remote control, which leads to a focus-based navigation model rather than pointer-based interaction. This affects how web content needs to be handled and navigated.<\/p>\n\n\n\n<p>Given all these constraints, it became clear that the goal of this project should not be to build a fully-featured browser. Instead, we focused on enabling Blink-based web capabilities on tvOS in a way that is both practical and maintainable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Current progress<\/h2>\n\n\n\n<p>To get Blink running on tvOS, we made a number of changes across both the build system and the runtime. On the build side, we introduced tvOS-specific configurations, including a new toolchain, the <code>IS_IOS_TVOS<\/code> build flag in C++ and Objective-C code, and a <code>target_platform = \"tvos\"<\/code> setting in GN.<\/p>\n\n\n\n<p>On the runtime side, the lack of multi-process support required us to enable a single-process mode. We also removed or disabled code paths that depend on BrowserEngineKit and ensured that unsupported low-level system APIs are not used in the tvOS build.<\/p>\n\n\n\n<p>Several modifications were also necessary in core components. For example, JIT was disabled in V8, and build configurations were adjusted for third-party libraries such as ANGLE, V8, and Dawn to make them compatible with tvOS.<\/p>\n\n\n\n<p>At the same time, we worked on integrating platform-specific features. This includes support for hardware-accelerated graphics, media codecs, and Crashpad, as well as improvements to input handling to better support remote-based interaction.<\/p>\n\n\n\n<p>As a result of these efforts, <code>content_shell<\/code> is now able to run in our internal repository, and work toward upstreaming is currently in progress.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Demo<\/h2>\n\n\n\n<p>To demonstrate the current state of the project, we prepared a simple demo showing Blink running on tvOS. In this demo, a YouTube video is played inside <code>content_shell<\/code> on the tvOS simulator, which illustrates that Blink is capable of rendering and running real-world web content in this environment.<br><\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/blogs.igalia.com\/gyuyoung\/files\/2026\/04\/content_shell_on_tvos_simulator.mp4\"><\/video><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Next steps<\/h2>\n\n\n\n<p>There is still a significant amount of work ahead. In the short term, our focus is on making <code>content_shell<\/code> build and run in upstream Chromium, setting up a reference bot for tvOS builds, and passing relevant unit tests, browser tests, and web platform tests.<\/p>\n\n\n\n<p>In other words, we are currently transitioning from a prototype that \u201cworks\u201d to something that is stable, maintainable, and ready for upstream integration.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Closing thoughts<\/h2>\n\n\n\n<p>One of the most interesting aspects of this project is how different tvOS is, despite being closely related to iOS. Even relatively small platform restrictions can have large architectural implications when working with a complex system like Blink.<\/p>\n\n\n\n<p>While tvOS is a constrained environment, that is precisely what makes it an interesting engineering challenge. We will continue exploring how far we can take this effort and whether Blink on tvOS can eventually become part of upstream Chromium.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Acknowledgements<\/h2>\n\n\n\n<p>This work would not have been possible without the support of many contributors, including Blink and Chromium reviewers, the Google YouTube team, and many collaborators in the community.<\/p>\n\n\n\n<p>Thank you all!<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"285\" height=\"110\" src=\"https:\/\/blogs.igalia.com\/gyuyoung\/files\/2026\/04\/youtube-logo-1.jpg\" alt=\"\" class=\"wp-image-1053\" style=\"width:236px;height:auto\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"234\" height=\"87\" src=\"https:\/\/blogs.igalia.com\/gyuyoung\/files\/2026\/04\/igalia-logo-2.jpg\" alt=\"\" class=\"wp-image-1054\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Igalia Contributors<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Abhijeet Kandalkar<\/li>\n\n\n\n<li>Gyuyoung Kim<\/li>\n\n\n\n<li>Jeongeun Kim (Julie)<\/li>\n\n\n\n<li>Raphael Kubo da Costa<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>At BlinkOn 20 in 2025, I gave a short lightning talk about an experimental project called Blink for Apple tvOS. Although the presentation took place about a year ago, I wanted to take some time to provide more context on why we started this work, what challenges we encountered along the way, and where the [&hellip;]<\/p>\n","protected":false},"author":52,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[4,18,20],"class_list":["post-1019","post","type-post","status-publish","format-standard","hentry","category-igalia-chromium","tag-chromium","tag-ios","tag-tvos"],"_links":{"self":[{"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/posts\/1019","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/users\/52"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/comments?post=1019"}],"version-history":[{"count":18,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/posts\/1019\/revisions"}],"predecessor-version":[{"id":1066,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/posts\/1019\/revisions\/1066"}],"wp:attachment":[{"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/media?parent=1019"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/categories?post=1019"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.igalia.com\/gyuyoung\/wp-json\/wp\/v2\/tags?post=1019"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}