{"id":15136246,"url":"https://github.com/rosbit/duktape-bridge","last_synced_at":"2025-10-23T11:31:21.818Z","repository":{"id":57487620,"uuid":"157183436","full_name":"rosbit/duktape-bridge","owner":"rosbit","description":"A very easy-to-use wrapper of Duktape JavaScript engine,  including wrappers for C, Go and Java. The bridge wrapper is also supporting module loader for loading modules written in JS, C and Go. This package is not a binding implementation, it is aimed to be used easily","archived":false,"fork":false,"pushed_at":"2021-12-20T10:07:26.000Z","size":963,"stargazers_count":13,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-01-30T18:05:43.969Z","etag":null,"topics":["c","duktape","easy-to-use","embedding","golang","java","javascript"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rosbit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-12T08:52:46.000Z","updated_at":"2024-01-12T17:41:37.000Z","dependencies_parsed_at":"2022-08-29T11:00:30.581Z","dependency_job_id":null,"html_url":"https://github.com/rosbit/duktape-bridge","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosbit%2Fduktape-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosbit%2Fduktape-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosbit%2Fduktape-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosbit%2Fduktape-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rosbit","download_url":"https://codeload.github.com/rosbit/duktape-bridge/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237821462,"owners_count":19371759,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","duktape","easy-to-use","embedding","golang","java","javascript"],"created_at":"2024-09-26T06:04:40.812Z","updated_at":"2025-10-23T11:31:16.018Z","avatar_url":"https://github.com/rosbit.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Duktape bridge for C, Go(Golang) and Java.\n\n[Duktape](http://duktape.org/index.html) is a thin, embeddable javascript engine.\nIts [api](http://duktape.org/api.html) is very well documented. For most of developers\nwho are not familiar with C language, it is very tedious to call duk\\_push\\_xxx() and\nduk\\_pop() to make use of the power of Duktape. Though there are some binding\nimplementations of Duktape for languages other than C, most of them inherit the\nmethods of using API of Duktape.\n\nThis package is intended to implement a wrapper called duk-bridge in C, and on top of\nthe C bridge, wrappers in Go and Java are implemented. All of the bridge wrappers\nprovide very common functions just like Eval(), CallFunc(), RegisterGoFunc().\nSo even without any Duktape knowledge, one can embed Duktape to an application.\n\nWhat's more, Go functions registered to be called in JS are common Go functions.\nGiven a logic function written in Go, the Go bridge will convert arguments of\nJavaScript code to those of Go function, call the Go function and convert the result\nfrom Go function to JavaScript function.\n\nThe Go bridge can also make your Go package to a Duktape JavaScript module. So\nwhat you can do is just writing `var mod = require('your_module')`, your Go package is\nready to be called by JS. See sample application [jsgo](https://github.com/rosbit/jsgo),\nwhich is a **standalone** executable, but can be used as a **js interpreter** or even\na mini node.js container.\n\n### Usage\n\nThe package is fully go-getable, no need to install any external C libraries. \nSo, just type\n\n  `go get github.com/rosbit/duktape-bridge/duk-bridge-go`\n\nto install.\n\n```go\npackage main\n\nimport \"fmt\"\nimport js \"github.com/rosbit/duktape-bridge/duk-bridge-go\"\n\nfunc main() {\n  ctx := js.NewEnv(nil)\n  defer ctx.Destroy()\n\n  res, _ := ctx.Eval(\"2 + 3\")\n  fmt.Println(\"result is:\", res)\n\n  /*\n  // or run a js file\n  res, _ := ctx.EvalFile(\"filename.js\")\n  fmt.Println(\"result is:\", res)\n  */\n}\n```\n\n### Go calls JavaScript function\n\nSuppose there's a js file named `a.js` like this:\n\n```js\nfunction test() {\n        var prefix = 'v'\n        var res = {}\n        for (var i=0; i\u003carguments.length; i++) {\n                res[prefix+i] = arguments[i]\n        }\n        return res // boolean, integer, number, array, object are acceptable\n}\n```\n\none can call the js function test() in Go code like the following:\n\n```go\npackage main\n\nimport \"fmt\"\nimport js \"github.com/rosbit/duktape-bridge/duk-bridge-go\"\n\nfunc main() {\n  ctx := js.NewEnv(nil)\n  defer ctx.Destroy()\n\n  res, _ := ctx.CallFileFunc(\"a.js\", \"args 1\", 2, true, \"other args\") // only filename is needed.\n  fmt.Println(\"result is:\", res)\n\n  /*\n  // or if you want to call the js function more than 1 times, just register it first\n  ctx.RegisterFileFunc(\"a.js\", \"test\")\n  ctx.CallFunc(\"test\", \"args 1\", 2, true, \"other args\")\n  ctx.CallFunc(\"test\", \"array args\", []int{1, 2, 3})\n  ctx.CallFunc(\"test\", \"map args\", map[string]interface{}{\"str\":\"anything\", \"int\": 100})\n  ctx.UnregisterFunc(\"test\") // unregister it if you don't use it anymore\n  */\n}\n```\n\n### JavaScript calls Go function\n\nJavaScript calling Go function is also easy. In the Go code, register a function with\na name by calling `RegisterGoFunc(\"name\", function)`. There's the Go example:\n\n```go\npackage main\n\nimport js \"github.com/rosbit/duktape-bridge/duk-bridge-go\"\n\n// function to be called by JS\nfunc adder(a1 float64, a2 float64) float64 {\n\treturn a1 + a2\n}\n\nfunc main() {\n  ctx := js.NewEnv(nil)\n  defer ctx.Destroy()\n\n  ctx.RegisterGoFunc(\"adder\", adder)\n  // ctx.UnregisterGoFunc(\"adder\")  // unregister it if you don't use it anymore\n  ctx.EvalFile(\"b.js\")  // b.js containing code calling \"adder\"\n}\n```\n\nIn JS code, one can call the registered name directly. There's the example js `b.js`.\n\n```js\nvar r = adder(1, 100)   // the function \"adder\" is implemented in Go\nconsole.log(r)\n```\n\n#### The limitation of Go function\n\nIf a Go function registered to be called by JS, the types of its arguments and result\nmust meet some satisfications:\n\n - any primitive type bool, int, intXX, uintXX, float32, float64 are acceptable\n - string and []byte are acceptable\n - array slice of primitive types and string are acceptable. e.g. []bool, []int\n - map with string as the key type is acceptable. e.g. map[string]interface{}\n - a pointer of struct is acceptable, which will be converted to a js class instance\n - the returned result can contains at most 2 result. If it has 2 results, the 2nd\n   one must be type `error`. The non-nil error will cause a js exception.\n\n### Go module and module loader\n\nduk-bridge for Go provides a default module loader which will convert a Go plugin package into\na JS module. There's the example `c.js`:\n\n```js\nvar m = require('test') // this will load the Go plugin test.so\nvar r = m.adder(1, 300)\nconsole.log(r)\n\nconsole.log('m.name', m.name)\nconsole.log('m.age', m.age)\n```\n\nThe Go code calls the js\n\n```go\npackage main\n\nimport js \"github.com/rosbit/duktape-bridge/duk-bridge-go\"\n\nfunc main() {\n  ctx := js.NewEnv(nil)\n  defer ctx.Destroy()\n\n  ctx.EvalFile(\"c.js\")\n}\n```\nBuild it to a directory, make a subdirectory `modules` under it like the following:\n\n```\n bin\n  +-- go_exe_file\n  +-- modules\n        +-- test.so\n        +-- \u003cother_so_module\u003e.so\n        +-- \u003cjs_module\u003e.js\n```\n\nThe Go plugin module implementation:\n\n```go\npackage main\n\ntype Test struct {\n\tName string\n\tAge int\n\tOther map[string]interface{}\n}\n\nfunc NewGoModule() interface{} {\n\treturn \u0026Test{\"rosbit\", 20}\n}\n\nfunc (t *Test) Adder(a1 float64, a2 float64) float64 {\n\treturn a1 + a2\n}\n\nfunc (t *Test) OtherFunctions() {\n}\n```\n\nSave it as `test.go`, then build it to a Go plugin with the command:\n`go build -buildmode=plugin test.go`, a file `test.so` is created.\ncopy it to the `modules` subdirectory. now run the main Go app.\n\n#### Limitation of Go module\n\nNot all Go packages can become js module. There are some limitations:\n\n - function NewGoModule with prototype `func NewGoModule() interface{}` must be in the module,\n   and it returns a pointer to struct.\n - Though as if function NewGoModule() will be called multi-times, in fact Duktape engine will\n   cache the required module and it is called **only once** even if you `require` it multi-times.\n   So don't declare module related variables in struct. Only read only constants are acceptable.\n - function/field name with the first letter in capital will be exported as moudle method/attribute.\n   For example, `Adder` will be exported but `adder` will not. But to refer the `Adder` method,\n   please use `adder` as used in `c.js`\n\n### Duktape bridge for C and Java\n\n - Duktape bridge for C is under the main directory of the project, just run `make`,\n   a file `duk_bridge.so` will be created, with `duk_bridge.h` and `duk_bridge.so`,\n   one can embed Duktape in any C/C++ project.\n - Duktape bridge for Java is under the subdiretory `duk-bridge-java`, run `make` to\n   create `dukbridge.jar` and `libdukjs.so`. Then one can run\n \n   `java -jar dukbridge.jar -Djava.library.path=. \u003cfile.js\u003e \u003cfunc_name\u003e`\n \n   to hava a test.\n - Of course, with duktape bridge for C, one can implement duktape bridge for\n   other language like Python.\n \n### Lua vs. Dutakpe\n\n - Duktape borrows a lot from Lua conceptually. The usage of Duktape API\n   is very similar to that of Lua.\n - The difference of Lua and Duktape is the embedding language: Duketape engine supports\n   JavaScript, which is now very popular.\n\n### Node.js vs. Duktape\n\n - Node.js objects the web application develepment, in the area there exists PHP, \n   Java Servlet and Python WSGI.\n - Duktape focuses the embedding area where one want to add dynamic modification without\n   rebuild the main application.\n\n### Status\n\nThe package is not fully tested, so be careful.\n\n### Contribution\n\nPull requests are welcome! Also, if you want to discuss something send a pull request with proposal and changes.\n__Convention:__ fork the repository and make changes on your fork in a feature branch.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frosbit%2Fduktape-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frosbit%2Fduktape-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frosbit%2Fduktape-bridge/lists"}