Katherine oversees editorial operations across all six brands. Before joining The Meridan Group, she spent 14 years at the Minneapolis Star Tribune, where she led the metro desk through its digital transformation. She holds a Master's in Journalism from Northwestern's Medill School.
Chrome as a library — light, fast, everywhere, and easy.
One API on Linux, macOS and Windows. Add it in a few lines.
Introduction
zebkit is Chromium's engine as one library you link into your own
application: Blink, V8 with every JIT tier, PDFium, FFmpeg and the rest of
what Chrome is made of, with nothing of Chrome's browser and nothing of
Electron's runtime. Your application stays yours, in C, C++, Rust, Python
or JavaScript, with its own windows and toolkit. Where it needs the web,
it adds a zebkit view; where it needs a PDF, media, compression or crypto,
it calls zebkit's API: in C, or through the bindings for Rust, Python and
JavaScript (
zebkit-js
, and
zebkit.*
in the application's own pages).
Integrate it, don't build on it.
Electron is a base: an application
is built inside it, on its runtime, its windows and its packaging.
zebkit is a part: an application adds it, as it adds SQLite, and keeps
its process, its toolkit and its way of shipping. It runs inside the
application's own event loop (
zebkit_init()
,
zebkit_pump()
), and draws
in the application's windows, as frames you draw or in a child of a window
you give it, an X11 window, an
NSView
or an
HWND
(
examples/native-host
),
and gives back the window a page is in for the system's dialogs.
Take what you need.
Web views, in a window or off-screen with their
frames handed to you; a full PDF API; saving what a page plays; your own
URL schemes; native UI from JavaScript; Playwright's API and CDP for
agents. Use one, or all.
The real Chrome engine.
Pages see Chromium 157: its user agent and
client hints,
window.chrome
, popups blocked without a click, and
nothing of a debugger attached (
docs/API.md
has what still differs,
Google's sign-in among it).
Lighter than Electron.
Against the latest Electron, 45.2.1: 34% smaller,
a cold start in 2.3 s against 6.6, a page in 29% less memory, and the DOM, text
layout and JavaScript level (
Benchmark
).
No Node.
No second JavaScript runtime and no IPC through one. The
application is native code, or JavaScript run by
zebkit-js
on the
engine's V8.
Chromium's libraries are yours.
17 C libraries inside the engine, about
7,490 functions on each of Linux, macOS and Windows (7,487 on all three, the
rest each system's own), exported under
zebkit_vendor_*
: SQLite, LevelDB, BoringSSL,
zlib, Zstandard, Brotli, ICU, HarfBuzz, libxml2, libwebp, libjpeg-turbo,
FFmpeg, dav1d, Opus, libvpx, FreeType and PDFium. You do not ship them twice.
PDF built in.
A full API on Chromium's PDFium: rendering and tiles,
text with layout, search, outline, links, annotations as an editor has them
(line endings, cloudy borders, free text with callouts and rich text, stamps,
replies and states, measurement, XFDF and FDF), forms, redaction, page editing,
merging, attachments, metadata, and signatures checked for integrity; hooks for
an application's own annotation kinds, appearances, events with undo, render
layers, OCR, fonts, trust and actions. In C, Rust, Python and JavaScript.
2D drawing and shaping.
on the engine's Skia and
on its HarfBuzz, without shipping either again.
Media, saved as it plays.
Whatever a page plays, a file, MSE/DASH or
HLS, written to MP4 or WebM as it was sent, without re-encoding and
without a second download (
).
Bytes as they are.
A page's calls to the application go over its
frame's own Mojo channel, large ones through shared memory: no base64, the
page's JSON handed on as it was written, as fast as Electron's IPC for small
calls and faster for large ones.
The window around a page, from JavaScript.
zebkit.ui
draws
windows, prompts and dialogs with Chromium's views toolkit: signals,
JSX, Tailwind classes, and automation for tests and agents. Rich UI is
a page;
zebkit.ui
is the chrome around it (
docs/UI.md
).
Playwright's API, natively.
The whole of Playwright (locators,
actions that wait until they can be done, keyboard, mouse and touch,
routes, dialogs, downloads, contexts, workers, traces, HAR, video) runs
inside the engine, without CDP or a Node.js driver: 3 to 10 times faster
than Playwright over CDP, and a click in 3 to 5 ms instead of 33
(
,
docs/AUTOMATION.md
). Playwright's own
clients, in any of its languages, connect to it unchanged with
chromium.connect()
.
Made for agents.
tools/zebkit-mcp
gives them pages, PDFs, files, media
and native windows as MCP tools, over standard input and HTTP, within bounds
its operator sets (
docs/MCP.md
). They can also drive zebkit through
Playwright's API or over CDP, Chromium's own DevTools server, headless or
windowed.
Customise it from your code, down to the desktop.
Native hooks decide
what the engine does, in C, Rust, Python and JavaScript: permissions,
navigation, popups, dialogs, downloads, certificates and client
certificates, sign-in, network requests and responses at every stage,
settings at run time, your own URL schemes, what a page may call, scripts
before the page's own (
docs/ROADMAP_HOOKS.md
). And everything a page or
the engine would show the person or ask of the system goes through the
application: the window's frame (system, overlay or none, with the page as
the title bar), menus and the context menu, JavaScript dialogs and sign-in,
file and device choosers, screen capture, notifications, the tray, the
Dock and taskbar, sharing, the system's theme, power and displays
(
Fit it into the desktop
,
docs/SYSTEM_INTEGRATION.md
).
Safe by default.
A page has no
zebkit
object unless the
application grants it, per view, per origin and per capability; the
origin is the browser's, never the page's word; the renderer stays
sandboxed; permissions a browser would ask about are not granted.
Engine
Chromium 157.0.8103.38 (
upstream.lock
): content layer, Blink, V8 with every JIT tier
Linux
x86-64, glibc 2.17 or newer (CentOS 7 and later), X11 and (
--ozone-platform=wayland
) Wayland:
libzebkit.so.1
and
zebkit-helper
macOS
Apple silicon:
Zebkit.framework
, built natively or cross-built on Linux (
docs/MACOS.md
)
Windows
x64, Windows 10 or newer:
zebkit.dll
and
zebkit-helper.exe
, cross-built on Linux (
docs/WINDOWS.md
)
Version
VERSION
: 0.4.0
Quick start
Get the engine
A package is a directory with the library, the helper, the engine's data
and
include/
. Either unpack a release's archive
(
zebkit--.tar.xz
from GitHub's releases), or build one:
mise run r
#
dist/release (Linux), dist/release-macos (macOS), dist/release-windows; hours the first time
Each archive also holds the tools, built for its system beside the library
and ready to run from where it is unpacked:
zebkit-run
,
zebkit-js
and
zebkit-mcp
(
.exe
on Windows, sandboxed there too).
On an Apple silicon Mac with full Xcode installed,
scripts/dist.sh release
builds the engine locally into
dist/release
. Then run
scripts/example.sh macos-basic
to build and launch the C embedding demo
in
dist/example/Zebkit Embedded Browser.app
.
Building needs about 30 GB for Chromium's tree (
docs/BUILD.md
). Below,
$PKG
is the package directory.
Add it to a program you already have
zebkit is a library: your program keeps its
main()
and calls it. This
one renders a PDF's first page to a PNG and reads its text, with PDFium
and the image encoders inside zebkit, and nothing else to install:
#include
#include
#include
/* Your program, your main(): zebkit is just a library it calls. */
int
main
(
int
argc
,
char
*
*
argv
) {
char
*
error
=
NULL
;
zebkit_pdf
*
pdf
=
zebkit_pdf_open_file
(
argv
[
1
],
NULL
,
&
error
);
if
(!
pdf
) {
fprintf
(
stderr
,
"%s\n"
,
error
);
return
1
;
}
/* The first page as a PNG, at twice its size. */
zebkit_pdf_render_options
options
=