{"id":15718247,"url":"https://github.com/overdrivenpotato/stasis","last_synced_at":"2025-05-13T02:24:13.775Z","repository":{"id":57369858,"uuid":"130405863","full_name":"overdrivenpotato/stasis","owner":"overdrivenpotato","description":"WIP: WebAssembly runtime and rust binding","archived":false,"fork":false,"pushed_at":"2018-09-09T18:30:58.000Z","size":227,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-28T03:46:32.095Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/overdrivenpotato.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-04-20T19:34:14.000Z","updated_at":"2021-01-22T03:36:09.000Z","dependencies_parsed_at":"2022-09-18T10:43:03.005Z","dependency_job_id":null,"html_url":"https://github.com/overdrivenpotato/stasis","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overdrivenpotato%2Fstasis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overdrivenpotato%2Fstasis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overdrivenpotato%2Fstasis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overdrivenpotato%2Fstasis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/overdrivenpotato","download_url":"https://codeload.github.com/overdrivenpotato/stasis/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253857979,"owners_count":21974842,"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":[],"created_at":"2024-10-03T21:52:33.824Z","updated_at":"2025-05-13T02:24:13.753Z","avatar_url":"https://github.com/overdrivenpotato.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Stasis](art.png)\n\nA complete runtime for rust applications in the browser.\n\n* No build step\n* Stable Rust\n* Call JavaScript from Rust\n* Callback Rust from JavaScript\n* Async JavaScript + Rust support\n* Panic Handling\n\n```rust\nextern crate stasis;\n\nfn main() {\n    stasis::console::log(\"Hello World!\");\n}\n```\n\nThis library is intended to be used as a base for other libraries. The goal of\nthis project is to provide the ability to completely eject from the JavaScript\necosystem, while also allowing interop with existing JavaScript applications.\n\n**A complete example can be found at the bottom of this document.**\n\n# Embedding Stasis into existing JavaScript\n\nStasis is designed to be easily embeddable in existing projects. The runtime is\nnot global, so you can have many instances if needed. The `stasis` package on\nnpm exports a function which accepts a path to the binary.\n\nExample:\n\n```javascript\nimport load from 'stasis'\n\nload('/code/bundle1.wasm')\n  .then(() =\u003e {\n    console.log('Bundle 1\\'s main() has finished running!')\n  })\n\nload('/code/bundle2.wasm')\n  .then(() =\u003e {\n    console.log('Bundle 2\\'s main() has finished running!')\n  })\n\n// ...\n```\n\n# FAQ\n\n## Why not [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen)\n\n`wasm-bindgen` aims to make context switching between JavaScript and Rust as\npainless as possible. This comes with the cost of an extra build step and heavy\nmachinery. Stasis aims to be small and light. The goal of Stasis is to provide a\nplatform for complete Rust applications in the browser, and hiding the\nunderlying browser details from the developer. For this reason, Stasis cannot be\na component of the build step.\n\n## Why not [`stdweb`](https://github.com/koute/stdweb)?\n\nThe goal of `stdweb` is to provide Rust bindings to Web APIs while maintaining\ninteroperability between the two languages. Stasis takes a different approach,\nit views JavaScript as something closer to assembly that you can opt-in to use.\nStasis allows you to treat JavaScript code the same way we treat `unsafe`, by\ncreating safe Rust-first wrappers around the JavaScript APIs offered to us in\nthe browser.\n\n## What about `#![feature(wasm_syscall)]`?\n\nWebAssembly syscalls in Rust are not currently specific to JavaScript. This\nmeans we cannot use the API to craft JavaScript calls. Besides this, Stasis aims\nto work on stable rust.\n\n## How does this work?\n\nStasis creates a map of all registered modules and functions. When calling a\nregistered function from WebAssembly, objects describing the request are passed\nin JSON format. This may be changed in the future, however Stasis will make sure\nto be backwards compatible from both the library *and* runtime point of view.\n\n## What's the performance like?\n\nRegistering a function compiles it immediately with the use of `new Function`.\nThis allows the browser JS engine to optimize on a per-function basis, with no\ninterpreter overhead at the time of a call.\n\nFor tight loops that call heavily into JavaScript, library authors are\nencouraged to batch data if possible. This will minimize the overhead present\nwhen calling JavaScript code from WebAssembly.\n\n### TODO: Benchmarks here.\n\n## Isn't serde a huge dependency?\n\nWhen compiling with `lto = true`, the resulting .wasm binary tends to be only\nslightly larger (on the order of 3kb difference). This extra bloat makes it much\neasier to interlace JavaScript and rust code at the expense of a small size\nincrease. I don't believe this is an issue, however if you have a case for a\nbetter solution, please let me know and I am open to changes.\n\n## This doesn't work in node!\n\nStasis is not supported on node. The aim of this project is to enable rust\ncodebases to run on the browser. If you wish to call rust code from node, this\nis already supported in both languages via their respective FFI.\n\n## Won't unminified JavaScript increase final file size?\n\nGzipping the final `.wasm` binary will cut down on most of the file file size.\nHowever yes, unminified JavaScript will be a bit larger. Because Stasis\nencourages only writing absolutely necessary glue code in JavaScript, realistic\ndifferences should be small. From preliminary testing with a `fetch`\nimplementation, the difference between minified and unminified code was 52\nbytes. If a large Stasis library is causing intense bloat of the binary, the\nlibrary author is encouraged to have a `build.rs` script which can run a\nJavaScript minifier first, then include the final file with `include_str!` in\nthe source.\n\n### TODO: Publish a fetch example.\n\n## Why only rust?\n\nThe Stasis runtime hands a small WebAssembly environment to the binary. This\nenvironment is language agnostic. I currently have no plans to create bindings\nto languages other than rust, however feel free to open a pull request if you\nwould like to do so yourself.\n\n# Complete standalone example\n\nThis is a complete application that will print `Hello world!` to the browser\nconsole. To run it in chrome, open a webserver at the project root and navigate\nto `index.html`. If you are using firefox, you can simply open the `index.html`\nfile directly.\n\n## Project structure\n\n```\n.\n├── Cargo.toml\n├── index.html\n└── src\n    └── main.rs\n```\n\n## `Cargo.toml`\n\n```toml\n[package]\nname = \"stasis-test\"\nversion = \"0.1.0\"\nauthors = [\"Marko Mijalkovic \u003cmarko.mijalkovic97@gmail.com\u003e\"]\n\n[dependencies]\nstasis = \"0.1.0-alpha.1\"\n```\n\n## `src/main.rs`\n\n```rust\nextern crate stasis;\n\nfn main() {\n    stasis::console::log(\"Hello world!\");\n}\n```\n\n## `index.html`\n\nNOTE: This file only needs to be written once. This is only necessary to allow\nStasis to bootstrap the WebAssembly binary. In a full application, this file\nwould remain identical.\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003cscript\n            id=\"stasis\"\n            src=\"https://unpkg.com/stasis/dist/stasis.min.js\"\n            type=\"text/javascript\"\n            data-binary=\"target/wasm32-unknown-unknown/release/stasis-test.wasm\"\n        \u003e\u003c/script\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\u003c/body\u003e\n\u003c/html\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foverdrivenpotato%2Fstasis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foverdrivenpotato%2Fstasis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foverdrivenpotato%2Fstasis/lists"}