Zebkit – Chromium's engine as a library you link, not a runtime you live in

Hacker News by 21 min read 57x views
Zebkit – Chromium's engine as a library you link, not a runtime you live in

Share Post

Chrome as a archive — light, fast, everywhere, and easy.
One API on Linux, macOS and Windows. Add it in a few lines.

crates.io PyPI Engine release

zebkit is Chromium's motor as one archive you nexus into your own application: Blink, V8 alongside all JIT tier, PDFium, FFmpeg and the remainder of what Chrome is made of, alongside nothing of Chrome's browser and nothing of Electron's runtime. Your use stays yours, in C, C++, Rust, Python or JavaScript, alongside its own windows and toolkit. Where it needs the web, it adds a zebkit view; anywhere 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).

The use links one library, zebkit, which runs Chromium's satisfied layer, Blink and V8 inner the application's process; pages run in sandboxed helper processes; on Linux, macOS and Windows

  • Integrate it, don't build on it. Electron is a base: an application is built inner it, on its runtime, its windows and its packaging. zebkit is a part: an use adds it, as it adds SQLite, and keeps its process, its toolkit and its way of shipping. It runs inner the application's own event iteration (zebkit_init(), zebkit_pump()), and draws in the application's windows, as frames you diagram or in a kid of a window you provision it, an X11 window, an NSView or an HWND (examples/native-host), and gives rear the opening a leaf is in for the system's dialogs.
  • Take what you need. Web views, in a opening or off-screen alongside their frames handed to you; a complete PDF API; preservation what a leaf plays; your own URL schemes; native UI from JavaScript; Playwright's API and CDP for agents. Use one, or all.
  • The genuine Chrome engine. Pages see Chromium 157: its person delegate and client hints, window.chrome, popups blocked without a click, and nothing of a debugger attached (docs/API.md has what motionless differs, Google's sign-in among it).
  • Lighter than Electron. Against the latest Electron, 45.2.1: 34% smaller, a chilly commencement in 2.3 s against 6.6, a leaf in 29% small memory, and the DOM, text layout and JavaScript flat (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 inner the engine, about 7,490 functions on all of Linux, macOS and Windows (7,487 on all three, the rest all 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 container them twice.
  • PDF built in. A complete API on Chromium's PDFium: rendering and tiles, text alongside layout, search, outline, links, annotations as an publishing company has them (line endings, cloudy borders, liberated content alongside callouts and affluent text, stamps, replies and states, measurement, XFDF and FDF), forms, redaction, leaf editing, merging, attachments, metadata, and signatures checked for integrity; hooks for an application's own note kinds, appearances, events alongside undo, render layers, OCR, fonts, rely and actions. In C, Rust, Python and JavaScript.
  • 2D example and shaping. <zebkit/canvas.h> on the engine's Skia and <zebkit/text.h> on its HarfBuzz, without shipping either again.
  • Media, saved as it plays. Whatever a leaf plays, a file, MSE/DASH or HLS, written to MP4 or WebM as it was sent, without re-encoding and without a second download (<zebkit/media.h>).
  • Bytes as they are. A page's calls to the use go complete its frame's own Mojo channel, ample ones through shared memory: no base64, the page's JSON handed on as it was written, as accelerated as Electron's IPC for small calls and faster for ample ones.
  • The opening about a page, from JavaScript. zebkit.ui draws windows, prompts and dialogs alongside Chromium's views toolkit: signals, JSX, Tailwind classes, and automation for tests and agents. Rich UI is a page; zebkit.ui is the chrome about it (docs/UI.md).
  • Playwright's API, natively. The entire of Playwright (locators, actions that delay 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 complete CDP, and a click in 3 to 5 ms alternatively of 33 (<zebkit/automation.h>, docs/AUTOMATION.md). Playwright's own clients, in any of its languages, nexus to it unchanged with chromium.connect().
  • Made for agents. tools/zebkit-mcp gives them pages, PDFs, files, media and native windows as MCP tools, complete norm input and HTTP, inside bounds its controller sets (docs/MCP.md). They can additionally run zebkit through Playwright's API or complete CDP, Chromium's own DevTools server, headless or windowed.
  • Customise it from your code, downward to the desktop. Native hooks decide what the motor does, in C, Rust, Python and JavaScript: permissions, navigation, popups, dialogs, downloads, certificates and client certificates, sign-in, network requests and responses at all stage, settings at run time, your own URL schemes, what a leaf may call, scripts before the page's own (docs/ROADMAP_HOOKS.md). And everything a leaf or the motor would display the individual or ask of the scheme goes through the application: the window's example (system, overlay or none, alongside the leaf as the heading bar), menus and the environment menu, JavaScript dialogs and sign-in, file and equipment choosers, display 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 leaf has no zebkit entity unless the application grants it, per view, per base and per capability; the origin is the browser's, never the page's word; the renderer stays sandboxed; permissions a browser would ask concerning are not granted.
Engine Chromium 157.0.8103.38 (upstream.lock): satisfied layer, Blink, V8 alongside all 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

A bundle is a directory alongside the library, the helper, the engine's data and include/. Either unpack a release's archive (zebkit-<version>-<target>.tar.xz from GitHub's releases), or build one:

mise run r # dist/release (Linux), dist/release-macos (macOS), dist/release-windows; hours the archetypal time

Each archive additionally holds the tools, built for its scheme beside the library and prepared to run from anywhere it is unpacked: zebkit-run, zebkit-js and zebkit-mcp (.exe on Windows, sandboxed there too).

On an Apple silicon Mac alongside complete Xcode installed, scripts/dist.sh release builds the motor locally into dist/release. Then run scripts/example.sh macos-basic to build and initiate the C embedding demo in dist/example/Zebkit Embedded Browser.app.

Building needs concerning 30 GB for Chromium's tree (docs/BUILD.md). Below, $PKG is the bundle 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 archetypal leaf to a PNG and says its text, alongside PDFium and the depiction encoders inner zebkit, and nothing alternatively to install:

#include <stdio.h> #include <zebkit/pdf.h> #include <zebkit/services.h> /* Your program, your main(): zebkit is fair a archive 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 archetypal leaf as a PNG, at twice its size. */ zebkit_pdf_render_options options = {.scale = 2, .background = 0xffffffff}; int width, height; uint8_t *rgba = zebkit_pdf_render(pdf, 0, &options, &width, &height, &error); size_t size; uint8_t *png = zebkit_image_encode(ZEBKIT_IMAGE_PNG, rgba, width, height, 0, &size, &error); fwrite(png, 1, size, fopen("page1.png", "wb")); /* And its text. */ char *text = zebkit_pdf_text(pdf, 0, &error); printf("%d pages; leaf 1 says: %.80s\n", zebkit_pdf_page_count(pdf), text); zebkit_free(text), zebkit_free(png), zebkit_free(rgba); zebkit_pdf_close(pdf); return 0; }
cc thumb.c -I$PKG/include -L$PKG -l:libzebkit.so.1 -Wl,-rpath,$PKG -o thumb # Linux cc thumb.c -I$PKG/include -F$PKG -framework Zebkit -Wl,-rpath,$PKG -o thumb # macOS ./thumb report.pdf # 2 pages; leaf 1 says: Quarterly study ...

The PDF API, compression, crypto, URLs, depiction codecs, ICU and the libraries inner the motor (zebkit_vendor_*, FFmpeg's among them) need no motor iteration (docs/API.md); lone HTTP through the engine's network stack and web pages do.

Web pages need the motor running. Here the motor runs the loop: the program starts it alongside zebkit_main() and plant in its callbacks. A program with its own iteration (GTK, Qt, AppKit, winit) starts it alongside zebkit_init() and calls zebkit_pump() (examples/native-host).

#include <stdio.h> #include <zebkit/zebkit.h> static void printed(zebkit_view *view, const char *json, const char *error, void *data) { printf("%s\n", json ? json : error); zebkit_quit(); } static void loaded(zebkit_view *view, zebkit_load_event event, const char *url, void *data) { if (event == ZEBKIT_LOAD_FINISHED) zebkit_view_evaluate(view, "document.title", printed, NULL); } static void ready(void *data) { zebkit_view *view = zebkit_view_new("https://example.com/", 1024, 768); zebkit_view_on_load(view, loaded, NULL); } int main(int argc, char **argv) { return zebkit_main(argc, argv, ready, NULL); }
cc app.c -I$PKG/include -L$PKG -l:libzebkit.so.1 -Wl,-rpath,$PKG -o app # Linux cc app.c -I$PKG/include -F$PKG -framework Zebkit -Wl,-rpath,$PKG -o app # macOS clang-cl /MT app.c /I%PKG%\include %PKG%\zebkit.dll.lib %PKG%\zebkit_sandbox.lib # Windows ./app --remote-debugging-port=9222 # alongside CDP for Puppeteer and Playwright

On Windows the executable takes part in Chromium's sandbox: it links zebkit_sandbox.lib and calls zebkit_win_startup() archetypal in main() (docs/WINDOWS.md).

Without unprivileged person namespaces the motor refuses to commencement and says why: instal its helper, or in a receptacle of its own add --no-sandbox (docs/SANDBOX.md).

The leaf and the application

The use serves its own pages from a scheme and gives them functions to call; a leaf has nothing of zebkit unless it is granted.

/* The leaf calls zebkit.app.greet("Ada"). */ static void greet(zebkit_view *view, const char *origin, const char *args_json, zebkit_call *call, void *data) { char answer[256]; snprintf(answer, sizeof answer, "{\"hello\": %s}", args_json); zebkit_call_resolve(call, answer); } /* app://main/... from ./ui, in ranges for media. A genuine handler refuses "..". */ static void serve(zebkit_request *request, void *data) { char path[1024]; snprintf(path, sizeof path, "ui%s", zebkit_request_url(request) + sizeof "app://main" - 1); zebkit_request_respond_file(request, path, NULL); } static void closed(zebkit_view *view, void *data) { zebkit_quit(); } static void ready(void *data) { zebkit_view *view = zebkit_view_new("app://main/index.html", 1024, 768); zebkit_view_grant(view, "app://main", ZEBKIT_ALLOW_APP | ZEBKIT_ALLOW_PDF, NULL); zebkit_view_bind(view, "greet", greet, NULL); zebkit_view_on_close(view, closed, NULL); } int main(int argc, char **argv) { zebkit_scheme_register("app", ZEBKIT_SCHEME_STANDARD | ZEBKIT_SCHEME_SECURE | ZEBKIT_SCHEME_FETCH); zebkit_scheme_handle("app", serve, NULL); return zebkit_main(argc, argv, ready, NULL); }

In the page, all call is a commitment and bytes are Uint8Arrays:

const reply = await zebkit.app.greet('Ada'); // the application's function const pdf = await zebkit.pdf.open(await (await fetch('report.pdf')).bytes()); const rgba = await pdf.render(0, {scale: 2}); // a leaf as pixels const hits = await pdf.search('revenue'); const packed = await zebkit.compress('zstd', bytes, 19); const hash = await zebkit.crypto.digest('SHA-256', 'abc');

Each item the motor would display the person, or ask of the system, has a default that plant and a function of the application's that replaces it. Nothing reaches the scheme without a decision the use can take; without a function, a leaf gets what a careful browser gives it, and nothing at all anywhere a browser would ask.

import zebkit zebkit.scheme_register("app") # served by a scheme_handle(), as in the C example above zebkit.init(["app"]) # The leaf is the heading bar: the window's buttons complete it, dragged by its CSS. view = zebkit.View("app://main/index.html", 1000, 700, options={ "frame": "overlay", "controls": {"height": 40, "color": "#1b1d2a", "symbolColor": "#ffffff"}, "dragRegions": {"source": "css", "origins": ["app://main"]}}) # The application's list bar (macOS) and keys, alongside province that changes in place. zebkit.app_set_menu([{"title": "File", "items": [{"title": "Autosave", "id": "autosave", "checked": True}]}], lambda item: zebkit.app_update_menu_item(item, checked=False)) # A tray icon, the Dock's or the taskbar's badge, and the page's notifications as the application's. tray = zebkit.Tray(open("icon.png", "rb").read(), "My application") zebkit.app_set_badge("3") zebkit.on_notification(lambda event: print("show in my own UI:", event)) # What a leaf asks for: a USB device, a display to capture, a colour, a share. view.on_device_chooser(lambda request: request.respond(request.metadata["devices"][0]["id"])) view.on_media_access(lambda request: request.respond(True, None, "view")) view.on_share(lambda request: request.respond(True)) # The system: its theme and its changes, the session's lock, the screens. zebkit.on_environment_changed(lambda env: print("dark" if env["colorScheme"] == "dark" else "light")) zebkit.on_power_event(lambda event: print(event["event"])) # suspend, resume, lock, unlock print(zebkit.displays())
The default The application's
Window frame the system's overlay (Window Controls Overlay) or none, title, colours, drag regions, state, actions
Menus the list bar on macOS; the default environment menu items alongside province by id; the environment list replaced, extended or run
Dialogs the system's alerts; the engine's immediate and sign-in anywhere there is a window zebkit_view_on_dialog, on_http_auth, on_client_certificate, the eye dropper
Files and devices the system's document dialog; no device the document chooser and File System Access; WebUSB, WebHID and Web Serial choosers
Capture and media camera and microphone by permission; no screen getDisplayMedia()'s source: the perspective itself or the screen
Notifications undecided; afterward the system's own service shown in the application's UI, alongside clicks and closes rear to the page
Desktop none the tray, the Dock's and the taskbar's badge, advancement and attention, the Dock menu, Web Share, beginning URLs and folders
The system a ray page the system's dreary manner and difference followed live; power, fastener and display events; keeping awake

docs/SYSTEM_INTEGRATION.md has all surface, its default, its position on each scheme and why; docs/API.md has the calls in the four languages; examples/custom-titlebar is a opening whose heading bar is the page.

zebkit on crates.io, with zebkit-build to put the engine beside your program; the build downloads the motor for your scheme formerly and checks its SHA-256.

[dependencies] zebkit = "0.4.0" [build-dependencies] zebkit-build = "0.4.0"
// build.rs: puts the motor beside the executable fn main() { zebkit_build::bundle(); } // main.rs fn main() { std::process::exit(zebkit::run(|| { let perspective = zebkit::View::new(Some("https://example.com/"), 1024, 768); view.grant("https://example.com", zebkit::Allow::APP, None); view.bind("greet", |call| { let answer = format!("\"hello, {}\"", call.args_json()); call.resolve(&answer) }); view.on_close(zebkit::quit); })); }

ZEBKIT_DIR points the build at a bundle (bindings/rust/README.md).

zebkit on PyPI is the binding; the engine is the archive for your scheme from the releases of the identical version, with ZEBKIT_DIR pointing at it:

pip instal zebkit export ZEBKIT_DIR=/path/to/zebkit-0.4.0-x86_64-unknown-linux-gnu
import zebkit # clean Python on ctypes: nothing to compile def ready(): view = zebkit.View("https://example.com/") view.grant("https://example.com", zebkit.ALLOW_APP) view.bind("greet", lambda name, origin: f"hello, {name}") zebkit.main(ready) # the motor is established in $ZEBKIT_DIR

zebkit-js runs an ES component on the engine's V8, for applications written in JavaScript, alongside views, the identical APIs, and native windows:

// zebkit-js main.mjs const view = new zebkit.View('app://main/index.html', {width: 1024, height: 768}); view.grant('app://main', ['app', 'pdf']); view.bind('save', async (name, text) => { await zebkit.fs.writeFile(`${zebkit.args[0]}/${name}`, text); return {saved: true}; }); view.on('close', () => zebkit.quit());
// zebkit-js examples/ui/todo.mjs: a opening of native widgets, styled with // Tailwind's classes and kept up to date by signals (an excerpt) const {h, signal, computed, For, window} = zebkit.ui; const [tasks, setTasks] = signal([]); const done = computed(() => tasks().filter((t) => t.done).length); const Task = (task) => h('view', {class: 'flex-row items-center gap-3 p-3 rounded-xl bg-[#141a2e]'}, h('button', {class: 'w-8 h-8 p-0 rounded-full bg-[#7c5cff] text-white', onClick: () => toggle(task)}, task.done ? '✓' : ''), h('text', {class: 'grow text-[#e6e8f2]'}, task.text)); window({title: 'Today', width: 460, height: 680}, () => h('view', {class: 'flex-col gap-4 p-6 bg-[#0b1020]'}, h('text', {class: 'text-3xl font-bold text-white'}, 'Ship item great'), h('text', {class: 'text-sm text-[#8a91aa]'}, () => `${done()} of ${tasks().length} done`), h(For, {each: tasks}, Task)));

examples/ui/todo.mjs

Playwright's API runs inner the motor (docs/AUTOMATION.md): every command of Playwright's protocol, in the application's process, alongside no CDP and no Node.js. From C it is one call, zebkit_automation_call(view, "Frame.click", "{\"selector\": \"#go\"}", done, data); Python has it with Playwright's names:

import zebkit from zebkit.automation import Page, expect, run async def test(): page = Page() await page.goto("https://example.com/") await expect(page).to_have_title("Example Domain") await expect(page.get_by_text("documentation examples")).to_be_visible() await page.screenshot(path="example.png") zebkit.quit() zebkit.main(lambda: run(test()), ["python", "--headless"])

Playwright's own clients, its test runner and its another languages included, connect to the engine's Playwright endpoint unchanged:

tools/zebkit-run --headless --playwright-port=0 # prints "Playwright listening on ws://127.0.0.1:<port>/<token>"
const browser = await chromium.connect('ws://127.0.0.1:<port>/<token>'); const page = await (await browser.newContext()).newPage();

Agents and tools that conversation CDP run zebkit as they would run Chrome:

tools/zebkit-run --headless --remote-debugging-port=9222 https://example.com/

Any CDP client connects to http://127.0.0.1:9222.

An MCP client gets the engine's capabilities as tools from tools/zebkit-mcp, a separate program, alongside document admission and origins denied until its controller grants them (docs/MCP.md):

ZEBKIT_DIR=<package> cargo build --release --manifest-path tools/zebkit-mcp/Cargo.toml # or the archive's zebkit-mcp --allow-origin https://example.com --allow-write ~/agent-files # on norm input and output zebkit-mcp --http 8931 --allow-origin '*' # on 127.0.0.1, alongside a token
mise example:linux:basic # examples/window.c: a browser window mise example:rust:window # the identical in Rust mise example:ffmpeg # examples/ffmpeg.cpp: a archive inner the engine (cd examples/gpui-browser && cargo run --release) # a tabbed browser in GPUI-KIT

Against the latest stable Electron, 45.2.1 (Chromium 156), measured the identical way: one harness, the identical pages, two lean hosts that do the identical thing, all process counted, medians of 5 to 11 runs taking turns, Linux x86-64, 2026-11-06 and 07 (scripts/electron-compare.sh, docs/reports/electron-compare.md).

zebkit 0.2.0 Electron 45.2.1
As an use ships it, uncompressed / .tar.xz 171.2 / 59.4 MiB 260.5 / 87.1 MiB 34% smaller
Start, cold, to archetypal paint 2.3 s 6.6 s 66% less
Start, warm, to archetypal paint 116 ms 236 ms 51% less
Memory, a blank page 179 MB 250 MB 29% less
A call from the leaf to the presenter and back, 1 MiB / 16 MiB 3.3 / 58 ms 4.3 / 66 ms 23% / 12% less
DOM, 20,000 elements made and laid out 280 ms 278 ms level
JavaScript and DOM, ten workloads 1139 ms 1193 ms level
Text layout, a division of a book 8.1 ms 7.6 ms level, inside noise
A 756-page PDF in all one's viewer: CPU / memory 0.75 s / 261 MB 1.6 s / 399 MB 53% / 35% less
Ten famous sites: CPU loading / memory 21.7 s / 4756 MB 25.2 s / 5060 MB 14% / 6% less
Processes, a page 7 6 one more: retention sandboxed in its own, as Chrome
  • Size. zebkit keeps the entire web phase applications use: HTML, CSS, JavaScript alongside all JIT tier, WebAssembly, WebGL, media alongside H.264 and AAC, HTTP/3, PDF.
  • Speed. Chrome's own profile-guided optimization reaches Blink because zebkit is built alongside CFI as Chrome is; all speed alter is kept lone whenever it gains additional than it expenses in size (docs/SIZE_AND_SPEED.md).
  • Where Electron is ahead: one procedure small a page, and recollection on two of the ten sites, YouTube and The Verge, anywhere promotion and video decide.
  • How all figure is made: docs/SIZE_AND_SPEED.md.

The identical Playwright commands three ways, headless, medians (docs/reports/automation-bench.md, scripts/automation-bench.sh):

zebkit's API, in-process Your Playwright scripts, connected to zebkit Playwright alongside Chrome 156
locator.click() 2.0 ms 3.5 ms 33.3 ms
locator.fill() 2.1 ms 2.0 ms 2.9 ms
locator.press('Enter') 0.59 ms 0.98 ms 2.6 ms
locator.textContent() 0.23 ms 0.70 ms 0.81 ms
allTextContents() of 200 0.34 ms 1.9 ms 1.9 ms
page.goto() 11.2 ms 13.0 ms 18.2 ms
page.screenshot() 12.4 ms 16.7 ms 33.8 ms
page.screenshot({type: 'jpeg'}) 13.9 ms 14.4 ms 32.9 ms
the screenshot's pixels, unencoded 9.3 ms
  • zebkit's API, in-process: your program calls the command through <zebkit/automation.h>, Python's zebkit.automation or Rust's zebkit::automation; it runs inner the engine, alongside no Node.js and no protocol.
  • Your Playwright scripts, connected to zebkit: Playwright's own Node.js client, unchanged, alongside chromium.connect() to zebkit's endpoint; its test suite (v1.64.1) passes 4,046 of its tests there, Chrome 4,196 (docs/AUTOMATION.md, division 7).
  • Playwright alongside Chrome: Playwright as usual, complete CDP.
  • Why it is faster: one call in the renderer anywhere Playwright's server makes several circular trips complete CDP, no JSON between processes, no Node.js process (Playwright's solitary reached 175 MiB); and the frames a click's checks delay for are made at formerly alternatively of at 60 Hz on a leaf without a display.
  • A screenshot is 2.7 times faster: the caller example it takes is made at once alternatively of at the next 60 Hz tick, the PNG is deflated at flat 1 with the Up display (2 ms anywhere Chrome's default flat takes 13, for 59 KB instead of 40 KB on this page), and the picture's shared recollection is made in one call alternatively of a leaf error at a time. What is remaining of the 12 ms is the page's example (4 ms), copying the image out of the compositor (4 ms) and encoding it (4 ms). The pixels themselves, alongside no encoding (zebkit_automation_screenshot_pixels(), zebkit's own), obtain 9 ms. Over CDP zebkit does what Chrome does: frames at 60 Hz, Chrome's PNG.
Document What it covers
docs/API.md Everything an use can call, in C, Rust, Python and JavaScript
docs/BUILD.md Fetching Chromium, building, packaging, testing, measuring and releasing; profiles and patches
docs/ARCHITECTURE.md How the motor is made, and what in this repository is what
docs/AUTOMATION.md Playwright's API without CDP: how Playwright works, what zebkit does instead, the endpoint, what it costs
docs/MCP.md tools/zebkit-mcp: the motor as MCP tools for agents, its bounds, what is weak
docs/SIZE_AND_SPEED.md Where the size goes, what was cut and kept, the compiler against speed, the Electron baseline
docs/MACOS.md The macOS framework, native and cross builds
docs/WINDOWS.md The Windows DLL, its sandbox, cross-building on Linux, the province of the port
docs/SANDBOX.md The sandbox on all system, and operating without one
docs/ROADMAP.md The archive and the engine: requirements, what is done, what is next
docs/ROADMAP_HOOKS.md Hooks: how an use decides what the motor does, from native code
docs/UI.md zebkit.ui: the engine's own small UI, what it is for and what it is not
bindings/rust/README.md The Rust crates
docs/releases/ Each release: what is in it, what was tested, what is missing
docs/reports/ Size reports, regenerated by the scripts
Path What it holds
upstream.lock The Chromium publish built, the pinned depot_tools, the Electron publish measured against
profiles/ Build flavours as GN arguments: slim.gn (the product), slim-macos.gn, slim-windows.gn, baseline.gn (Chromium's defaults)
patches/ Changes to Chromium, applied in the command of patches/series
src/engine/ zebkit's own code, connected into Chromium as //zebkit/engine: the library, its C API and headers
src/ffmpeg/ zebkit's FFmpeg configuration, from scripts/ffmpeg-config.sh
bindings/rust/, bindings/python/ The Rust crates and the Python binding
tools/ zebkit-run (open pages, assist CDP or Playwright's endpoint), zebkit-js (applications in JavaScript) and zebkit-mcp (the motor as MCP tools)
tests/ Programs that test all tier of the API against a package; speed workloads
examples/ A browser opening in C, zebkit.ui, a archive inner the engine, the Electron baseline
scripts/ Every step, one manuscript each; mise tasks lists the abbreviated forms

upstream/ (Chromium's tree, concerning 30 GB), out/, dist/ and .cache/ are generated and not tracked.

zebkit is Chromium affirmative a small place set (patches/), built from source. Where Chromium lacks item an use needs, zebkit patches Chromium fairly than operating about it (docs/BUILD.md).

Other Article Hacker News
↑
Close Right Ads
Close Left Ads