Skip to content

Latest commit

Β 

History

49 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Kromium Logo
Kromium

Modern Chromium Embedded Framework for Compose Multiplatform Desktop & Universal Java (Swing, AWT, SWT, JavaFX) Applications

Maven Central Documentation Portal Kotlin Java Compose Multiplatform License Platforms


Kromium is an open-source, production-grade Chromium Embedded Framework (CEF) library built with first-class multi-toolkit ergonomics for Compose Multiplatform Desktop and the entire Universal Java Desktop ecosystem (Swing, AWT, Eclipse SWT, JavaFX) across Windows, macOS, and Linux.

Backed by CEF 150 and the battle-tested JetBrains JCEF runtime, Kromium delivers on-demand bootstrapping, hardware-accelerated rendering, pure Java2D lightweight off-screen rendering (OSR), dynamic HiDPI scaling, virtual asset streaming via custom protocols (app://), asynchronous PDF export, declarative context menus, WebRTC permission interception, two-way JavaScript IPC bridges, and enterprise proxying.

Tip

Explore the Interactive Documentation Portal: Visit kromium.daviante.dev for interactive guides, API search, and live demos. Full technical documentation is also maintained in the docs/ directory.


🌟 Highlights & Killer Features

  • πŸš€ Universal Java Desktop Ecosystem: Native declarative @Composable KromiumView for Compose Desktop, alongside first-class support for Java Swing, Standard AWT, Eclipse SWT, and JavaFX with zero Kotlin runtime dependencies required for JVM callers.
  • 🎨 Pure Java2D Lightweight OSR (Zero JOGL/OpenGL): Built-in KromiumOSRPanel draws Chromium byte buffers directly into Java2D double-buffered images, completely resolving Swing/JavaFX airspace and Z-ordering conflicts without external OpenGL native libraries. True-color little-endian memory mapping eliminates the classic inverted red/blue "Smurf" bug with zero CPU overhead.
  • πŸ–±οΈ Continuous Sub-Pixel Trackpad & Wheel Scrolling: Full getPreciseWheelRotation() sub-pixel event translation and floating-point accumulation eliminate dead-zones, lag, and sudden jumps on macOS Trackpads and Windows Precision Touchpads.
  • ⌨️ Native macOS Command (⌘) Shortcuts in OSR: Seamless execution of Cmd+C, Cmd+V, Cmd+X, Cmd+A, Cmd+Z, redo, reload, zoom, and history navigation even without a native Cocoa window or menu bar.
  • πŸ–₯️ Automatic HiDPI / Retina Scaling: Dynamic scale factor detection (AffineTransform.getScaleX()) and real-time screen info synchronization guarantee razor-sharp web rendering across mixed 125%, 150%, and 200% displays on Windows, macOS, and Linux. Fully configurable via developer APIs (scaleFactor, scrollMultiplier, RenderingHints).
  • πŸ“¦ Zero-Bloat On-Demand Bootstrapping: Ship ultra-compact 15–30 MB desktop installers. Kromium downloads, verifies with SHA-256, extracts, and caches the native platform JCEF runtime on first launch.
  • 🌐 Virtual Asset Streaming (app://): Stream local bundled HTML, CSS, JS, and WebAssembly directly from classpath resources or local directories via custom protocols without running a local HTTP server.
  • πŸ“„ Async Vector PDF Export & Native Print Dialog: Non-blocking document printing via Kotlin Coroutines (printToPdf) or Java CompletableFuture (printToPdfAsync), plus native OS print dialogs (print()).
  • πŸ–±οΈ Declarative Context Menu DSL: Full control over right-click menus with turnkey shortcuts (inspectElement(), copyLink(), searchWeb()) and direct lambda callbacks without JCEF integer command bookkeeping.
  • πŸŽ™οΈ WebRTC Media & Device Permissions: Granular, origin-aware permission interception for Microphone, Camera, Screen Sharing, and Desktop Audio with in-memory session caching and strict security defaults.
  • ⚑ Two-Way JavaScript Bridge: Coroutine and CompletableFuture JS evaluation, DOM extraction, and secure type-safe bidirectional IPC routing using @JavascriptInterface.
  • 🏒 Enterprise Proxy & Network Management: Dynamic runtime proxy switching (PAC, WPAD, HTTPS TLS tunnels, SOCKS5 remote DNS), NTLM/Kerberos SSO, SSL error policies, and host locking.
  • β˜• Zero JVM Module Configuration: Automatic runtime module opening eliminates manual --add-opens flags on Java 17, 21, and 23+.
  • πŸ€– Enterprise Web Automation & Headless Normalization: Rich, auto-waiting DOM automation DSL (click, fill, waitForSelector, selectOption), in-flight network synchronization (waitForNetworkIdle), and headless desktop environment normalization for reliable E2E testing and server-side data extraction without external drivers or fragile Selenium/Playwright processes.

πŸ“¦ Installation

Add Kromium to your project dependencies:

Gradle (Kotlin DSL)

repositories {
    mavenCentral()
    google()
    maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}

dependencies {
    // For Compose Multiplatform Desktop:
    implementation("dev.daviante:kromium-compose:3.0.150-b11")

    // Or for Pure Java / Swing / Headless JVM:
    implementation("dev.daviante:kromium-core:3.0.150-b11")
}

Gradle (Groovy DSL)

repositories {
    mavenCentral()
    google()
    maven { url 'https://maven.pkg.jetbrains.space/public/p/compose/dev' }
}

dependencies {
    implementation 'dev.daviante:kromium-compose:3.0.150-b11'
    // or: implementation 'dev.daviante:kromium-core:3.0.150-b11'
}

Apache Maven (pom.xml for Pure Java)

<dependency>
    <groupId>dev.daviante</groupId>
    <artifactId>kromium-core</artifactId>
    <version>3.0.150-b11</version>
</dependency>

⚑ 5-Minute Quickstart

Kotlin (Compose Multiplatform Desktop)

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import dev.daviante.kromium.compose.KromiumView
import dev.daviante.kromium.compose.rememberKromiumViewState
import dev.daviante.kromium.presentation.browser.Kromium

fun main() = application {
    LaunchedEffect(Unit) {
        if (!Kromium.isReady) Kromium.initialize()
    }

    Window(onCloseRequest = ::exitApplication, title = "Kromium Compose Browser") {
        MaterialTheme {
            val state = rememberKromiumViewState(initialUrl = "https://github.com/daviante/kromium")
            KromiumView(state = state, modifier = Modifier.fillMaxSize())
        }
    }
}

Pure Java (Swing / Enterprise)

import dev.daviante.kromium.domain.config.KromiumConfig;
import dev.daviante.kromium.presentation.browser.Kromium;
import dev.daviante.kromium.presentation.browser.KromiumBrowser;
import dev.daviante.kromium.presentation.browser.KromiumClient;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class QuickstartJava {
    public static void main(String[] args) {
        // 1. Initialize engine
        Kromium.initialize(KromiumConfig.builder().build());

        // 2. Create client and browser
        KromiumClient client = Kromium.newClient();
        KromiumBrowser browser = client.createBrowser("https://github.com/daviante/kromium");

        // 3. Mount UI component into standard JFrame
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Kromium Java Browser");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(1280, 800);
            frame.add(browser.getUiComponent());
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

πŸ–₯️ Universal Java Desktop Compatibility Matrix

Kromium is engineered to run seamlessly across every major JVM graphical toolkit. Choose the optimal rendering mode and container for your architecture:

Framework / Toolkit Recommended Mode Underlying Technology Primary Container Sample Project
Compose Multiplatform Windowed (GPU) (or OSR) Skia Hole-Punching via SwingPanel @Composable KromiumView :kromium-sample-compose
Java Swing Lightweight OSR (Default) Pure Java2D KromiumOSRPanel JFrame / JPanel :kromium-sample-swing
Standard AWT Heavyweight Windowed Native OS Window embedding java.awt.Frame / Panel :kromium-sample-awt
Eclipse SWT Heavyweight Windowed Bridged AWT Composite (SWT_AWT) org.eclipse.swt.widgets.Shell :kromium-sample-swt
JavaFX Lightweight OSR Embedded Swing wrapper (SwingNode) javafx.scene.Scene / SwingNode :kromium-sample-javafx

Tip

For complete setup instructions and code examples for each framework, see the Universal Java Desktop Quickstart.


1. 🌐 Virtual Local Asset Streaming (app://)

Serve local bundled web applications (HTML, CSS, JavaScript, React/Vue bundles, WebAssembly) securely via custom protocols without opening local HTTP ports or battling port-clash and CORS issues.

Kotlin (Compose)

import dev.daviante.kromium.presentation.browser.Kromium
import dev.daviante.kromium.presentation.scheme.KromiumCustomScheme
import dev.daviante.kromium.presentation.scheme.KromiumSchemeHandler

// Register 'app://' before initialize:
Kromium.registerCustomScheme(
    KromiumCustomScheme.create(
        schemeName = "app",
        domain = "myapp",
        handler = KromiumSchemeHandler.fromClasspath(
            resourcePathPrefix = "/web-app",
            spaFallback = "index.html"
        )
    )
)
Kromium.initialize()

// In Compose UI:
state.loadUrl("app://myapp/index.html")

Pure Java (Swing)

import dev.daviante.kromium.presentation.browser.Kromium;
import dev.daviante.kromium.presentation.scheme.KromiumCustomScheme;
import dev.daviante.kromium.presentation.scheme.KromiumSchemeHandler;

// Register 'app://' protocol backed by classpath bundle:
Kromium.registerCustomScheme(
    KromiumCustomScheme.builder("app")
        .domain("myapp")
        .handler(KromiumSchemeHandler.fromClasspath("/web-app", "index.html"))
        .build()
);
Kromium.initialize();

browser.loadUrl("app://myapp/index.html");

πŸ“– Deep dive: docs/guides/asset-filtering-and-security.md


2. πŸ“„ Async Vector PDF Export & Native Print Dialog

Export web pages into high-resolution, vector-crisp PDF documents asynchronously with precise layout control, or trigger the operating system's native print preview dialog.

Kotlin (Coroutines & Compose)

import dev.daviante.kromium.domain.model.KromiumPaperSize
import dev.daviante.kromium.domain.model.KromiumPdfMargins
import dev.daviante.kromium.domain.model.KromiumPdfSettings
import java.io.File

// Non-blocking suspending export:
val pdf: File = browser.printToPdf(
    targetFile = File("exports/invoice.pdf"),
    settings = KromiumPdfSettings(
        paperSize = KromiumPaperSize.A4,
        landscape = false,
        printBackground = true,
        margins = KromiumPdfMargins.fromMillimeters(10.0, 10.0, 10.0, 10.0),
        displayHeaderFooter = true,
        headerTemplate = "<span class=\"title\"></span>",
        footerTemplate = "<span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span>"
    )
)

// Or open the native OS print dialog:
state.print() // in Compose
// or: browser.print()

Pure Java (CompletableFuture)

import dev.daviante.kromium.domain.model.KromiumPaperSize;
import dev.daviante.kromium.domain.model.KromiumPdfMargins;
import dev.daviante.kromium.domain.model.KromiumPdfSettings;
import java.io.File;

KromiumPdfSettings settings = KromiumPdfSettings.builder()
    .paperSize(KromiumPaperSize.Letter)
    .printBackground(true)
    .margins(KromiumPdfMargins.None.INSTANCE)
    .build();

// Non-blocking async generation returning CompletableFuture<File>:
browser.printToPdfAsync(new File("exports/report.pdf"), settings)
    .thenAccept(file -> System.out.println("Generated PDF: " + file.getAbsolutePath()))
    .exceptionally(ex -> {
        System.err.println("PDF generation failed: " + ex.getMessage());
        return null;
    });

// Interactive native print dialog:
browser.print();

πŸ“– Deep dive: docs/reference/browser-and-client-api.md


3. πŸ–±οΈ Declarative Context Menu DSL & Turnkey Actions

Customize, add, or replace right-click context menus with high-level actions, custom callbacks, and built-in shortcuts without manual integer command ID plumbing.

Kotlin (Compose)

import dev.daviante.kromium.presentation.menu.KromiumContextMenuHandler

state.setContextMenu { ctx ->
    clear() // Remove default browser items (View Source, etc.)

    if (ctx.params.isLink()) {
        copyLink("Copy Target Link")
        separator()
    }

    if (ctx.params.hasSelection()) {
        copy("Copy")
        searchWeb() // Turnkey: "Search Google for '%s'"
        separator()
    }

    item("Custom App Action") { context ->
        println("User clicked on: ${context.params.pageUrl}")
    }

    subMenu("Developer") {
        inspectElement() // Opens DevTools inspecting clicked coordinates
        viewSource()
    }
}

// Or use ready-made turnkey presets:
state.contextMenuHandler = KromiumContextMenuHandler.minimalEditing(includeInspectElement = true)
state.contextMenuHandler = KromiumContextMenuHandler.devToolsOnly()
state.contextMenuHandler = KromiumContextMenuHandler.disabled()

Pure Java (Swing)

import dev.daviante.kromium.presentation.menu.KromiumContextMenuHandler;

client.setContextMenuHandler((builder, ctx) -> {
    builder.clearDefaults();

    if (ctx.getParams().hasSelection()) {
        builder.copy();
        builder.searchWeb();
        builder.addSeparator();
    }

    builder.inspectElement();
    builder.addItem("Export Row", c -> exportSelection(c.getParams().getSelectionText()));
});

// Turnkey presets:
client.setContextMenuHandler(KromiumContextMenuHandler.minimalEditing(true));
client.setContextMenuHandler(KromiumContextMenuHandler.devToolsOnly());

πŸ“– Deep dive: docs/reference/handlers-and-events.md


4. πŸŽ™οΈ WebRTC Media Permissions & Session Caching

Intercept and evaluate web permission requests (Microphone, Camera, Screen Sharing, Desktop Audio) requested by web apps (e.g. Google Meet, Zoom, WebRTC video calling). Unhandled requests default strictly to Deny.

Kotlin (Compose)

import dev.daviante.kromium.presentation.handler.KromiumPermissionDecision
import dev.daviante.kromium.presentation.handler.KromiumPermissionHandler
import dev.daviante.kromium.presentation.handler.KromiumPermissionType

// Fine-grained selective permission filtering:
state.permissionHandler = KromiumPermissionHandler { request ->
    when {
        // Whitelist corporate domain for audio only
        request.origin == "https://meet.corp.internal" -> {
            KromiumPermissionDecision.grant(KromiumPermissionType.AUDIO_CAPTURE)
        }
        // Grant all permissions for trusted apps
        request.origin.startsWith("app://") -> KromiumPermissionDecision.GRANT
        // Securely deny all untrusted sites
        else -> KromiumPermissionDecision.DENY
    }
}

// Or use ready-made turnkey domain presets:
state.permissionHandler = KromiumPermissionHandler.forOrigins("meet.google.com", "zoom.us")

// Programmatically revoke remembered session permissions:
state.clearPermissionCache()

Pure Java (Swing)

import dev.daviante.kromium.presentation.handler.KromiumPermissionDecision;
import dev.daviante.kromium.presentation.handler.KromiumPermissionHandler;
import dev.daviante.kromium.presentation.handler.KromiumPermissionType;

client.setPermissionHandler(request -> {
    if (request.hasAudio() && "https://meet.company.com".equals(request.getOrigin())) {
        return KromiumPermissionDecision.grant(KromiumPermissionType.AUDIO_CAPTURE);
    }
    return KromiumPermissionDecision.DENY;
});

// Turnkey origin allowlist:
client.setPermissionHandler(KromiumPermissionHandler.forOrigins("meet.google.com", "zoom.us"));

// Revoke session cache:
client.clearPermissionCache();

πŸ“– Deep dive: docs/reference/handlers-and-events.md


5. ⚑ Two-Way JavaScript Bridge & Typed DOM Evaluation

Execute arbitrary JavaScript with coroutine and CompletableFuture return values, or bind native JVM objects to JavaScript's window object for bidirectional communication.

Kotlin (Coroutines & Compose)

import dev.daviante.kromium.presentation.js.JavascriptInterface

// 1. Evaluate JavaScript asynchronously:
val headingText: String? = browser.evaluateJavascript("document.querySelector('h1').innerText")

// 2. Register native object into JavaScript window context:
class NativeBridge {
    @JavascriptInterface
    fun onUserAction(payload: String) {
        println("Received from web page: $payload")
    }
}

browser.registerJsInterface(NativeBridge(), "desktopApp")
// In web page: window.desktopApp.onUserAction("Hello from JS!")

Pure Java (CompletableFuture)

import dev.daviante.kromium.presentation.js.JavascriptInterface;

// 1. Evaluate JavaScript returning CompletableFuture<String>:
browser.evaluateJavascript("document.title")
    .thenAccept(title -> System.out.println("Page title is: " + title));

// 2. Register native Java bridge object:
public class NativeBridge {
    @JavascriptInterface
    public void notify(String message) {
        System.out.println("Message from JS: " + message);
    }
}

browser.registerJsInterface(new NativeBridge(), "desktopApp");

πŸ“– Deep dive: docs/guides/javascript-and-dom.md


6. πŸ€– Headless Automation, DOM Interaction DSL & Screenshots

Perform server-side web automation, E2E workflow testing, structured DOM extraction, and automated screenshot capture in offscreen headless environments with full desktop environment normalization and network idle synchronization.

Kotlin (Coroutines)

// 1. Initialize headless browser with desktop normalization:
val config = KromiumConfig().apply {
    windowlessRendering = true
    emulateDesktopEnvironment = true
}
Kromium.initialize(config)

val browser = Kromium.newClient().createBrowser("https://example.com/login")

// 2. Automate user interaction with auto-waiting DSL:
browser.waitForSelector("#username")
browser.fill("#username", "service-account")
browser.fill("#password", "SecureKey456!")
browser.click("button[type='submit']")

// 3. Synchronize with background network activity:
browser.waitForNetworkIdle(idleTimeMs = 500)

// 4. Extract data or capture raster screenshot:
val headline = browser.getTextContent(".welcome-title")
val screenshot: java.awt.image.BufferedImage? = browser.takeScreenshot()

Pure Java (CompletableFuture)

KromiumBrowser browser = client.createBrowser("https://example.com/portal");

// Chain interaction steps asynchronously:
browser.waitForSelectorAsync("#search", 5_000)
    .thenCompose(ok -> browser.fillAsync("#search", "Enterprise Chromium", 5_000))
    .thenCompose(ok -> browser.clickAsync("#submit", 5_000))
    .thenCompose(ok -> browser.waitForNetworkIdleAsync(500, 10_000))
    .thenCompose(ok -> browser.getTextContentAsync(".result-text", 5_000))
    .thenAccept(result -> System.out.println("Extracted Result: " + result));

πŸ“– Deep dive: docs/guides/headless-and-automation.md


πŸͺŸ Native Window Chrome & Custom Tab Strips

Optional, flag-enabled helper utilities for integrating custom tab strips with native OS titlebars and macOS traffic lights without imposing rigid defaults or altering standard window behavior.

Kotlin Compose Multiplatform

import dev.daviante.kromium.compose.chrome.macTrafficLightsPadding
import dev.daviante.kromium.compose.chrome.MacTrafficLightsSpacer

// In your custom TabStrip / Header composable:
Row(
    modifier = Modifier
        .fillMaxWidth()
        // Automatically applies padding on macOS only when enabled; 0.dp otherwise
        .macTrafficLightsPadding(enabled = true, width = 76.dp)
) {
    // Custom tab items here...
}

// Or use a platform-adaptive spacer:
Row(modifier = Modifier.fillMaxWidth()) {
    MacTrafficLightsSpacer(enabled = true, width = 76.dp)
    // Custom tabs...
}

Pure Java & Swing

import dev.daviante.kromium.presentation.chrome.KromiumChromeConfig;
import dev.daviante.kromium.presentation.chrome.KromiumWindowChrome;

// 1. Configure macOS full window content (merging tab strip with titlebar)
KromiumChromeConfig config = KromiumChromeConfig.builder()
    .enabled(true)
    .macTrafficLightsWidth(80)
    .transparentTitleBar(true)
    .hideWindowTitle(true)
    .build();

KromiumWindowChrome.apply(frame, config);

// 2. Enable window dragging & double-click maximize on custom tab strip
KromiumWindowChrome.installWindowDragger(tabStripPanel, frame);

πŸ“š Modular Documentation Hub

Comprehensive, in-depth documentation organized according to the DiΓ‘taxis framework is maintained in the docs/ directory:

Category Guides & References Key Topics
πŸš€ Getting Started Installation Guide
Compose Quickstart
Swing JVM Quickstart
Repository setup, multi-module configurations, Gradle dependencies, first browser window.
πŸ›οΈ Core Concepts Architecture
State & Lifecycle
Security & Privacy
Bootstrap pipeline, multi-process Chromium architecture, KromiumState flow, and telemetry suppression.
πŸ“– Guides Compose UI Integration
Navigation & History
JavaScript & DOM
Network & Proxies
Multi-tab UI, navigation controls, coroutine JS execution, IPC routers, and enterprise proxy configuration.
πŸ“– Guides (Cont.) Asset Filtering & Schemes
Cookie Management
Downloads & Dialogs
Headless & Automation
Virtual asset streaming, ad blocking, host locking, async cookie store, modal dialogs, and off-screen data extraction.
πŸ“‹ API Reference Configuration (KromiumConfig)
Browser & Client API
Handlers & Events
Exceptions & Logging
Complete property catalogs, method signatures, composite multiplexers, and pluggable logging.
πŸ“¦ Deployment Packaging & Distribution
Platform Considerations
Troubleshooting & FAQ
Desktop installers (MSI, DMG, DEB), ProGuard/R8 rules, macOS framework symlinks, and Linux dependencies.

Visit the master sitemap at docs/README.md.


πŸ’» Supported Platforms & OS Requirements

Operating System Architectures Minimum Version Prerequisites
Windows x64 (64-bit) Windows 10 / 11, Server 2019+ Visual C++ 2015–2022 Redistributable
macOS ARM64 (Apple Silicon) & Intel x64 macOS 11.0 (Big Sur)+ None (Universal binaries resolved automatically)
Linux x64 & ARM64 Ubuntu 20.04+, Debian 11+, Fedora 36+ Standard desktop X11/GTK libraries (libnss3, libasound2, libdrm2)

Minimum Java Runtime: Java 17 LTS (Java 21 LTS Recommended).


πŸš€ Running the Showcase Demos

The repository includes ready-to-run desktop browser applications demonstrating every framework integration:

1. Compose Multiplatform Browser Demo

./gradlew :kromium-sample-compose:run

Features multi-tab browsing, DevTools REPL, live canvas animation, and visible text extraction.

2. Pure Java & Swing Showcase Demo

./gradlew :kromium-sample-swing:run

Features lightweight pure Java2D OSR rendering, modern FlatLaf dark theme, download manager dialog, proxy switching, and native print preview.

3. Standard AWT Heavyweight Browser Demo

./gradlew :kromium-sample-awt:run

Demonstrates native heavyweight java.awt.Frame embedding with functional navigation toolbar and clean lifecycle disposal.

4. Eclipse SWT Bridged Browser Demo

./gradlew :kromium-sample-swt:run

Demonstrates embedding CEF inside an Eclipse SWT application via SWT_AWT.new_Frame with full toolbar controls and SWT event loop handling.

5. JavaFX Bridged OSR Browser Demo

./gradlew :kromium-sample-javafx:run

Demonstrates embedding lightweight OSR Chromium inside a JavaFX Scene via SwingNode with dynamic HiDPI scaling, scene resize synchronization, and navigation controls.


βš–οΈ License & Contributing

Kromium is open-source software licensed under the Apache License, Version 2.0. Commercial friendly, royalty-free, and compliant with standard patent and distribution requirements.

All community contributions are welcomed and governed by our Contributor License Agreement (CLA).

About

Production-grade Chromium Embedded Framework (CEF) for Compose Multiplatform Desktop & Universal Java (Swing, JavaFX, SWT, AWT). Features pure Java2D OSR (zero JOGL), dual Kotlin/Java ergonomics, sub-pixel trackpad scrolling, HiDPI scaling, virtual app:// schemes, and WebRTC on Windows, macOS, & Linux.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

22 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages