<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jani Hautakangas</title>
    <description>The latest articles on Forem by Jani Hautakangas (@janihau).</description>
    <link>https://forem.com/janihau</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3635802%2F30618e2e-6e8c-4fa9-9462-345be1385224.png</url>
      <title>Forem: Jani Hautakangas</title>
      <link>https://forem.com/janihau</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/janihau"/>
    <language>en</language>
    <item>
      <title>How to Build an Enterprise Browser</title>
      <dc:creator>Jani Hautakangas</dc:creator>
      <pubDate>Mon, 16 Feb 2026 18:01:28 +0000</pubDate>
      <link>https://forem.com/janihau/how-to-build-an-enterprise-browser-571f</link>
      <guid>https://forem.com/janihau/how-to-build-an-enterprise-browser-571f</guid>
      <description>&lt;p&gt;Originally posted on &lt;a href="https://medium.com/kodegood/how-to-build-an-enterprise-browser-1dd49a5b1d89" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;The concept of an enterprise browser was something I hadn’t paid much attention to until recently, when I found myself in discussions with teams building these systems.&lt;/p&gt;

&lt;p&gt;Having worked as a contractor for over ten years, I’ve frequently used managed browsers such as Chrome and Edge. Yet I rarely considered what actually goes into making them “enterprise-ready.” My work has primarily involved Chromium engine internals, including the content layer, Blink, and hardware integration, rather than the browser application layer itself.&lt;/p&gt;

&lt;p&gt;During those discussions, I realized how interesting enterprise browsers are, especially in safety-critical environments. I recalled multiple situations in my career where a hardened enterprise browser would have been far more practical than the complicated stacks of VPNs, VDI setups, and jump hosts required just to access secure development environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Enterprise Browser Blueprint
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cdwk2d6iu1t09nhowa5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cdwk2d6iu1t09nhowa5.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before tearing down the Chromium source code, we must define what “enterprise-grade” actually means. It boils down to five core pillars:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Centralized Policy Enforcement Engine:&lt;/strong&gt; A remotely managed control plane that defines, distributes, and enforces browser behavior across all managed instances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity- and Context-Aware Access Control:&lt;/strong&gt; An identity-integrated runtime that evaluates access decisions based on user identity, device posture, network context, and real-time risk signals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Loss Prevention (DLP):&lt;/strong&gt; A protection layer that monitors and restricts sensitive data flows within and between web applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insights and Reporting:&lt;/strong&gt; Centralized telemetry and proactive security event reporting for visibility and auditability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Trust Engine:&lt;/strong&gt; A continuous verification model enforcing least-privilege access by validating identity and session risk throughout the lifecycle of a session. “Never Trust, Always Verify.”&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Managed Standard Browsers vs. Commercial Solutions
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Managed Standard Browsers (Chrome &amp;amp; Edge)
&lt;/h4&gt;

&lt;p&gt;These are “enterprise-light” versions of everyday browsers. They are essentially consumer Chromium binaries with management hooks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Google Chrome Enterprise:&lt;/strong&gt; Managed via Chrome Browser Cloud Management (&lt;strong&gt;CBCM&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microsoft Edge for Business:&lt;/strong&gt; Deeply integrated with Microsoft Entra ID and Microsoft ecosystem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy &amp;amp; DLP Capabilities:&lt;/strong&gt; Both provide an extensive set of enterprise policies, built-in data loss prevention capabilities, Safe Browsing integration, identity-based access controls, and centralized reporting through their respective management platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise Connectors:&lt;/strong&gt; These are integration frameworks that allow the browser to send telemetry and content (such as file uploads or clipboard data) to third-party security providers for real-time analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Commercial Enterprise Browsers
&lt;/h4&gt;

&lt;p&gt;These are typically hardened Chromium derivatives or wrapper-based architectures designed specifically for security boundaries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Granular Policy Extensions:&lt;/strong&gt; Hyper-specific controls over browser internals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Data Loss Prevention:&lt;/strong&gt; These tools implement advanced content inspection to redact sensitive data in real-time and prevent unauthorized data movement between applications via the clipboard or file uploads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;“Last Mile” Visibility:&lt;/strong&gt; By enforcing policies within the browser runtime and renderer process, these solutions gain visibility into the DOM and user interactions that are invisible to network-level security tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full control over the browser runtime:&lt;/strong&gt; The ability to modify or instrument components of the rendering engine and JavaScript execution environment when necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailored per client:&lt;/strong&gt; The entire browser lifecycle and feature set can be customized to meet the specific compliance or operational needs of a single customer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Build a Custom Enterprise Browser?
&lt;/h2&gt;

&lt;p&gt;n my case, this project is driven by curiosity and the fact that no open-source project currently provides a full enterprise browser stack. However, for organizations in high-stakes industries such as Defense, Intelligence, or High-Frequency Trading, the reasoning goes far deeper than curiosity.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Sovereignty Gap
&lt;/h4&gt;

&lt;p&gt;While Chrome and Edge offer a vast number of security, reporting, and policy enforcement features, they are fundamentally designed to operate within the Google or Microsoft ecosystems. For organizations with extreme security requirements, this creates a “Sovereignty Gap” that only a custom-built solution can bridge.&lt;/p&gt;

&lt;p&gt;Building a custom browser allows us to achieve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;De-Google the Core:&lt;/strong&gt; Completely strip proprietary Google service dependencies that standard browsers require for background tasks, sync, and telemetry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Services are Not Allowed:&lt;/strong&gt; Ensure that no part of the browser attempts to communicate with Google-owned endpoints, eliminating “phone-home” traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;External Cloud is Forbidden:&lt;/strong&gt; Architect the management and reporting plane to exist entirely within a private, air-gapped, or sovereign cloud environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep Runtime Instrumentation:&lt;/strong&gt; Inject advanced controls deep into the renderer and JavaScript engine to monitor and block malicious behavior at the instruction level.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-client Hardened Runtime:&lt;/strong&gt; Tailor the specific security surface area such as disabling specific Web APIs or hardware acceleration based on the unique risk profile of a specific client or mission.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traceability &amp;amp; Determinism:&lt;/strong&gt; Achieve full source-level auditability and deterministic builds, ensuring that every binary can be verified and every runtime decision can be traced back to a specific line of code.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Building a Custom Enterprise Browser
&lt;/h2&gt;

&lt;p&gt;Almost every enterprise browser is Chromium-based. There is a good reason for that: it provides many necessary building blocks out of the box. Even when full implementations are not available, the necessary interfaces usually are. Therefore, it is significantly more practical to build on top of Chromium than to start from scratch, especially considering that for many users, the word “browser” effectively means Chrome.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmin4u4otg6mr4bj6spt7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmin4u4otg6mr4bj6spt7.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make it a true enterprise tool, several components must be implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cloud Management&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Device Management and Reporting Servers&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secure Browsing Services&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zero Trust Engine&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From a Chromium integration perspective, the following require extension or replacement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Service Integration:&lt;/strong&gt; Connecting the browser to the management plane.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy Handlers:&lt;/strong&gt; Implementing specialized handlers for proprietary security constraints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DLP Logic:&lt;/strong&gt; Enhanced data loss prevention mechanisms integrated into the runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;“Last-mile” Control:&lt;/strong&gt; Advanced controls injected deep into the Chromium engine.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Implementing the Foundation
&lt;/h2&gt;

&lt;p&gt;There are many approaches to implementing an enterprise browser, and there is no single correct path. It requires significant effort on both the cloud and browser sides. However, given the AI tooling available today, the barrier to entry is significantly lower than it was just a few years ago.&lt;/p&gt;

&lt;p&gt;My approach leverages Chromium’s modular architecture while maintaining a clean “downstream” build model:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Protocol Compatibility:&lt;/strong&gt; Use Chromium’s existing protobuf interfaces for management services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity:&lt;/strong&gt; Rely on a third-party IdP (Identity Provider), as identity management is its own domain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;De-Google:&lt;/strong&gt; Gradually remove Google service dependencies from Chromium components, replacing them with custom implementations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branding:&lt;/strong&gt; Apply custom branding to establish a unique identity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build System:&lt;/strong&gt; Instead of a messy fork, I use a &lt;strong&gt;sibling browser layer&lt;/strong&gt; model to manage downstream updates.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  The “eb” Build Tool
&lt;/h4&gt;

&lt;p&gt;I created the &lt;strong&gt;eb (Enterprise Browser) build tool&lt;/strong&gt;, heavily inspired by &lt;a href="https://brave.com/" rel="noopener noreferrer"&gt;Brave’s&lt;/a&gt; tooling. It pulls a specific Chromium tag and patches the source to include the &lt;code&gt;enterprise_browser&lt;/code&gt; layer as a sibling to the standard &lt;code&gt;/chrome&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffwb3mh0aqxym143h5o5u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffwb3mh0aqxym143h5o5u.png" alt=" " width="493" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Enterprise Browser Cloud Management (EBCM)
&lt;/h4&gt;

&lt;p&gt;This is where policy rules are defined and assigned to users via &lt;strong&gt;JIT (Just-In-Time) provisioning&lt;/strong&gt;. EBCM integrates with a third-party IdP to provide user authentication and maps policies to specific user roles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxo4mht6r3am7yjw64iij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxo4mht6r3am7yjw64iij.png" alt=" " width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Enterprise Browser Device Management Server (EBDM Server)
&lt;/h4&gt;

&lt;p&gt;The EBDM acts as the backend authority:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OIDC Authentication:&lt;/strong&gt; The browser presents a signed ID token issued by the IdP to prove identity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy Fetching:&lt;/strong&gt; The server sends a protobuf payload containing settings (e.g., “Disable Incognito”).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfffohexzjojrcyft7e1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfffohexzjojrcyft7e1.png" alt=" " width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Sign-in &amp;amp; Policy
&lt;/h4&gt;

&lt;p&gt;I adapted Chromium’s OIDC authentication interceptor to authenticate users directly against my EBCM via the IdP. Currently, the system supports global policy settings driven through Chromium’s device management protobuf definitions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm49jt1q4znxowbt5h082.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm49jt1q4znxowbt5h082.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fby82we5cwwut55jbdpym.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fby82we5cwwut55jbdpym.gif" alt=" " width="720" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project is available on GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/KodeGood/enterprise-browser-chromium" rel="noopener noreferrer"&gt;Enterprise Browser Chromium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/KodeGood/enterprise-browser-cloud" rel="noopener noreferrer"&gt;Enterprise Browser Cloud&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The project is currently in a very early prototyping stage.&lt;/p&gt;

&lt;p&gt;This lays the foundation. Deeper dives into enterprise browser architecture will follow.&lt;/p&gt;

</description>
      <category>browser</category>
      <category>enterprisebrowser</category>
      <category>zerotrust</category>
      <category>chromium</category>
    </item>
    <item>
      <title>Ladybird Browser in an Embedded Web Runtime</title>
      <dc:creator>Jani Hautakangas</dc:creator>
      <pubDate>Sat, 29 Nov 2025 10:44:57 +0000</pubDate>
      <link>https://forem.com/janihau/ladybird-browser-in-an-embedded-web-runtime-2pb7</link>
      <guid>https://forem.com/janihau/ladybird-browser-in-an-embedded-web-runtime-2pb7</guid>
      <description>&lt;p&gt;Originally posted on &lt;a href="https://medium.com/kodegood" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;In my previous &lt;a href="https://dev.to/janihau/build-embedded-debian-web-runtime-with-the-power-of-isar-150a"&gt;blog post&lt;/a&gt;, I showed how to build and create an experimental web runtime using &lt;strong&gt;Isar&lt;/strong&gt;, &lt;strong&gt;Debian Bookworm&lt;/strong&gt;, and &lt;strong&gt;WPEWebKit&lt;/strong&gt;. In that post, I also mentioned that I had a Ladybird version incubating. Now it’s time to reveal it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ladybird&lt;/strong&gt; is a completely new browser, built from scratch instead of relying on any existing browser codebases. It has its roots in &lt;strong&gt;SerenityOS&lt;/strong&gt;, but has since diverged into its own project. The project is still in its early phases, so I didn’t expect much to work. To my surprise, it’s already rendering pages quite well. Even &lt;strong&gt;WebGL&lt;/strong&gt; works!&lt;/p&gt;

&lt;h2&gt;
  
  
  Integrating Ladybird
&lt;/h2&gt;

&lt;p&gt;Ladybird depends on components that aren’t available in Debian Bookworm, such as the &lt;strong&gt;Skia&lt;/strong&gt; and &lt;strong&gt;ANGLE&lt;/strong&gt; graphics libraries. For those, I created dedicated recipes.&lt;/p&gt;

&lt;p&gt;It also requires newer versions of some Debian libraries that aren’t in Bookworm or its backports repository (e.g. &lt;strong&gt;libpng&lt;/strong&gt; with APNG support). For those, I ended up creating a backports repository of my own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Debian Backports
&lt;/h2&gt;

&lt;p&gt;I created a new GitHub repository, &lt;a href="https://github.com/KodeGood/debian-backports" rel="noopener noreferrer"&gt;debian-backports&lt;/a&gt;, which includes a &lt;strong&gt;GitHub Actions&lt;/strong&gt; &lt;a href="https://github.com/KodeGood/debian-backports/blob/main/.github/workflows/deb-build-bookworm.yml" rel="noopener noreferrer"&gt;workflow&lt;/a&gt; that downloads package source tarballs from upstream repositories and overlays Debian build rules.&lt;/p&gt;

&lt;p&gt;The workflow uses &lt;strong&gt;QEMU&lt;/strong&gt; to build both amd64 and arm64 versions of the Debian packages. Finally, it publishes the APT repository (created with &lt;strong&gt;reprepro&lt;/strong&gt;) to GitHub Pages.&lt;/p&gt;

&lt;p&gt;The repository is available at: &lt;a href="https://kodegood.github.io/debian-backports" rel="noopener noreferrer"&gt;kodegood.github.io/debian-backports&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Isar/BitBake Recipes
&lt;/h2&gt;

&lt;p&gt;As mentioned, I wrote new recipes for some dependencies like &lt;strong&gt;Skia&lt;/strong&gt; and &lt;strong&gt;ANGLE&lt;/strong&gt;, and then for Ladybird itself.&lt;/p&gt;

&lt;p&gt;I also applied a couple of patches on top of Ladybird. The main one strips out the browser chrome from Ladybird’s UI, since that’s not needed in a web runtime.&lt;/p&gt;

&lt;p&gt;Ladybird uses &lt;strong&gt;Qt&lt;/strong&gt; as its UI library on Linux and Windows. For now, I simply commented out parts of the code, but since Ladybird has a web content view API, a better long-term approach would be to implement a separate lightweight Qt content view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flx39pitbrdi1saqj2j4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flx39pitbrdi1saqj2j4y.png" alt="Isar image flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;The demo setup is similar to what I had with the WPE version&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Debian Bookworm&lt;/strong&gt; as the base platform&lt;/li&gt;
&lt;li&gt;A slightly customized &lt;strong&gt;Weston IVI-shell&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ladybird browser&lt;/strong&gt;, built from source&lt;/li&gt;
&lt;li&gt;Hardware: &lt;strong&gt;Raspberry Pi 5&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Known issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IME integration is not working, meaning no virtual keyboard&lt;/li&gt;
&lt;li&gt;YouTube is not working. For now, Big Buck Bunny plays via a local page and local file using the video tag&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;From the build configuration menu you can select Ladybird to be built.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk1xyda9bhmo6dioggxh5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk1xyda9bhmo6dioggxh5.png" alt="KAS build menu"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, after flashing the image to the Raspberry Pi 5:&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/hnucZqk6n7M"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;Note: This is just a tech demo, not a full production web runtime&lt;/p&gt;

&lt;p&gt;If you’d like to try it, the project’s &lt;a href="https://github.com/zhani/webruntime-debian/blob/main/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt; has setup instructions.&lt;/p&gt;

&lt;p&gt;The project is available on GitHub as &lt;a href="https://github.com/zhani/webruntime-debian" rel="noopener noreferrer"&gt;webruntime-debian&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ladybird</category>
      <category>embedded</category>
      <category>raspberrypi</category>
    </item>
    <item>
      <title>Build Embedded Debian Web Runtime with the Power of Isar</title>
      <dc:creator>Jani Hautakangas</dc:creator>
      <pubDate>Sat, 29 Nov 2025 10:29:11 +0000</pubDate>
      <link>https://forem.com/janihau/build-embedded-debian-web-runtime-with-the-power-of-isar-150a</link>
      <guid>https://forem.com/janihau/build-embedded-debian-web-runtime-with-the-power-of-isar-150a</guid>
      <description>&lt;p&gt;Originally posted on &lt;a href="https://medium.com/kodegood" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;When most people think about building something for embedded devices, &lt;strong&gt;Yocto&lt;/strong&gt; is the first tool that comes to mind.&lt;/p&gt;

&lt;p&gt;But there’s another option worth considering, one that blends the stability of &lt;strong&gt;Debian&lt;/strong&gt; with the flexibility of &lt;strong&gt;BitBake&lt;/strong&gt;. In this post, I’ll walk you through how I used &lt;strong&gt;&lt;a href="https://github.com/ilbers/isar" rel="noopener noreferrer"&gt;Isar&lt;/a&gt;&lt;/strong&gt; (Integration System for Automated Root filesystem generation), &lt;strong&gt;Debian Bookworm&lt;/strong&gt;, and &lt;strong&gt;WPEWebKit&lt;/strong&gt; to create an experimental embedded web runtime running on a &lt;strong&gt;Raspberry Pi 5&lt;/strong&gt; and &lt;strong&gt;Intel NUC&lt;/strong&gt;, and why this approach might be worth trying in your next project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqpqzupq8s14ey1rt784g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqpqzupq8s14ey1rt784g.png" alt="Isar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mazdfmd5d1tfgbqb3de.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mazdfmd5d1tfgbqb3de.png" alt="Isar flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Isar?
&lt;/h2&gt;

&lt;p&gt;The build process in Isar will feel familiar if you’ve worked with Yocto: each component is defined in a BitBake recipe, and you can create dependency trees in the same way.&lt;/p&gt;

&lt;p&gt;The biggest difference is that Isar builds everything around Debian tooling and packaging. It fetches packages directly from upstream Debian repositories, giving you stable and well-tested packages out of the box.&lt;/p&gt;

&lt;p&gt;That said, you can still build from source, customize configurations, and add your own packages.&lt;/p&gt;

&lt;p&gt;I’ve been using Isar for some time in a client project to create and maintain Debian platforms for a fleet of industrial PCs. Ever since, I’ve thought it would be a handy tool for creating an embedded web runtime. So, I decided to give it a try and figured others might be interested in the process too.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Demo Setup
&lt;/h2&gt;

&lt;p&gt;For this demo, I used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Debian Bookworm&lt;/strong&gt; as the base platform&lt;/li&gt;
&lt;li&gt;A slightly customized &lt;strong&gt;Weston IVI-shell&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WPEWebKit&lt;/strong&gt;, built from source (version 2.48.3)&lt;/li&gt;
&lt;li&gt;Hardware: &lt;strong&gt;Raspberry Pi 5&lt;/strong&gt; and an old &lt;strong&gt;Intel NUC&lt;/strong&gt; (still in its box after many years!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For configuration, I used &lt;strong&gt;kas&lt;/strong&gt; (a tool that makes it easy to set up BitBake-based projects) and &lt;strong&gt;kas-container&lt;/strong&gt; to run the build in a container, avoiding the need to install Isar and its dependencies locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;I started by creating a configuration structure for my needs, plus BSP layer recipes for the Raspberry Pi 5 and Intel NUC.&lt;/p&gt;

&lt;p&gt;I implemented a few Weston modules to make the system UI look more polished than the default Weston setup.&lt;/p&gt;

&lt;p&gt;Next, I wrote the recipes to build the Weston modules and WPEWebKit.&lt;br&gt;
I wanted Weston to run as a dedicated webruntime user, which required additional configs and PolicyKit rules.&lt;/p&gt;

&lt;p&gt;Getting WPEWebKit up and running took several iterations, a few quirks, and some patching here and there but eventually it worked.&lt;/p&gt;
&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;The result was a config screen where you can select the desired build configuration:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrd06udm3fxmqjroz95z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrd06udm3fxmqjroz95z.png" alt="KAS container menu"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you hit &lt;strong&gt;Build&lt;/strong&gt;, you’ll see the familiar BitBake process in the terminal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5yc5pu3ndg9y62bcyz1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5yc5pu3ndg9y62bcyz1w.png" alt="Isar terminal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, after flashing the image to the Raspberry Pi 5:&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/ne90xg-Iwmc"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This is just a tech demo, not a full production web runtime. Each application launches a separate WPEWebKit instance, and there’s no runtime manager to coordinate them.&lt;/p&gt;

&lt;p&gt;If you’d like to try it, the project’s &lt;a href="https://github.com/zhani/webruntime-debian/blob/main/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt; has setup instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debian 13&lt;/strong&gt; support is already in progress, and there’s an experimental branch with early &lt;a href="https://github.com/zhani/webruntime-debian/tree/ladybird" rel="noopener noreferrer"&gt;Ladybird browser engine&lt;/a&gt; integration but it’s not finished and currently does not even compile.&lt;/p&gt;

&lt;p&gt;The project is available on GitHub as &lt;a href="https://github.com/zhani/webruntime-debian" rel="noopener noreferrer"&gt;webruntime-debian&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>embedded</category>
      <category>webdev</category>
      <category>webkit</category>
      <category>raspberrypi</category>
    </item>
  </channel>
</rss>
