Skip to content

headerkit

A C/C++ header parsing toolkit with pluggable backends and writers.

headerkit parses C and C++ header files into a language-agnostic Intermediate Representation (IR), then transforms that IR into various output formats. Use it to generate FFI bindings, serialize header metadata to JSON, or build your own custom code generators.

Key Features

  • Pluggable parser backends -- swap between parsing implementations (libclang ships built-in) without changing your code
  • Dataclass-based IR -- a clean, inspectable Python representation of C/C++ declarations: structs, functions, enums, typedefs, and more
  • Pluggable output writers -- generate CFFI bindings, ctypes modules, Cython .pxd files, LuaJIT FFI bindings, JSON, API diffs, LLM-optimized prompts, or write your own writer for any target format
  • Registry pattern -- backends and writers self-register, making the system extensible without modifying core code

Quick Example

from headerkit import get_backend, get_writer

# Parse a C header
backend = get_backend()
header = backend.parse(
    open("mylib.h").read(),
    "mylib.h",
)

# Generate CFFI bindings (default writer)
writer = get_writer("cffi")
cdef_source = writer.write(header)

# Or pick another built-in writer
ctypes_writer = get_writer("ctypes")      # Python ctypes bindings
cython_writer = get_writer("cython")      # Cython .pxd declarations
lua_writer = get_writer("lua")            # LuaJIT FFI bindings
json_writer = get_writer("json", indent=2)  # JSON for inspection
prompt_writer = get_writer("prompt")      # Token-optimized LLM context

print(json_writer.write(header))

How It Works

graph LR
    A["C/C++ Header"] --> B["Backend"]
    B --> C["IR"]
    C --> D["Writer"]
    D --> E["Output"]
    B -.- B1["ParserBackend<br>Protocol"]
    D -.- D1["WriterBackend<br>Protocol"]
  1. A backend (e.g., LibclangBackend, TreeSitterBackend) parses source code and produces a normalized SourceUnit containing typed declarations.
  2. A writer (inheriting from BaseWriter, such as CtypesWriter, CffiWriter, MojoWriter, NimWriter, CshimWriter, etc.) consumes the IR and produces single-file bindings or scaffolds full multi-file packages.

Backends and writers self-register via unified hooks and Python entry points, so you can add new source languages or output formats without modifying HeaderKit itself.

Next Steps