{"id":13712627,"url":"https://github.com/mitchellh/zig-js","last_synced_at":"2025-10-08T09:58:48.675Z","repository":{"id":64173768,"uuid":"573295685","full_name":"mitchellh/zig-js","owner":"mitchellh","description":"Access the JS host environment from Zig compiled to WebAssembly.","archived":false,"fork":false,"pushed_at":"2025-08-23T19:46:54.000Z","size":250,"stargazers_count":255,"open_issues_count":3,"forks_count":11,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-09-23T16:55:53.061Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Zig","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/mitchellh.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-02T05:53:26.000Z","updated_at":"2025-09-20T19:36:09.000Z","dependencies_parsed_at":"2024-01-07T17:31:00.283Z","dependency_job_id":"732c8be7-5795-494f-ab74-34c1692dcaf0","html_url":"https://github.com/mitchellh/zig-js","commit_stats":{"total_commits":72,"total_committers":2,"mean_commits":36.0,"dds":0.01388888888888884,"last_synced_commit":"d0b8b0a57c52fbc89f9d9fecba75ca29da7dd7d1"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mitchellh/zig-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fzig-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fzig-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fzig-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fzig-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitchellh","download_url":"https://codeload.github.com/mitchellh/zig-js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fzig-js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278924143,"owners_count":26069400,"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","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":"2024-08-02T23:01:20.655Z","updated_at":"2025-10-08T09:58:48.646Z","avatar_url":"https://github.com/mitchellh.png","language":"Zig","readme":"# zig-js\n\nzig-js is a Zig library (and accompanying JS glue) that enables Zig\nrunning in a WebAssembly environment to interact with a JavaScript-based\nhost.\n\nNote this makes it particularly easy for Zig to call into JS. This\ndoesn't help for JS calling into Zig. This is more akin to Go's\n`syscall/js` package and not like Rust's `wasm-bindgen`.\n\n## Example\n\n```zig\n// Get and set objects and properties\nconst document = try js.global.get(js.Object, \"document\");\ndefer document.deinit();\n\nconst title = try document.getAlloc(js.String, alloc, \"title\");\ndefer alloc.free(title);\nstd.log.info(\"the title is: {s}\", .{str});\n\ntry document.set(\"title\", js.string(\"A new title.\"));\n\n// Call functions\njs.global.call(void, \"alert\", .{js.string(\"Hello from Zig!\")});\n```\n\nThe code is a bit verbose with the error handling but since JS is a\ndynamic language there are potential invalid types at every step of the\nway. Additionally, `deinit` calls are necessary to dereference garbage-collected\nvalues on the host side.\n\nUnder the covers, this is hiding a lot of complexity since the JS/WASM\nABI only allows passing numeric types and sharing memory.\n\n## Usage\n\nTo use this library, you must integrate a component in both the Zig\nand JS environment. For Zig, vendor this repository and add the package.\nFor example in your build.zig:\n\n```zig\nconst js = @import(\"zig-js\");\n\npub fn build(b: *std.build.Builder) !void {\n  // ... other stuff\n\n  exe.addPackage(js.pkg);\n}\n```\n\nFrom JS, install and import the package in the `js/` directory (in the future\nthis will be published to npm). A TypeScript example is shown below but\nJS could just as easily be used:\n\n```typescript\nimport { ZigJS } from 'zig-js-glue';\n\n// Initialize the stateful zigjs class. You should use one per wasm instance.\nconst zigjs = new ZigJS();\n\nfetch('my-wasm-file.wasm').then(response =\u003e\n  response.arrayBuffer()\n).then(bytes =\u003e\n  // When creating your Wasm instance, pass along the zigjs import\n  // object. You can merge this import object with your own since zigjs\n  // uses its own namespace.\n  WebAssembly.instantiate(bytes, zigjs.importObject())\n).then(results =\u003e {\n  const { memory, my_func } = results.instance.exports;\n\n  // Set the memory since zigjs interfaces with memory.\n  zigjs.memory = memory;\n\n  // Run any of your exported functions!\n  my_func();\n});\n```\n\n**WARNING:** The zig-js version used in your Zig code and JS code must match.\nI'm not promising any protocol stability right now so pin your versions\nappropriately. To determine what version is compatible, look up the tagged\nversion in this repository and the corresponding commits.\n\n## Internals\n\nThe fundamental idea in this is based on the Go\n[syscall/js](https://pkg.go.dev/syscall/js) package. The implementation\nis relatively diverged since Zig doesn't have a runtime or garbage collection,\nbut the fundamental idea of sharing \"refs\" and the format of those refs is\nbased on Go's implementation.\n\nThe main idea is that Zig communicates to JS what values it would like\nto request, such as the \"global\" object. JS generates a \"ref\" for this\nobject (a unique 64-bit numeric value) and sends that to Zig. This ref now\nuniquely identifies the value for future calls such as \"give me the\n'document' property on this ref.\"\n\nThe ref itself is a 64-bit value. For numeric types, the ref _is_ the\nvalue. We take advantage of the fact that all numbers in JavaScript are\nIEEE 754 encoded 64-bit floats and use NaN as a way to send non-numeric values\nto Zig (NaN-boxing).\n\nNaN in IEEE 754 encoding is `0111_1111_1111_\u003canything but all 0s\u003e` in binary.\nWe use a common NaN value of `0111_1111_1111_1000_0000...` so that we can use\nthe bottom (least-significant) 49 bits to store type information and\na 32-bit ID.\n\nThe 32-bit ID is just an index into an array on the JS side. A simple scheme\nis used to reuse IDs after they're dereferenced.\n\n## Performance\n\nUsage of this package causes the WASM/JS boundary to be crossed a LOT\nand this is generally not very fast and not an optimal way to use wasm.\nThe optimal way to use WASM is more like a GPU: have the host (or wasm\nmodule) preload a bunch of work into a byte buffer and send it over\nin one single call. However, this approach is pretty painful.\nThis packge makes interfacing with JS very, very easy. Consider the\ntradeoffs and choose what is best for you.\n","funding_links":[],"categories":["Zig","Network \u0026 Web"],"sub_categories":["WebAssembly"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitchellh%2Fzig-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitchellh%2Fzig-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitchellh%2Fzig-js/lists"}