{"id":48542207,"url":"https://github.com/gnh1201/catswords-jsrt-rs","last_synced_at":"2026-04-08T05:02:45.143Z","repository":{"id":342201805,"uuid":"1129444601","full_name":"gnh1201/catswords-jsrt-rs","owner":"gnh1201","description":"catswords-jsrt-rs provides minimal ChakraCore (JsRT) bindings for Rust. (Experimental)","archived":false,"fork":false,"pushed_at":"2026-01-09T04:44:04.000Z","size":83,"stargazers_count":3,"open_issues_count":1,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-05T11:22:41.412Z","etag":null,"topics":["chakracore","ecmascript","embedded","ffi","ffi-bindings","industrial","javascript","jsrt","runtime","rust","rust-lang","rust-library","welsonjs"],"latest_commit_sha":null,"homepage":"https://catswords.social/@catswords_oss","language":"Rust","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/gnh1201.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-07T05:22:14.000Z","updated_at":"2026-01-14T07:53:43.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gnh1201/catswords-jsrt-rs","commit_stats":null,"previous_names":["gnh1201/catswords-jsrt-rs"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/gnh1201/catswords-jsrt-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnh1201%2Fcatswords-jsrt-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnh1201%2Fcatswords-jsrt-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnh1201%2Fcatswords-jsrt-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnh1201%2Fcatswords-jsrt-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gnh1201","download_url":"https://codeload.github.com/gnh1201/catswords-jsrt-rs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnh1201%2Fcatswords-jsrt-rs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31540826,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"online","status_checked_at":"2026-04-08T02:00:06.127Z","response_time":54,"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":["chakracore","ecmascript","embedded","ffi","ffi-bindings","industrial","javascript","jsrt","runtime","rust","rust-lang","rust-library","welsonjs"],"created_at":"2026-04-08T05:02:33.150Z","updated_at":"2026-04-08T05:02:45.137Z","avatar_url":"https://github.com/gnh1201.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# catswords-jsrt-rs\n\n[![Discord chat](https://img.shields.io/discord/359930650330923008?logo=discord)](https://discord.gg/XKG5CjtXEj?utm_source=catswords)\n\n**catswords-jsrt-rs** provides minimal [ChakraCore](https://github.com/chakra-core/ChakraCore?utm_source=catswords) bindings for Rust. (Experimental)\n\nThis project aims to keep all `unsafe` code strictly inside the low-level FFI crate, while offering a small, ergonomic, and predictable API surface for embedding ChakraCore in Rust applications.\n\nInspired by [@darfink’s Rust wrapper](https://github.com/darfink/chakracore-rs?utm_source=catswords), which is outdated. I rewrote it from scratch with compatibility in mind.\n\nThis project is a subproject within the [WelsonJS](https://github.com/gnh1201/welsonjs) open-source ecosystem.\n\n---\n\n## Workspace layout\n\nThis repository is a Cargo workspace with the following crates:\n\n* **`catswords-jsrt-sys`**\n\n  * Raw FFI bindings to ChakraCore\n  * All `unsafe` code lives here\n  * Thin, mostly mechanical bindings to the C API\n\n* **`catswords-jsrt`**\n\n  * Safe-ish ergonomic wrapper\n  * API inspired by ChakraCore samples\n  * Focused on correctness and minimal abstraction\n\n* **`catswords-jsrt-examples`**\n\n  * Runnable example binaries\n  * Used to validate real execution paths\n\n---\n\n## High-level API overview\n\nThe `chakracore` crate exposes a minimal, explicit API:\n\n* `Runtime::new()`\n* `Context::new(\u0026runtime)`\n* `context.make_current() -\u003e Guard`\n* `script::eval(\u0026guard, \"...\")`\n* `value::Function::new(\u0026guard, closure)`\n* `Function::call(\u0026guard, \u0026[\u0026Value])`\n\nThe `Guard` type enforces context lifetime and helps prevent common misuse patterns.\n\n---\n\n## Requirements (Windows)\n\nYou need ChakraCore headers and libraries available on your system.\n\n### Required files\n\n* `ChakraCore.h` (header)\n* `ChakraCore.lib` (import library)\n* `ChakraCore.dll` (runtime)\n\n### Environment variables\n\nSet these so `chakracore-sys` can locate ChakraCore:\n\n```powershell\n$env:CHAKRACORE_INCLUDE_DIR=\"C:\\path\\to\\ChakraCore\\include\"\n$env:CHAKRACORE_LIB_DIR=\"C:\\path\\to\\ChakraCore\\lib\"\n```\n\n### Build\n\n```powershell\ncargo build\n```\n\n### Runtime notes\n\nAt runtime, `ChakraCore.dll` must be discoverable:\n\n* Place it next to the produced `.exe`, **or**\n* Add its directory to `PATH`\n\n---\n\n## Requirements (Linux)\n\nChakraCore must be available as a shared library. If your distribution provides ChakraCore:\n\n* `ChakraCore.h` must be available\n* `libChakraCore.so` must be linkable\n\nSet environment variables if needed:\n\n```bash\nexport CHAKRACORE_INCLUDE_DIR=\"/usr/include\"\nexport CHAKRACORE_LIB_DIR=\"/usr/lib\"\n#export CHAKRACORE_INCLUDE_DIR=\"/path/to/ChakraCore/include\"  # build from source\n#export CHAKRACORE_LIB_DIR=\"/path/to/ChakraCore/build/lib\"  # build from source\n#export LD_LIBRARY_PATH=\"$CHAKRACORE_LIB_DIR:$LD_LIBRARY_PATH\"  # build from source\n```\n\nBuild:\n\n```bash\ncargo build\n```\n\n---\n\n## Running the examples\n\nAll runnable examples live in the **`catswords-jsrt-examples`** crate and are built as binaries.\n\n### Example binaries\n\n* `hello_world`\n* `multiply`\n\n### Example console messages\n\n```text\n\u003e cargo run -p catswords-jsrt-examples --bin multiply\n    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.09s\n     Running `target\\debug\\multiply.exe`\ndirect call: 191 * 7 = 1337\nglobal eval: multiply(191, 7) = 1337\n```\n\n---\n\n### Windows\n\n```powershell\ncargo run -p catswords-jsrt-examples --bin hello_world\ncargo run -p catswords-jsrt-examples --bin multiply\n```\n\nIf you encounter a runtime error related to missing `ChakraCore.dll`, ensure it is either:\n\n* In the same directory as the executable, or\n* In a directory listed in `PATH`\n\n---\n\n### Linux\n\nIf `libChakraCore.so` is not in a default loader path:\n\n```bash\nexport LD_LIBRARY_PATH=\"$CHAKRACORE_LIB_DIR:$LD_LIBRARY_PATH\"\n```\n\nThen run:\n\n```bash\ncargo run -p catswords-jsrt-examples --bin hello_world\ncargo run -p catswords-jsrt-examples --bin multiply\n```\n\n---\n\n## Example: Hello World\n\n**Binary:** `catswords-jsrt-examples --bin hello_world`\n\n```rust\nextern crate catswords_jsrt as js;\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    // 1. Create runtime\n    let runtime = js::Runtime::new()?;\n\n    // 2. Create context\n    let context = js::Context::new(\u0026runtime)?;\n\n    // 3. Make context current (RAII)\n    let guard = context.make_current()?;\n\n    // 4. Evaluate script\n    let result = js::script::eval(\u0026guard, \"5 + 5\")?;\n\n    // 5. Convert result\n    let value = result.to_integer(\u0026guard)?;\n\n    assert_eq!(value, 10);\n    println!(\"5 + 5 = {}\", value);\n\n    Ok(())\n}\n```\n\nRun:\n\n```bash\ncargo run -p catswords-jsrt-examples --bin hello_world\n```\n\n---\n\n## Example: Function – Multiply\n\n**Binary:** `catswords-jsrt-examples --bin multiply`\n\n```rust\nextern crate catswords_jsrt as js;\n\ntype AnyResult\u003cT\u003e = Result\u003cT, Box\u003cdyn std::error::Error\u003e\u003e;\n\nfn make_multiply(guard: \u0026js::Guard) -\u003e js::value::Function {\n    js::value::Function::new(guard, Box::new(|guard, info| {\n        if info.arguments.len() != 2 {\n            return Err(js::err_msg(\n                js::JsErrorCode::JsErrorInvalidArgument,\n                format!(\"multiply expects 2 arguments, got {}\", info.arguments.len()),\n            ));\n        }\n\n        let a = info.arguments[0].to_integer(guard)?;\n        let b = info.arguments[1].to_integer(guard)?;\n        Ok(js::value::Number::new(guard, a * b).into())\n    }))\n}\n\nfn scenario_direct_call(guard: \u0026js::Guard, multiply: \u0026js::value::Function) -\u003e AnyResult\u003c()\u003e {\n    let a: js::value::Value = js::value::Number::new(guard, 191).into();\n    let b: js::value::Value = js::value::Number::new(guard, 7).into();\n\n    let result = multiply.call(guard, \u0026[\u0026a, \u0026b])?;\n    let value = result.to_integer(guard)?;\n\n    assert_eq!(value, 1337);\n    println!(\"direct call: 191 * 7 = {}\", value);\n    Ok(())\n}\n\nfn scenario_global_eval(guard: \u0026js::Guard, multiply: js::value::Function) -\u003e AnyResult\u003c()\u003e {\n    let context = guard.context();\n\n    let fval: js::value::Value = multiply.into();\n    context.set_global(\"multiply\", \u0026fval)?;\n\n    let result = js::script::eval(guard, \"multiply(191, 7)\")?;\n    let value = result.to_integer(guard)?;\n\n    assert_eq!(value, 1337);\n    println!(\"global eval: multiply(191, 7) = {}\", value);\n    Ok(())\n}\n\nfn main() -\u003e AnyResult\u003c()\u003e {\n    let runtime = js::Runtime::new()?;\n    let context = js::Context::new(\u0026runtime)?;\n    let guard = context.make_current()?;\n\n    let multiply = make_multiply(\u0026guard);\n\n    scenario_direct_call(\u0026guard, \u0026multiply)?;\n    scenario_global_eval(\u0026guard, multiply)?;\n\n    Ok(())\n}\n```\n\nRun:\n\n```bash\ncargo run -p catswords-jsrt-examples --bin multiply\n```\n\n---\n\n## Join the community\nI am always open. Collaboration, opportunities, and community activities are all welcome.\n\n* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss?utm_source=catswords)\n* XMPP [catswords@conference.omemo.id](xmpp:catswords@conference.omemo.id?join)\n* [Join Catswords OSS on Microsoft Teams (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI?utm_source=catswords)\n* [Join Catswords OSS #catswords-jsrt-rs on Discord (discord.gg)](https://discord.gg/jVvhB8N7tb?utm_source=catswords)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgnh1201%2Fcatswords-jsrt-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgnh1201%2Fcatswords-jsrt-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgnh1201%2Fcatswords-jsrt-rs/lists"}