Jvppeteer drives Chrome over DevTools and Firefox over WebDriver-bidi
Java API For Chrome and Firefox
At a glance
- What is it?
- Jvppeteer is a Java port of the Puppeteer style browser automation API, published on Maven Central, that controls Chrome for Testing through the DevTools protocol and Firefox through WebDriver-bidi. It pins a browser version per library release, and the two browsers do not offer the same feature set.
- Who is it for?
- Java teams that want Puppeteer style browser automation without leaving the JVM should adopt Jvppeteer, because it offers Puppeteer style automation for Chrome while also exposing Firefox through WebDriver-bidi.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 19 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 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A Java port of the Puppeteer idea, with two different transports
Jvppeteer is described as a Java API for Chrome and Firefox, and it controls Chrome for Testing through the DevTools protocol and Firefox through WebDriver-bidi.
That single sentence contains the important architectural fact, and it is easy to read past it. Chrome is driven over DevTools, which is the browser's own debugging protocol and therefore gives access to everything the browser exposes. Firefox is driven over WebDriver-bidi, the browser's bidirectional WebDriver extension, and the README is explicit that it does not support all functions. Functions it does not support throw UnsupportedOperationException.
So the library presents one API over two protocols with different coverage. For a Chrome-only team this is not a caveat, since DevTools is the richer path. For a team that needs Firefox, it means the feature matrix is not the same on both browsers, and the README points at a support list rather than claiming parity.
The default mode is headless, without a UI, and a headed mode can be configured instead. The rest of the feature list is the familiar one: generating a PDF of a page, scraping a single page application and producing pre-rendered content, that is server side rendering, automating form submission for UI testing and keyboard input, building an automated test environment that always runs the latest JavaScript and browser features in the latest Chrome, capturing a timeline trace of a site to help analyse performance problems, and testing browser extensions.
The project is published to Maven Central under io.github.fanyong920, is Apache-2.0 licensed, and the repository carries a pom.xml, a src directory, an example directory with its own pom.xml and example sources, a CHANGELOG.md and a _config.yml.
Each library version is bound to a browser version
The README keeps a table mapping Jvppeteer versions to the browser versions they are tested against, and the advice is to use the bound version.
For the current line the table maps 3.6.3 to 3.6.5 to Chrome for Testing 149.0.7798.0 and Firefox stable 149.0. The previous lines follow the same pattern, with 3.5.0 to 3.6.2 bound to Chrome 142.0.7444.175 and Firefox 145.0.1, 3.4.0 to 3.4.2 to Chrome 137.0.7151.119 and Firefox 139.0.4, and so on back through 3.0.0 to 2.2.0. The rule stated above the table is that if no exactly matching Jvppeteer version is listed, the supported browser version is the one from the version immediately before it.
That fallback rule is the practical bit. It means you can pin a Jvppeteer version and still know which browser build it expects, even when your version sits between two listed ranges.
There is also a change of browser family in the history. From version 2.0.0 onwards Jvppeteer works with Chrome for Testing, which uses the new headless mode, with the old headless mode now a separate program called chrome-headless-shell. Whichever of Chrome or chrome-headless-shell you use, you set headless to true and Jvppeteer matches the new and old headless modes automatically. Before that version Jvppeteer downloaded and worked with Chromium.
For a build pipeline this is the part that needs attention. The browser is not something you pick freely at runtime; it is a consequence of the library version you pinned.
Adding the dependency, and the logging you have to supply
The dependency is an ordinary Maven artifact, and the README gives the Maven form:
<dependency>
<groupId>io.github.fanyong920</groupId>
<artifactId>jvppeteer</artifactId>
<version>3.6.5</version>
</dependency>For Gradle, the Maven Central repository is added to the repository list, with the entry given as mavenCentral(), and the dependency is then declared as:
compile "io.github.fanyong920:jvppeteer:3.6.5"There is a standalone jar as well, for anyone who does not use a dependency manager, linked from the releases page.
The logging note is short and easy to miss. The library uses SLF4J for logging and does not bundle any default logging implementation. The debugger sets the log level to Debug.
That combination is worth pausing on. If you add the dependency to a project with no SLF4J binding, the library produces no output at all, and the debug level that the debugger needs will not appear. For a library whose hardest problems are browser start-up and protocol mismatches, the missing log output is exactly what you will want. Adding a binding is therefore part of setting this up, not an optional extra.
The repository also ships an example directory with its own pom.xml and example sources, which is the fastest way to see a working launch configuration before writing your own.
Generating a PDF needs headless mode and a sandbox argument
The PDF example in the README is worth reading closely, because the required setup is unusual and the comments explain why.
The library's advice is that PDF printing must be configured with headless set to true, and that the --no-sandbox argument must be added, otherwise printing does not work, with a link to the Puppeteer issue that describes the same problem.
//pdf必须配置headless = true
launchOptions.setHeadless(true);
ArrayList<String> args = new ArrayList<>();//添加一些额外的启动参数
args.add("--no-sandbox");
launchOptions.setArgs(args);
Browser cdpBrowser = Puppeteer.launch(launchOptions);
Page page = cdpBrowser.newPage();
GoToOptions goToOptions = new GoToOptions();
goToOptions.setWaitUntil(Collections.singletonList(PuppeteerLifeCycle.NETWORKIDLE));
page.goTo("https://www.baidu.com/?tn=68018901_16_pg",goToOptions);
PDFOptions pdfOptions = new PDFOptions();
pdfOptions.setPath("baidu.pdf");
pdfOptions.setOutline(true);
pdfOptions.setFormat(PaperFormats.a4);
pdfOptions.setPrintBackground(true);
pdfOptions.setPreferCSSPageSize(false);
pdfOptions.setScale(1.1);
page.pdf(pdfOptions);
cdpBrowser.close();The structure is the Puppeteer one, which is the point of the port: launch options, a browser, a page, a navigation with a wait condition, an options object for the operation, then close.
Two of those lines carry behaviour you would otherwise discover the hard way. The navigation waits for the network to be idle, so the page is not captured mid-load. And the PDF options expose outline generation, paper format, background printing, CSS page size preference and a scale factor, which means the output is controllable rather than a default dump.
The README also notes that by default Page.pdf() waits for fonts to load, which matters for documents where the font arrives late.
One caveat to carry with you: the sandbox argument is presented as a requirement for printing, and disabling the sandbox is a decision with security consequences when the browser is pointed at untrusted content.
Screenshots cover full page and beyond the viewport
Screenshotting is handled by Page.screenshot() with a ScreenshotOptions object, and the two examples in the README show the options that matter.
@Test
public void test3() throws Exception {
Browser cdpBrowser = Puppeteer.launch(launchOptions);
Page page = cdpBrowser.newPage();
page.goTo("https://www.baidu.com/?tn=68018901_16_pg");
ScreenshotOptions screenshotOptions = new ScreenshotOptions();
screenshotOptions.setPath("baidu.png");
screenshotOptions.setOmitBackground(true);
//全屏截图
screenshotOptions.setFullPage(true);
//截图的更多
screenshotOptions.setCaptureBeyondViewport(true);
page.screenshot(screenshotOptions);
cdpBrowser.close();
}setFullPage captures the whole page rather than the visible viewport, and setCaptureBeyondViewport extends the capture area beyond the viewport. The two are separate switches, which matters because a long page and a page whose content overflows are different problems.
The second example changes the output format. setType with ImageType.JPEG switches the image type, and the comment notes that when the type is set explicitly the suffix in the path name no longer has any effect, so a path called baidu.png can still produce a JPEG.
setOmitBackground removes the default page background, which is the switch to reach for when a screenshot is going to be placed on a coloured surface and the white page background would show as a rectangle.
The rest is the same shape as the PDF example: launch, new page, navigate, build the options, take the shot, close the browser.
Where Jvppeteer is the wrong tool
The limitations are concentrated in two areas, and both are structural.
The first is browser parity. Chrome is controlled over DevTools and Firefox over WebDriver-bidi, and the README says plainly that WebDriver-bidi does not support all functions, with unsupported ones raising UnsupportedOperationException. A test suite that must run identically on both browsers is exactly the case this breaks, and the failure mode is an exception at runtime rather than a compile error, so the affected calls are discovered by running the suite.
The second is the browser version coupling. Because each Jvppeteer version binds a browser version, and because the fallback rule only tells you the closest previous version, an environment that already pins its own browser build can end up in a mismatch. The table shows the mapping changing with every minor release, so the browser in your CI image and the Jvppeteer version in your pom have to be managed together.
A third practical constraint is the dependency management for the browser itself. The README's quick start begins with downloading the browser, so the setup is not just adding a jar. There is a standalone jar for people who do not use a dependency manager, but the browser remains a separate step.
And the logging gap is worth repeating, because it is the one that costs you time when something goes wrong. SLF4J with no bundled implementation means a project without a binding runs the library silently.
On the positive side, the licence is Apache-2.0 with a LICENSE file at the root, the releases are regular with 3.6.3 on 2026-04-26, 3.6.4 on 2026-05-20 and 3.6.5 on 2026-07-12, and the last push was on 2026-10-04, so the library is still being worked on after its last tagged release.
Editorial conclusion
Java teams that want Puppeteer style browser automation without leaving the JVM should adopt Jvppeteer, because it offers Puppeteer style automation for Chrome while also exposing Firefox through WebDriver-bidi. It is the wrong tool if you need identical behaviour on both browsers, because Firefox only gets the BiDi subset and unsupported calls throw UnsupportedOperationException, and it is the wrong tool if you want a self-contained browser install, since the browser version is bound to the library version and has to be matched. Before adopting, check the version table for the browser your CI actually has, and remember that logging uses SLF4J with no implementation bundled, so a missing binding means no debug output at all.
Frequently asked questions
How do I add Jvppeteer to a Maven project?
Add the dependency with groupId io.github.fanyong920, artifactId jvppeteer and the version you want, for example 3.6.5. The artifact is published to Maven Central, and a standalone jar is also available from the releases page if you do not use a dependency manager.
Which browser version does my Jvppeteer version expect?
Each Jvppeteer version is bound to a browser version, and the README publishes the mapping table. The current 3.6.3 to 3.6.5 line is bound to Chrome for Testing 149.0.7798.0 and Firefox stable 149.0, and if no exact Jvppeteer version is listed the supported browser version is the one from the immediately preceding version.
Does Jvppeteer support Firefox the same way as Chrome?
Not exactly. Chrome is controlled through the DevTools protocol and Firefox through WebDriver-bidi, and the README states that WebDriver-bidi does not support all functions, with unsupported ones throwing UnsupportedOperationException.
Why do I not see any Jvppeteer log output?
The library logs through SLF4J and does not bundle a default logging implementation, so without an SLF4J binding in your project there is no output at all. The debugger sets the log level to Debug, so adding a binding is what makes that visible.
Official sources
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.
[](https://hysenlabs.com/projects/fanyong920-jvppeteer)Was this useful?