puregocef

package module
v0.14.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: MIT Imports: 0 Imported by: 0

README

purego-cef

Go bindings for the Chromium Embedded Framework C API, using purego instead of cgo.

Linux only. CGO_ENABLED=0.

[!NOTE] purego-cef is usable today, but it is still pre-1.0. Expect API changes while the handwritten cef layer settles.

Status

purego-cef exposes the CEF C API through generated bindings and adds a smaller handwritten cef layer for the common paths.

What to expect today:

  • generated low-level bindings across the CEF C API
  • a smaller ergonomic cef layer for init, clients, and common handlers
  • shipped mocks for testing
  • ongoing API cleanup before 1.0

Architecture

The binding layer is generated from CEF C headers (~114 files). The generator parses all headers and produces:

  • Inbound port interfaces for every CEF handler and type
  • Outbound port interfaces grouping CEF free functions and object methods by domain
  • A composite CAPI interface embedding all outbound ports
  • Typed constructors for handlers and wrappers for CEF objects with automatic refcount management
  • C struct layouts and purego symbol registration
  • Doc comments extracted from CEF C headers

The public cef package then adds a small handwritten layer for the places where the raw C API is too awkward to expose directly.

A hand-written core domain handles UTF-16 string conversion, reference counting, CEF lifecycle orchestration, and the Bridge adapter implementing the CAPI interface.

Mocks for all interfaces are generated by Mockery v3 and shipped in cef/mocks/.

API shape

For most code, prefer the ergonomic handwritten layer when it exists:

  • cef.Settings instead of cef.RawSettings
  • cef.NewClient(...) with cef.Client
  • cef.NewLifeSpanHandler(...) with cef.LifeSpanHandler
  • cef.NewAudioHandler(...) with the decoded cef.AudioHandler interface
  • cef.ExecuteSubprocess() when you want subprocess status and errors without implicit os.Exit or stderr writes; cef.MaybeExitSubprocess() remains the short helper for main packages
  • cef.ExecuteSubprocessWithApp(app) when helper subprocess startup also needs a custom cef.App
  • cef.LifeSpanHandler popup callbacks receive a callback-scoped *cef.RawClientWriteSlot when CEF exposes a writable popup client out-param; check for nil before calling Set or Clear

Treat Raw* types as advanced escape hatches.

Usage

For main packages, cef.MaybeExitSubprocess() is the short path. If you need explicit subprocess status and error handling, use cef.ExecuteSubprocess() or cef.ExecuteSubprocessWithApp(app).

package main

import (
	"runtime"

	"github.com/bnema/purego-cef/cef"
)

func main() {
	runtime.LockOSThread()
	cef.MaybeExitSubprocess()

	if err := cef.Init(cef.DefaultSettings()); err != nil {
		panic(err)
	}
	defer cef.Shutdown()

	client := cef.NewClient(myClient{})
	_ = client

	// Your render loop here
	for {
		cef.DoMessageLoopWork()
	}
}

// Implement the user-facing client interface — only the methods you need.
type myClient struct{}

func (c myClient) GetLifeSpanHandler() cef.LifeSpanHandler { return nil }
func (c myClient) GetRenderHandler() cef.RenderHandler     { return myRenderer{} }
// ... other handler getters return nil

Requirements

  • Go 1.26+
  • CEF 150 runtime (the minimum accepted Chrome/CEF major; earlier versions are rejected at load time)

Runtime discovery

purego-cef locates libcef.so using this order:

  1. CEF_DIR environment variable
  2. Explicit Settings.CEFDir argument passed to cef.Init()
  3. /usr/lib/cef (the Arch Linux cef package install path), if libcef.so exists there
  4. ~/.local/share/cef
Arch Linux
sudo pacman -S cef

This installs /usr/lib/cef/libcef.so and the required Resources — no env var needed.

Runtime diagnostics
  • CEF_SKIP_VERSION_CHECK=1 bypasses the major-version guard only (diagnostics only; API 15000 hash validation always applies).

Building

CGO_ENABLED=0 go build ./...
CGO_ENABLED=0 go test ./...

Integration tests need the CEF runtime (adjust the directory as needed):

go test -tags=cef_integration ./integration

If your runtime is in a non-standard location, set CEF_DIR:

CEF_DIR=/custom/path go test -tags=cef_integration ./integration

Regenerating bindings

CEF_HEADERS=/usr/include/cef/include go generate ./...

Or manually:

go run ./cmd/cefgen \
  --headers-dir /usr/include/cef/include \
  --capi-dir internal/capi \
  --port-in-dir internal/ports/in \
  --port-out-dir internal/ports/out \
  --public-dir cef
mockery

Project layout

cef/                 public API (generated) + mocks
  bridge.go          hand-written: handler constructors, string helpers
  init.go            hand-written: Init(), Shutdown(), orchestration
internal/
  ports/in/          inbound port interfaces (generated)
  ports/out/         outbound port interfaces (generated) + composite CAPI (hand-written) + mocks
  core/              domain logic: engine, string marshaling, refcount (hand-written)
  capi/              purego bindings + bridge (generated + hand-written)
  loader/            dlopen libcef.so + version validation (hand-written)
cmd/cefgen/          binding generator (parser, model, emitter, templates)
integration/         integration tests (require CEF runtime)

License

MIT

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cef
bridge.go provides package-level helper functions that delegate to the core Engine.
bridge.go provides package-level helper functions that delegate to the core Engine.
cmd
cefgen command
internal
capi
bridge.go implements portout.CAPI using purego bindings.
bridge.go implements portout.CAPI using purego bindings.
cefapi
Package cefapi defines the generated CEF ABI contract shared by generation and loading.
Package cefapi defines the generated CEF ABI contract shared by generation and loading.
core
internal/core/engine.go
internal/core/engine.go
loader
internal/loader/loader.go
internal/loader/loader.go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL