{"id":37158645,"url":"https://github.com/fd/v8.go","last_synced_at":"2026-01-14T18:56:49.290Z","repository":{"id":15931900,"uuid":"18673946","full_name":"fd/v8.go","owner":"fd","description":"V8 JavaScript engine bindings for Go","archived":false,"fork":true,"pushed_at":"2014-04-14T07:24:15.000Z","size":433,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-13T07:17:26.948Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"lazytiger/go-v8","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fd.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":"2014-04-11T12:48:09.000Z","updated_at":"2015-01-22T06:02:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fd/v8.go","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fd/v8.go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fd%2Fv8.go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fd%2Fv8.go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fd%2Fv8.go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fd%2Fv8.go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fd","download_url":"https://codeload.github.com/fd/v8.go/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fd%2Fv8.go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28431018,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T16:38:47.836Z","status":"ssl_error","status_checked_at":"2026-01-14T16:34:59.695Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2026-01-14T18:56:48.546Z","updated_at":"2026-01-14T18:56:49.283Z","avatar_url":"https://github.com/fd.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"v8.go\n=====\n\nV8 JavaScript engine bindings for Go.\n\nFeatures\n=======\n\n* Thread safe\n* Thorough and careful testing\n* Boolean, Number, String, Object, Array, Regexp, Function\n* Compile and run JavaScript\n* Save and load pre-compiled script data\n* Create JavaScript context with global object template\n* Operate JavaScript object properties and array elements in Go\n* Define JavaScript object template in Go with property accessors and interceptors\n* Define JavaScript function template in Go\n* Catch JavaScript exception in Go\n* Throw JavaScript exception by Go\n* JSON parse and generate\n* Powerful binding API\n\nInstall\n=======\n\nFor 'curl' user. please run this shell command:\n\n\u003e curl -O https://raw.github.com/idada/v8.go/master/get.sh \u0026\u0026 chmod +x get.sh \u0026\u0026 ./get.sh v8.go\n\nFor 'wget' user. Please run this shell command:\n\n\u003e wget https://raw.github.com/idada/v8.go/master/get.sh \u0026\u0026 chmod +x get.sh \u0026\u0026 ./get.sh v8.go\n\nNote: require Go version 1.2 and Git.\n\nHello World\n===========\n\nThis 'Hello World' program shows how to use v8.go to compile and run JavaScript code then get the result.\n\n```go\npackage main\n\nimport \"github.com/idada/v8.go\"\n\nfunc main() {\n\tengine := v8.NewEngine()\n\tscript := engine.Compile([]byte(\"'Hello ' + 'World!'\"), nil, nil)\n\tcontext := engine.NewContext(nil)\n\n\tcontext.Scope(func(cs v8.ContextScope) {\n\t\tresult := cs.Run(script)\n\t\tprintln(result.ToString())\n\t})\n}\n```\n\nFast Binding\n============\n\n```go\npackage main\n\nimport \"fmt\"\nimport \"reflect\"\nimport \"github.com/idada/v8.go\"\n\ntype MyType struct {\n\tId       int\n\tName     string\n\tData     map[string]int\n\tCallback func(a int, b string)\n}\n\nfunc (mt *MyType) Dump(info string) {\n\tfmt.Printf(\n\t\t\"Info: \\\"%s\\\", Id: %d, Name: \\\"%s\\\", Data: %v\\n\",\n\t\tinfo, mt.Id, mt.Name, mt.Data,\n\t)\n}\n\nfunc main() {\n\tengine := v8.NewEngine()\n\n\tglobal := engine.NewObjectTemplate()\n\n\tglobal.Bind(\"MyType\", MyType{})\n\n\tglobal.Bind(\"print\", func(v ...interface{}) {\n\t\tfmt.Println(v...)\n\t})\n\n\tglobal.Bind(\"test\", func(obj *v8.Object) {\n\t\traw := obj.GetInternalField(0).(*reflect.Value)\n\t\traw.Interface().(*MyType).Callback(123, \"dada\")\n\t})\n\n\tengine.NewContext(global).Scope(func(cs v8.ContextScope) {\n\t\tcs.Eval(`\n\t\t\tvar a = new MyType();\n\n\t\t\ta.Dump(\"old\");\n\n\t\t\ta.Id = 10;\n\t\t\ta.Name = \"Hello\";\n\t\t\ta.Data = {\n\t\t\t\t'x': 1,\n\t\t\t\t'y': 2\n\t\t\t};\n\t\t\ta.Dump(\"new\");\n\n\t\t\ta.Callback = function(a, b) {\n\t\t\t\tprint(a, b);\n\t\t\t}\n\n\t\t\ta.Callback(10, \"Hello\");\n\n\t\t\ttest(a);\n\t\t`)\n\t})\n}\n\n```\n\nPerformance and Stability \n=========================\n\nThe benchmark result on my iMac:\n\n```\nBenchmark_NewContext   285869 ns/op\nBenchmark_NewInteger      707 ns/op\nBenchmark_NewString      1869 ns/op\nBenchmark_NewObject      3292 ns/op\nBenchmark_NewArray0      1004 ns/op\nBenchmark_NewArray5      4024 ns/op\nBenchmark_NewArray20     8601 ns/op\nBenchmark_NewArray100   31963 ns/op\nBenchmark_Compile      640988 ns/op\nBenchmark_PreCompile   629534 ns/op\nBenchmark_RunScript       888 ns/op\nBenchmark_JsFunction     1148 ns/op\nBenchmark_GoFunction     1491 ns/op\nBenchmark_Getter         2215 ns/op\nBenchmark_Setter         3261 ns/op\nBenchmark_TryCatch      47366 ns/op\n```\n\nConcepts\n========\n\nEngine\n------\n\nIn v8.go, engine type is the wrapper of v8::Isolate.\n\nBecause V8 engine use thread-local storage but cgo calls may be execute in different thread. So v8.go use v8::Locker to make sure V8 engine's thread-local data initialized. And the locker make v8.go thread safe.\n\nYou can create different engine instance for data isolate or improve efficiency of concurrent purpose.\n\n```go\nengine1 := v8.NewEngine()\nengine2 := v8.NewEngine()\n```\n\nScript\n------\n\nWhen you want to run some JavaScript. You need to compile first.\n\nScripts can run many times or run in different context.\n\n```go\nscript := engine.Compile([]byte(`\"Hello \" + \"World!\"`), nil, nil)\n```\n\nThe Engine.Compile() method take 3 arguments. \n\nThe first is the code.\n\nThe second is a ScriptOrigin, it stores script's file name or line number offset etc. You can use ScriptOrigin to make error message and stack trace friendly.\n\n```go\nname := \"my_file.js\"\nreal := ReadFile(name)\ncode := \"function(_export){\\n\" + real + \"\\n}\"\norigin := engine.NewScriptOrigin(name, 1, 0)\nscript := engine.Compile(code, origin, nil)\n```\n\nThe third is a ScriptData, it's pre-parsing data, as obtained by Engine.PreCompile(). If you want to compile a script many time, you can use ScriptData to speeds compilation. \n\n```go\ncode := []byte(`\"Hello \" + \"World!\"`)\ndata := engine.PreCompile(code)\nscript1 := engine.Compile(code, nil, data)\nscript2 := engine.Compile(code, nil, data)\n```\n\nContext\n-------\n\nThe description in V8 embedding guide:\n\n\u003e In V8, a context is an execution environment that allows separate, unrelated, JavaScript applications to run in a single instance of V8. You must explicitly specify the context in which you want any JavaScript code to be run.\n\nIn v8.go, you can create many contexts from a V8 engine instance. When you want to run some JavaScript in a context. You need to enter the context by calling Scope() and run the JavaScript in the callback.\n\n```go\ncontext.Scope(func(cs v8.ContextScope){\n\tscript.Run()\n})\n```\n\nContext in V8 is necessary. So in v8.go you can do this:\n\n```go\ncontext.Scope(func(cs v8.ContextScope) {\n\tcontext2 := engine.NewContext(nil)\n\tcontext2.Scope(func(cs2 v8.ContextScope) {\n\n\t})\n})\n```\n\nMore\n----\n\nPlease read `v8_all_test.go` and the codes in `samples` folder.\n\n中文介绍\n========\n\nV8引擎的Go语言绑定。\n\n特性\n====\n\n* 线程安全\n* 详细的测试\n* 数据类型：Boolean, Number, String, Object, Array, Regexp, Function\n* 编译并运行JavaScript\n* 保存和加载预编译的JavaScript数据\n* 创建带有全局对象模板的Context\n* 在Go语言端操作和访问JavaScript数组的元素\n* 在Go语言端操作和访问JavaScript对象的属性\n* 用Go语言创建支持属性访问器和拦截器的JavaScript对象模板\n* 用Go语言创建JavaScript函数模板\n* 在Go语言端捕获JavaScript的异常\n* 从Go语言端抛出JavaScript的异常\n* JSON解析和生成\n* 强大的绑定功能\n\n安装\n====\n\n'curl'用户请运行以下脚本：\n\n\u003e curl -O https://raw.github.com/idada/v8.go/master/get.sh \u0026\u0026 chmod +x get.sh \u0026\u0026 ./get.sh v8.go\n\n'wget'用户请运行以下脚本：\n\n\u003e wget https://raw.github.com/idada/v8.go/master/get.sh \u0026\u0026 chmod +x get.sh \u0026\u0026 ./get.sh v8.go\n\n需求本地安装有Go 1.2和git命令。\n\nHello World\n===========\n\n以下是一段Hello World程序，用来展示v8.go如何编译和运行JavaScript并获得结果：\n\n```go\npackage main\n\nimport \"github.com/idada/v8.go\"\n\nfunc main() {\n\tengine := v8.NewEngine()\n\tscript := engine.Compile([]byte(\"'Hello ' + 'World!'\"), nil, nil)\n\tcontext := engine.NewContext(nil)\n\n\tcontext.Scope(func(cs v8.ContextScope) {\n\t\tresult := cs.Run(script)\n\t\tprintln(result.ToString())\n\t})\n}\n```\n\n快速绑定\n=======\n\n```go\npackage main\n\nimport \"fmt\"\nimport \"reflect\"\nimport \"github.com/idada/v8.go\"\n\ntype MyType struct {\n\tId       int\n\tName     string\n\tData     map[string]int\n\tCallback func(a int, b string)\n}\n\nfunc (mt *MyType) Dump(info string) {\n\tfmt.Printf(\n\t\t\"Info: \\\"%s\\\", Id: %d, Name: \\\"%s\\\", Data: %v\\n\",\n\t\tinfo, mt.Id, mt.Name, mt.Data,\n\t)\n}\n\nfunc main() {\n\tengine := v8.NewEngine()\n\n\tglobal := engine.NewObjectTemplate()\n\n\tglobal.Bind(\"MyType\", MyType{})\n\n\tglobal.Bind(\"print\", func(v ...interface{}) {\n\t\tfmt.Println(v...)\n\t})\n\n\tglobal.Bind(\"test\", func(obj *v8.Object) {\n\t\traw := obj.GetInternalField(0).(*reflect.Value)\n\t\traw.Interface().(*MyType).Callback(123, \"dada\")\n\t})\n\n\tengine.NewContext(global).Scope(func(cs v8.ContextScope) {\n\t\tcs.Eval(`\n\t\t\tvar a = new MyType();\n\n\t\t\ta.Dump(\"old\");\n\n\t\t\ta.Id = 10;\n\t\t\ta.Name = \"Hello\";\n\t\t\ta.Data = {\n\t\t\t\t'x': 1,\n\t\t\t\t'y': 2\n\t\t\t};\n\t\t\ta.Dump(\"new\");\n\n\t\t\ta.Callback = function(a, b) {\n\t\t\t\tprint(a, b);\n\t\t\t}\n\n\t\t\ta.Callback(10, \"Hello\");\n\n\t\t\ttest(a);\n\t\t`)\n\t})\n}\n\n```\n\n性能和稳定性 \n============\n\n以下是在我的iMac上运行benchmark的输出结果:\n\n```\nNewContext     249474 ns/op\nNewInteger        984 ns/op\nNewString         983 ns/op\nNewObject        1036 ns/op\nNewArray0        1130 ns/op\nNewArray5        1314 ns/op\nNewArray20       1666 ns/op\nNewArray100      3124 ns/op\nCompile         11059 ns/op\nPreCompile      11697 ns/op\nRunScript        1085 ns/op\nJsFunction       1114 ns/op\nGoFunction       1630 ns/op\nGetter           2060 ns/op\nSetter           2934 ns/op\nTryCatch        43097 ns/op\n```\n\n概念\n====\n\nEngine\n------\n\n在v8.go中，Engine类型是对象v8::Isolate的封装。\n\n因为V8引擎使用线程相关的存储机制用来优化性能，但是CGO调用可能会在不同的线程里执行。所以v8.go使用v8::Locker来确定V8引擎的线程数据有初始化，并确保v8.go是线程安全的。\n\n你可以创建多个引擎实例用来隔离数据和优化并发效率。\n\n```go\nengine1 := v8.NewEngine()\nengine2 := v8.NewEngine()\n```\n\nScript\n------\n\n当你要运行一段JavaScript代码前，你需要先把它编译成Script对象。\n\n一个Script对象可以在不同的Context中运行多次。\n\n```go\nscript := engine.Compile([]byte(`\"Hello \" + \"World!\"`), nil, nil)\n```\n\nEngine.Compile()方法需要三个参数。\n\n第一个参数是所要编译的JavaScript代码。\n\n第二个参数是一个ScriptOrigin对象，其中存储着脚本对应的文件名和行号等。你可以用ScriptOrigin来让错误信息和栈跟踪信息更友好。\n\n```go\nname := \"my_file.js\"\nreal := ReadFile(name)\ncode := \"function(_export){\\n\" + real + \"\\n}\"\norigin := engine.NewScriptOrigin(name, 1, 0)\nscript := engine.Compile(code, origin, nil)\n```\n\n第三个参数是一个ScriptData对象，它是Engine.PreCompile()方法预解析脚本后得到的数据。如果有一段代码你需要反复编译多次，那么你可以先预解析后，用ScriptData来加速编译。\n\n```go\ncode := []byte(`\"Hello \" + \"World!\"`)\ndata := engine.PreCompile(code)\nscript1 := engine.Compile(code, nil, data)\nscript2 := engine.Compile(code, nil, data)\n```\n\nContext\n-------\n\nV8嵌入指南中的解释:\n\n\u003e In V8, a context is an execution environment that allows separate, unrelated, JavaScript applications to run in a single instance of V8. You must explicitly specify the context in which you want any JavaScript code to be run.\n\n在v8.go中，你可以从一个Engine实例中创建多个上下文。当你需要在某个上下文中运行一段JavaScript时，你需要调用Context.Scope()方法进入这个上下文，然后在回调函数中运行JavaScript。\n\n```go\ncontext.Scope(func(cs v8.ContextScope){\n\tcs.Run(script)\n})\n```\n\n上下文在V8中是可以嵌套的。所以v8.go中你可以这样做：\n\n```go\ncontext.Scope(func(cs v8.ContextScope) {\n\tcontext2 := engine.NewContext(nil)\n\tcontext2.Scope(func(cs2 v8.ContextScope) {\n\n\t})\n})\n```\n\n更多\n----\n\n请阅读`v8_all_test.go`以及`samples`目录下的示例代码。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffd%2Fv8.go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffd%2Fv8.go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffd%2Fv8.go/lists"}