SkillAgentSearch skills...

Quickjs

CGO-free Go bindings for QuickJS-ng, a modern ES2023+ JavaScript engine. Uses WebAssembly and wazero for pure Go execution without any C dependencies.

Install / Use

/learn @Gaurav-Gosain/Quickjs
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

quickjs

CGO-free Go bindings for QuickJS-ng, a modern ES2023+ JavaScript engine.

Uses WebAssembly and wazero for pure Go execution without any C dependencies.

qjs-repl.jpg

Features

  • No CGO required
  • ES2023+ support (classes, async/await, Promises, BigInt, modules)
  • Cross-platform (Linux, macOS, Windows, any platform wazero supports)
  • Thread-safe
  • Go function bindings
  • Full type support (primitives, objects, arrays, functions)

Installation

go get github.com/Gaurav-Gosain/quickjs

Requires Go 1.21 or later.

Usage

package main

import (
    "fmt"
    "log"

    "github.com/Gaurav-Gosain/quickjs"
)

func main() {
    rt, err := quickjs.NewRuntime()
    if err != nil {
        log.Fatal(err)
    }
    defer rt.Close()

    ctx, err := rt.NewContext()
    if err != nil {
        log.Fatal(err)
    }
    defer ctx.Close()

    result, err := ctx.Eval("1 + 2")
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(result.String()) // 3
}

Go Function Bindings

fn := ctx.Function("add", func(ctx *quickjs.Context, this quickjs.Value, args []quickjs.Value) quickjs.Value {
    a, _ := args[0].Int32()
    b, _ := args[1].Int32()
    return ctx.Int32(a + b)
})
ctx.SetGlobal("add", fn)

result, _ := ctx.Eval("add(2, 3)")
fmt.Println(result.String()) // 5

Objects

obj := ctx.Object()
obj.Set("name", ctx.String("Alice"))
obj.Set("age", ctx.Int32(30))
ctx.SetGlobal("person", obj)

result, _ := ctx.Eval("person.name + ' is ' + person.age")
fmt.Println(result.String()) // Alice is 30

Error Handling

result, err := ctx.Eval("throw new Error('failed')")
if err != nil {
    fmt.Println("Error:", err)
}

result, err = ctx.Eval("syntax error {")
if err != nil {
    fmt.Println("Syntax error:", err)
}

Concurrency

The library is thread-safe. Multiple goroutines can use the same runtime:

rt, _ := quickjs.NewRuntime()
defer rt.Close()

var wg sync.WaitGroup
for i := range 10 {
    wg.Add(1)
    go func(n int) {
        defer wg.Done()
        ctx, _ := rt.NewContext()
        defer ctx.Close()
        result, _ := ctx.Eval(fmt.Sprintf("%d * %d", n, n))
        fmt.Printf("%d^2 = %s\n", n, result.String())
    }(i)
}
wg.Wait()

API

Runtime

rt, err := quickjs.NewRuntime()
rt.Close() error
rt.NewContext() (*Context, error)
rt.RunGC() error
rt.SetMemoryLimit(limit uint32) error

Context

ctx.Eval(code string) (Value, error)
ctx.EvalFile(filename string) (Value, error)
ctx.Close() error

// Value constructors
ctx.Null() Value
ctx.Undefined() Value
ctx.Bool(v bool) Value
ctx.Int32(v int32) Value
ctx.Int64(v int64) Value
ctx.Float64(v float64) Value
ctx.String(v string) Value
ctx.Object() Value
ctx.Array() Value
ctx.Error(msg string) Value
ctx.Function(name string, fn GoFunc) Value

// Globals
ctx.Global() (Value, error)
ctx.SetGlobal(name string, value Value) error

Value

// Type checking
v.IsNull() bool
v.IsUndefined() bool
v.IsBool() bool
v.IsNumber() bool
v.IsString() bool
v.IsObject() bool
v.IsArray() bool
v.IsFunction() bool
v.IsError() bool

// Conversion
v.Bool() (bool, error)
v.Int32() (int32, error)
v.Int64() (int64, error)
v.Float64() (float64, error)
v.String() string
v.Len() int

// Object/Array access
v.Get(key string) (Value, error)
v.Set(key string, value Value) error
v.GetIdx(idx int) (Value, error)
v.SetIdx(idx int, value Value) error

// Function calls
v.Call(thisArg Value, args ...Value) (Value, error)

Benchmarks

go test -bench=. -benchmem

Examples

See the examples/ directory:

  • basic - Basic evaluation and types
  • gofunc - Go function bindings
  • json - JSON parsing
  • es6 - ES6+ features
  • objects - Object manipulation
  • errors - Error handling
  • concurrent - Concurrent usage

REPL

go run ./cmd/qjs

Requirements

  • Go 1.21+
  • No CGO (pure Go)
  • No external dependencies beyond wazero

Limitations

  • TinyGo is not supported (wazero requires syscall interfaces not available in TinyGo)

License

MIT

View on GitHub
GitHub Stars6
CategoryDevelopment
Updated2mo ago
Forks0

Languages

C

Security Score

85/100

Audited on Jan 29, 2026

No findings