Back to Skills

implementing-jsc-classes-zig

verified

Creates JavaScript classes using Bun's Zig bindings generator (.classes.ts). Use when implementing new JS APIs in Zig with JSC integration.

View on GitHub

Repository
Verified Org

oven-sh/bun
86.7kstars

.claude/skills/implementing-jsc-classes-zig/SKILL.md

Last Verified

January 25, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/oven-sh/bun/blob/70fe76209b79b5280fd6c5641ef5814e8fa5ee0d/.claude/skills/implementing-jsc-classes-zig/SKILL.md -a claude-code --skill implementing-jsc-classes-zig

Installation paths:

Claude
.claude/skills/implementing-jsc-classes-zig/
Powered by add-skill CLI

Instructions

# Bun's JavaScriptCore Class Bindings Generator

Bridge JavaScript and Zig through `.classes.ts` definitions and Zig implementations.

## Architecture

1. **Zig Implementation** (.zig files)
2. **JavaScript Interface Definition** (.classes.ts files)
3. **Generated Code** (C++/Zig files connecting them)

## Class Definition (.classes.ts)

```typescript
define({
  name: "TextDecoder",
  constructor: true,
  JSType: "object",
  finalize: true,
  proto: {
    decode: { args: 1 },
    encoding: { getter: true, cache: true },
    fatal: { getter: true },
  },
});
```

Options:

- `name`: Class name
- `constructor`: Has public constructor
- `JSType`: "object", "function", etc.
- `finalize`: Needs cleanup
- `proto`: Properties/methods
- `cache`: Cache property values via WriteBarrier

## Zig Implementation

```zig
pub const TextDecoder = struct {
    pub const js = JSC.Codegen.JSTextDecoder;
    pub const toJS = js.toJS;
    pub const fromJS = js.fromJS;
    pub const fromJSDirect = js.fromJSDirect;

    encoding: []const u8,
    fatal: bool,

    pub fn constructor(
        globalObject: *JSGlobalObject,
        callFrame: *JSC.CallFrame,
    ) bun.JSError!*TextDecoder {
        return bun.new(TextDecoder, .{ .encoding = "utf-8", .fatal = false });
    }

    pub fn decode(
        this: *TextDecoder,
        globalObject: *JSGlobalObject,
        callFrame: *JSC.CallFrame,
    ) bun.JSError!JSC.JSValue {
        const args = callFrame.arguments();
        if (args.len < 1 or args.ptr[0].isUndefinedOrNull()) {
            return globalObject.throw("Input cannot be null", .{});
        }
        return JSC.JSValue.jsString(globalObject, "result");
    }

    pub fn getEncoding(this: *TextDecoder, globalObject: *JSGlobalObject) JSC.JSValue {
        return JSC.JSValue.createStringFromUTF8(globalObject, this.encoding);
    }

    fn deinit(this: *TextDecoder) void {
        // Release resources
    }

    pub fn finalize(this: *TextDecoder) void {
        this.deinit();
     

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
4660 chars