Matheus Sampaio Queiroga 813d742aff Add docs and remove threadsafe_function
- Add new function to ValueType conversion
- Add more docs to functions and minor changes
- rename entry to module
- don't expose Value and Env structs.

Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
2025-05-17 01:36:40 -03:00
2025-05-17 01:36:40 -03:00

napi-go

A Go library for building Node.js Native Addons using Node-API.

Important

This module require CGO, to cross-compile check cgo documentation.

My recommendation is to use a Linux distribution with the GCC installed together with the Required Destinations, or use zig(C: zig cc -target <target>, C++: zig c++ -target <target>)

Usage

Get module with go get -u sirherobrine23.com.br/Sirherobrine23/napi-go@latest

register function to export values on module start, example

package main

import (
	"encoding/json"
	"net/netip"
	_ "unsafe"

	"sirherobrine23.com.br/Sirherobrine23/napi-go"
	_ "sirherobrine23.com.br/Sirherobrine23/napi-go/module"
	"sirherobrine23.com.br/Sirherobrine23/napi-go/js"
)

type Test struct {
	Int    int
	String string
	Sub    []any
}

//go:linkname RegisterNapi sirherobrine23.com.br/Sirherobrine23/napi-go/entry.Register
func RegisterNapi(env napi.EnvType, export *napi.Object) {
	inNode, _ := napi.CreateString(env, "from golang napi string")
	inNode2, _ := napi.CopyBuffer(env, []byte{1, 0, 244, 21})
	toGoReflect := &Test{
		Int:    14,
		String: "From golang",
		Sub: []any{
			1,
			[]string{"test", "gopher"},
			[]bool{false, true},
			[]int{23, 244, 10, 2024, 2025, 2000},
			map[string]string{"exampleMap": "test"},
			map[int]string{1: "one"},
			map[bool]string{false: "false", true: "true"},
			map[[2]string]string{{"go"}: "example"},
			netip.IPv4Unspecified(),
			netip.IPv6Unspecified(),
			netip.AddrPortFrom(netip.IPv6Unspecified(), 19132),
			nil,
			true,
			false,
			inNode,
			inNode2,
			func() {
				println("called in go")
			},
		},
	}

	napiStruct, err := js.ValueOf(env, toGoReflect)
	if err != nil {
		panic(err)
	}
	export.Set("goStruct", napiStruct)

	fnCall, err := js.GoFuncOf(env, func(call ...any) (string, error) {
		d, err := json.MarshalIndent(call, "", "  ")
		if err == nil {
			println(string(d))
		}
		return string(d), err
	})
	if err != nil {
		panic(err)
	}
	export.Set("printAny", fnCall)

	fnCallStruct, err := js.GoFuncOf(env, func(call ...Test) (string, error) {
		d, err := json.MarshalIndent(call, "", "  ")
		if err == nil {
			println(string(d))
		}
		return string(d), err
	})
	if err != nil {
		panic(err)
	}
	export.Set("printTestStruct", fnCallStruct)
}

func main() {}

Finally, build the Node.js addon using go build:

go build -buildmode=c-shared -o "example.node" .

se more examples in internal/examples

Go bind

Now there are some new functions that convert values from Golang to JavaScript and Versa-Versa.

They are the:

  • ValueOf: Convert go values to Javascript values.
  • ValueFrom Convert Javascript values to Golang values.

From Go to Javascript:

  • Function
  • Struct, Map
  • Slice and Array
  • String
  • Int*, Uint* and Float
  • Boolean
  • Interface (interface if is any and not nil)
  • Promise
    • Async Worker
    • Thread safe function
  • Array buffer
  • Dataview
  • Typed Array
  • Class

Convert from Javascript values to Go

  • Struct, Map
  • Slice and Array
  • String
  • Int*, Uint* and Float
  • Boolean
  • Interface (if is any set types map[string]any, []any or primitive values)
  • Array buffer
  • Typed Array
  • Dataview
  • Function
  • Class
Description
Go library for building Node.js Native Addons using Node-API
Readme MIT 532 KiB
Languages
Go 99.7%
C 0.3%