Framework
chromiumembedded/java-cef avatar
chromiumembedded/java-cef

java-cef: embedding a Chromium browser in a Java desktop application

Java Chromium Embedded Framework (JCEF). A simple framework for embedding Chromium-based browsers in other applications using the Java programming language.

888 stars213 forksJavaNOASSERTION

At a glance

What is it?
The Java Chromium Embedded Framework is a Java wrapper around CEF, the Chromium Embedded Framework, giving a JVM application an HTML5 browser control without pulling in a browser engine of its own. The catch is that you build a native binary distribution against a specific Chromium release, and the project ships that build as a separate artifact rather than a jar.
Who is it for?
java-cef suits a Java desktop product that needs a real browser surface, an HTML5 user interface inside a native shell, or off-screen rendering for a custom drawing framework, and who accepts shipping a Chromium runtime inside their installer. It does not suit a server side service, a web application, or anyone who needs a small dependency, because the unit you consume is a Chromium binary distribution rather than a library.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 44 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A wrapper around CEF, not a browser engine of its own

The Java Chromium Embedded Framework is described as a simple framework for embedding Chromium-based browsers in other applications using the Java programming language, and the project site is at chromiumembedded.github.io/java-cef.

The relationship to CEF is the thing to understand first. CEF is a BSD-licensed open source project founded by Marshall Greenblatt in 2008 and based on the Google Chromium project. The documentation is explicit about the distinction in intent: unlike the Chromium project itself, which focuses mainly on Google Chrome application development, CEF focuses on facilitating embedded browser use cases in third-party applications.

What CEF provides is insulation. It hides the Chromium and Blink implementation complexity behind production-quality stable APIs, release branches that track specific Chromium releases, and binary distributions. Most features come with default implementations that require little or no integration work from the user. The documentation also states that there are currently over 100 million installed instances of CEF worldwide, embedded in products from a wide range of companies and industries.

The use cases listed are worth reading because they are more specific than webview libraries usually are. Embedding an HTML5-compliant web browser control in an existing native application. Creating a lightweight native shell application that hosts a user interface developed primarily using web technologies. Rendering web content off-screen in applications that have their own custom drawing frameworks. And acting as a host for automated testing of existing web properties and applications.

That last one is often overlooked and it is the one with the least obvious dependency cost, because a test host has no shipping constraints.

The Java wrapper covers the C and C++ interfaces through native libraries, and the documentation says it provides close integration between the browser and the host application including support for custom plugins, protocols, JavaScript objects and JavaScript extensions. The host application can optionally control resource loading, navigation, context menus and printing, while taking advantage of the same performance and HTML5 technologies available in the Chrome web browser.

The distribution is a binary package, not a jar

This is the practical difference between java-cef and a JavaScript webview library, and it decides everything about how you deploy it.

The documentation states that JCEF is an extension of the CEF project hosted at github.com/chromiumembedded/cef, that it maintains a development branch tracking the most recent CEF3 release branch, and that JCEF source code can be downloaded, built and packaged into a binary distribution. Once you have created the binary distribution for your platform you can distribute it as a stand-alone package without further dependencies on the JCEF, CEF or Chromium source code.

So the workflow is: check out the JCEF source, build it, package a binary distribution for your platform, and ship that package inside your application. The Branches and Building page at chromiumembedded.github.io/java-cef/branches_and_building holds the detailed instructions.

The repository layout shows what is involved in that build. There is a java/ directory for the Java sources, a native/ directory for the JNI layer, third_party/ for the vendored dependencies, cmake/ for the build system with a CMakeLists.txt at the root, plus tools/, docs/, a build.xml for Ant, appveyor.yml for Windows CI, and .clang-format alongside .style.cfg and .style.yapf.

Three separate build descriptions for one project is worth noting. CMake is the primary path, but build.xml suggests an Ant route and appveyor.yml a Windows CI route, and each of those is a place where the build can diverge between platforms.

The downloads are split across two repositories. Binary distributions come from jcefmaven/jcefbuild, and the Maven and Gradle artifacts from jcefmaven/jcefmaven. So there is a per-platform binary you ship and a jar you depend on, and they have to be kept in step.

Troubleshooting means matching versions across three layers

The contributing guidelines contain the most practically useful information in the repository, because they tell you what a good bug report looks like and therefore what the version surface actually is.

Every JCEF issue should include the JCEF revision, the CEF revision or binary distribution version, and information about the OS and compiler version. If the issue is a bug, it should provide detailed reproduction information. If it is a feature, it should describe why the feature is beneficial.

Three version identifiers in one report is the giveaway. The JCEF revision is your fork of CEF, the CEF revision is the Chromium release it tracks, and the binary distribution version is the packaged artefact your users actually run. A bug that only reproduces with a specific Chromium build can be in any of the three layers, and pinning them down is what makes it fixable.

The pull request guidelines are similarly specific. Changes should be submitted against the current JCEF master branch unless explicitly fixing a bug in a CEF release branch, they should follow the style of existing JCEF source files, and in general JCEF uses the Chromium coding style. They should include new or modified unit tests as appropriate, and they should not include unnecessary or unrelated changes.

Two other instructions are worth carrying into your own planning. Create or find an appropriate issue for each distinct bug, feature or change before you submit the pull request, and write unit tests for new or existing functionality.

The project also asks contributors to search for TODO(cef) in the source code for ideas, which is a useful way to find the work the upstream maintainers have marked as wanted.

Where java-cef is the wrong choice

Three cases, and the first one is categorical.

This is not a server side or web application dependency. CEF embeds a browser as a native control inside a desktop application, and the distribution model reflects that, a binary distribution per platform that goes into your installer. If you are writing a Spring Boot service or a React front end, the browser you want is the user's browser, and a JavaScript webview component is both smaller and more appropriate.

The second is the Chromium coupling. Because CEF tracks specific Chromium releases and exposes that API surface, you inherit Chromium's release cadence, including the security update pressure. That is entirely manageable if you plan for it, since you rebuild the binary distribution when Chromium moves, and it is a problem if you expected a stable library dependency. The repository has no GitHub releases, so the versioning is carried by the binary distribution version and the branches, which means the upgrade path is a rebuild rather than a dependency bump.

The third is the size of what you ship. A Chromium runtime inside an installer changes the download size of your product by an order of magnitude relative to a Swing or JavaFX control, and on a desktop product that matters for the download, for the disk footprint and for the enterprise deployment that pushes updates to thousands of machines.

The alternatives differ in what they give up. A JavaFX WebView gives you a browser inside a Java desktop application with no Chromium build step, at the cost of a different engine and a more limited API. A plain Swing or JavaFX application has no browser at all and the smallest footprint. And for a native shell whose whole interface is web technology, the smallest option is a native web view provided by the platform, a WKWebView on macOS or a WebView2 on Windows, with no embedded engine to distribute.

CEF earns its place when the application genuinely needs Chromium's behaviour specifically, because it is the only way to embed that exact engine outside of shipping Chrome itself.

Editorial conclusion

java-cef suits a Java desktop product that needs a real browser surface, an HTML5 user interface inside a native shell, or off-screen rendering for a custom drawing framework, and who accepts shipping a Chromium runtime inside their installer. It does not suit a server side service, a web application, or anyone who needs a small dependency, because the unit you consume is a Chromium binary distribution rather than a library. Before adopting it, read the Branches and Building page and decide which Chromium release you will track, because that choice determines your rebuild cadence and your security update path.

Frequently asked questions

What is the Java Chromium Embedded Framework?

It is a Java wrapper around CEF, the Chromium Embedded Framework, which lets a JVM application host an HTML5 browser control. CEF insulates the host from Chromium and Blink internals behind stable APIs, release branches that track specific Chromium releases, and binary distributions.

How is java-cef distributed?

As a native binary distribution you build yourself rather than as a jar alone. The JCEF source can be downloaded, built and packaged into a binary distribution for your platform, which you can then distribute as a stand-alone package with no further dependency on the JCEF, CEF or Chromium source. Binary downloads come from the jcefmaven/jcefbuild repository and the Maven and Gradle artifacts from jcefmaven/jcefmaven.

What should a java-cef bug report include?

The JCEF revision, the CEF revision or binary distribution version, and information about the OS and compiler version. Bugs need detailed reproduction information and feature requests should describe why the feature is beneficial.

Which languages and operating systems does CEF support?

The documentation states that CEF supports a wide range of programming languages and operating systems and can be integrated into both new and existing applications. The Java wrapper is this repository, and the JCEF project maintains a development branch tracking the most recent CEF3 release branch.

How do I get help with java-cef?

Usage questions go to the JCEF Forum rather than the issue tracker. Bugs and feature requests go to the JCEF issue tracker on GitHub, where contributions should be submitted against the current master branch, follow the Chromium coding style, include unit tests and avoid unrelated changes.

Official sources

  1. chromiumembedded/java-cef on GitHub
  2. Issues
  3. Project website
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/chromiumembedded-java-cef.svg)](https://hysenlabs.com/projects/chromiumembedded-java-cef)

Was this useful?