[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-10867":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":19,"rankGlobal":10,"rankLanguage":10,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":33,"readmeContent":34,"aiSummary":35,"trendingCount":16,"starSnapshotCount":16,"syncStatus":36,"lastSyncTime":37,"discoverSource":38},10867,"stdweb","koute\u002Fstdweb","koute","A standard library for the client-side Web","",null,"Rust",3452,178,60,104,0,1,3,59.56,"Apache License 2.0",false,"master",true,[25,26,27,28,29,30,31,32],"asmjs","emscripten","gui","javascript","rust","web","webasm","webassembly","2026-06-12 04:00:52","\u003Cp align=\"center\">\n    \u003Cimg src=\"info\u002Flogo.png\">\n\u003C\u002Fp>\n\n[![Build Status](https:\u002F\u002Fapi.travis-ci.org\u002Fkoute\u002Fstdweb.svg)](https:\u002F\u002Ftravis-ci.org\u002Fkoute\u002Fstdweb)\n[![Join the chat at https:\u002F\u002Fgitter.im\u002Fstdweb-rs\u002Fstdweb](https:\u002F\u002Fbadges.gitter.im\u002FJoin%20Chat.svg)](https:\u002F\u002Fgitter.im\u002Fstdweb-rs\u002Fstdweb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n# A standard library for the client-side Web\n\n[![Documentation](https:\u002F\u002Fdocs.rs\u002Fstdweb\u002Fbadge.svg)](https:\u002F\u002Fdocs.rs\u002Fstdweb\u002F*\u002Fstdweb\u002F)\n\nThe goal of this crate is to provide Rust bindings to the Web APIs and to allow\na high degree of interoperability between Rust and JavaScript.\n\n## Donate\n\n[![Become a patron](https:\u002F\u002Fkoute.github.io\u002Fimg\u002Fbecome_a_patron_button.png)](https:\u002F\u002Fwww.patreon.com\u002Fkoute)\n\n## Patrons\n\nThis software was brought to you thanks to these wonderful people:\n  * Embark Studios\n  * Joe Narvaez\n  * Eduard Knyshov\n  * Anselm Eickhoff\n  * Johan Andersson\n  * Stephen Sugden\n  * is8ac\n\nThank you!\n\n## Examples\n\nYou can directly embed JavaScript code into Rust:\n\n```rust\nlet message = \"Hello, 世界!\";\nlet result = js! {\n    alert( @{message} );\n    return 2 + 2 * 2;\n};\n\nprintln!( \"2 + 2 * 2 = {:?}\", result );\n```\n\nClosures are also supported:\n\n```rust\nlet print_hello = |name: String| {\n    println!( \"Hello, {}!\", name );\n};\n\njs! {\n    var print_hello = @{print_hello};\n    print_hello( \"Bob\" );\n    print_hello.drop(); \u002F\u002F Necessary to clean up the closure on Rust's side.\n}\n```\n\nYou can also pass arbitrary structures thanks to [serde]:\n\n```rust\n#[derive(Serialize)]\nstruct Person {\n    name: String,\n    age: i32\n}\n\njs_serializable!( Person );\n\njs! {\n    var person = @{person};\n    console.log( person.name + \" is \" + person.age + \" years old.\" );\n};\n```\n\n[serde]: https:\u002F\u002Fserde.rs\u002F\n\nThis crate also exposes a number of Web APIs, for example:\n\n```rust\nlet button = document().query_selector( \"#hide-button\" ).unwrap().unwrap();\nbutton.add_event_listener( move |_: ClickEvent| {\n    for anchor in document().query_selector_all( \"#main a\" ) {\n        js!( @{anchor}.style = \"display: none;\"; );\n    }\n});\n```\n\nExposing Rust functions to JavaScript is supported too:\n\n```rust\n#[js_export]\nfn hash( string: String ) -> String {\n    let mut hasher = Sha1::new();\n    hasher.update( string.as_bytes() );\n    hasher.digest().to_string()\n}\n```\n\nThen you can do this from Node.js:\n\n```js\nvar hasher = require( \"hasher.js\" ); \u002F\u002F Where `hasher.js` is generated from Rust code.\nconsole.log( hasher.hash( \"Hello world!\" ) );\n```\n\nOr you can take the same `.js` file and use it in a web browser:\n\n```html\n\u003Cscript src=\"hasher.js\">\u003C\u002Fscript>\n\u003Cscript>\n    Rust.hasher.then( function( hasher ) {\n        console.log( hasher.hash( \"Hello world!\" ) );\n    });\n\u003C\u002Fscript>\n```\n\nIf you're using [Parcel] you can also use our [experimental Parcel plugin];\nfirst do this in your existing Parcel project:\n\n    $ npm install --save parcel-plugin-cargo-web\n\nAnd then simply:\n\n```js\nimport hasher from \".\u002Fhasher\u002FCargo.toml\";\nconsole.log( hasher.hash( \"Hello world!\" ) );\n```\n\n[Parcel]: https:\u002F\u002Fparceljs.org\u002F\n[experimental Parcel plugin]: https:\u002F\u002Fgithub.com\u002Fkoute\u002Fparcel-plugin-cargo-web\n\n## Design goals\n\n  * Expose a full suite of Web APIs as exposed by web browsers.\n  * Try to follow the original JavaScript conventions and structure as much as possible,\n    except in cases where doing otherwise results in a clearly superior design.\n  * Be a building block from which higher level frameworks and libraries\n    can be built.\n  * Make it convenient and easy to embed JavaScript code directly into Rust\n    and to marshal data between the two.\n  * Integrate with the wider Rust ecosystem, e.g. support marshaling of structs\n    which implement serde's Serializable.\n  * Put Rust in the driver's seat where a non-trivial Web application can be\n    written without touching JavaScript at all.\n  * Allow Rust to take part in the upcoming WebAssembly (re)volution.\n  * Make it possible to trivially create standalone libraries which are\n    easily callable from JavaScript.\n\n## Getting started\n\nTake a look at some of the examples:\n\n  * `examples\u002Fminimal` - a totally minimal example which calls [alert]\n  * `examples\u002Ftodomvc` - a naively implemented [TodoMVC] application; shows how to call into the DOM\n  * `examples\u002Fhasher` - shows how to export Rust functions to JavaScript and how to call them from\n                        a vanilla web browser environment or from Nodejs\n  * `examples\u002Fhasher-parcel` - shows how to import and call exported Rust functions in a [Parcel] project\n  * [`pinky-web`] - an NES emulator; you can play with the [precompiled version here](http:\u002F\u002Fkoute.github.io\u002Fpinky-web\u002F)\n\n[The API documentation](https:\u002F\u002Fdocs.rs\u002Fstdweb\u002F*\u002Fstdweb\u002F) is also available for you to look at.\n\n[alert]: https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FWindow\u002Falert\n[TodoMVC]: http:\u002F\u002Ftodomvc.com\u002F\n[`pinky-web`]: https:\u002F\u002Fgithub.com\u002Fkoute\u002Fpinky\u002Ftree\u002Fmaster\u002Fpinky-web\n\n## Running the examples\n\n1. Install [cargo-web]:\n\n       $ cargo install -f cargo-web\n\n3. Go into `examples\u002Ftodomvc` and start the example using one of these commands:\n\n    * Compile to [WebAssembly] using Rust's native WebAssembly backend:\n\n          $ cargo web start --target=wasm32-unknown-unknown\n\n    * Compile to [asm.js] using Emscripten:\n\n          $ cargo web start --target=asmjs-unknown-emscripten\n\n    * Compile to [WebAssembly] using Emscripten:\n\n          $ cargo web start --target=wasm32-unknown-emscripten\n\n4. Visit `http:\u002F\u002Flocalhost:8000` with your browser.\n\nFor the `*-emscripten` targets `cargo-web` is not necessary, however\nthe native `wasm32-unknown-unknown` which doesn't need Emscripten\n**requires** `cargo-web` to work!\n\n[cargo-web]: https:\u002F\u002Fgithub.com\u002Fkoute\u002Fcargo-web\n[asm.js]: https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAsm.js\n[WebAssembly]: https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FWebAssembly\n\n## Changelog\n   * `stdweb 0.4.20`\n      * Compatibility with the newest `wasm-bindgen`\n      * New events:\n         * `FullscreenChangeEvent`\n   * `stdweb 0.4.19`\n      * New methods:\n         * `Document::fullscreen_enabled`\n         * `Document::fullscreen_element`\n         * `InputElement::selection_start`\n         * `InputElement::selection_end`\n         * `InputElement::set_selection_start`\n         * `InputElement::set_selection_end`\n         * `Object::to_iter`\n         * `Window::confirm`\n      * `&Array`s can now be converted to `Vec`s through `TryFrom`\n      * The runtime should now be compatible with newer versions of Emscripten\n      * The unstable `futures`-related APIs were updated to work with the latest nightlies\n      * The `syn` dependency was updated to version 1\n   * `stdweb 0.4.18`\n      * The `js!` macro can now be imported with an `use`\n      * New events:\n         * `BeforeUnloadEvent`\n         * `UnloadEvent`\n      * New methods:\n         * `IBlob::slice`\n         * `IBlob::slice_with_content_type`\n         * `IWindowOrWorker::set_clearable_timeout`\n   * `stdweb 0.4.17`\n      * The unstable `futures`-related APIs were updated to work with the latest nightlies\n   * `stdweb 0.4.16`\n      * Initial `wasm-bindgen` compatibility; you can now use `stdweb` in projects\n        using `wasm-bindgen`\n      * Minimum supported Rust version is now 1.33.0\n      * Minimum required `cargo-web` version is now 0.6.24\n   * `stdweb 0.4.15`\n      * The unstable `futures`-related APIs were updated to work with the latest nightlies\n      * New types:\n         * `FormData`\n         * `FormDataEntry`\n         * `MouseButtonsState`\n      * New methods:\n         * `Blob::new`\n   * `stdweb 0.4.14`\n      * The `js!` macro now generates slightly more efficient code\n        if you're not returning anything from your JS snippet. This makes\n        it unnecessary to add the `@(no_return)` annotation in the vast\n        majority of cases.\n      * New types:\n         * `File`\n   * `stdweb 0.4.13`\n      * Fixed the procedural `js!` macro's whitespace handling\n      * New types:\n         * `ITouchEvent`\n         * `Touch`\n         * `TouchType`\n      * New events:\n         * `TouchEvent`\n         * `TouchMove`\n         * `TouchLeave`\n         * `TouchEnter`\n         * `TouchEnd`\n         * `TouchCancel`\n         * `TouchStart`\n      * New methods:\n         * `XmlHttpRequest::set_response_type`\n   * `stdweb 0.4.12`\n      * Improved diagnostics when trying to compile for the `wasm32-unknown-unknown` target without `cargo-web`\n   * `stdweb 0.4.11`\n      * The minimum required Rust version is now 1.30.1\n      * The minimum required `cargo-web` version is now 0.6.22\n      * `wasm32-unknown-unknown` is now officially supported on stable Rust\n      * Debug builds on `wasm32-unknown-unknown` are now supported\n      * The `js!` macro is now partially implemented using a procedural macro\n      * String decoding\u002Fencoding is now a lot faster due to the use of native codec APIs\n      * New methods:\n        * `Document::import_node`\n        * `IElement::slot`\n        * `IElement::attach_shadow`\n        * `IElement::shadow_root`\n      * New types:\n        * `ISlotable`\n        * `ShadowRoot`\n        * `ShadowRootMode`\n        * `TemplateElement`\n        * `SlotElement`\n      * New events:\n        * `SlotChangeEvent`\n      * `IParentNode::query_selector` and `IParentNode::query_selector_all` now return a proper error type\n   * `stdweb 0.4.10`, `stdweb-derive 0.5.1`\n      * New methods:\n        * `IElement::insert_adjacent_html`\n        * `IElement::insert_html_before`\n        * `IElement::insert_html_after`\n        * `IElement::prepend_html`\n        * `IElement::append_html`\n        * `IElement::namespace_uri`\n        * `IElement::closest`\n        * `Document::create_element_ns`\n        * `Window::get_selection`\n      * New types:\n        * `AbortError`\n        * `SelectionType`\n        * `Selection`\n        * `Range`\n      * The error messages for failed type conversions are now improved\n      * The error type of failed conversions (when using `.try_into()`\u002F`.try_from()`) is now convertible into a `TypeError`\n      * Aggregate error types (like, e.g. `DrawImageError`) are now serializable through the `js!` macro\n      * `TypeError` is now fixed (it was incorrectly treated as a `DOMException`)\n      * `Number` can now be converted into `f64` with `.into()`\u002F`.from()`\n      * Added `Mut`, which is a new wrapper type for safely passing `FnMut` closures into the `js!` macro;\n        it is optional for now, however the usage of this wrapper type **will be mandatory** in the future!\n      * `FnMut` closures cannot be called recursively anymore\n      * `#[derive(ReferenceType)]` now supports a limited subset of generic types\n      * Asynchronous unit tests are now supported with a new `#[async_test]` attribute macro (nightly only)\n      * Updated to `futures 0.3` (nightly only)\n   * `stdweb 0.4.9`, `stdweb-derive 0.5.0`\n      * Performance improvements; serialization through serde is now twice as fast\n      * New events:\n        * `ScrollEvent`\n        * `DragRelatedEvent`\n        * `DragEvent`\n        * `DragStartEvent`\n        * `DragEndEvent`\n        * `DragEnterEvent`\n        * `DragLeaveEvent`\n        * `DragOverEvent`\n        * `DragExitEvent`\n        * `DragDropEvent`\n      * New types:\n        * `DataTransfer`\n        * `EffectAllowed`\n        * `DropEffect`\n        * `DataTransferItemList`\n        * `DataTransferItem`\n        * `DataTransferItemKind`\n        * `IDragEvent`\n      * `Value`s can now be converted to `Option\u003C Serde\u003C T > >` with `try_into`\n      * Deserialization of numbers through serde now works in the majority of cases\n        allowing types other than `i32` and `f64` to be used\n      * All of the events are now more strongly-typed\n          * Previously in was possible to deserialize e.g. a `keyup` event\n            as a `KeyDownEvent` since only the event's JS type was checked\n            and both `keyup` and `keydown` share the same JS type (`KeyboardEvent`).\n            From now on the `type` field of the event is also checked, so\n            such conversions are not allowed anymore.\n   * `0.4.8`\n      * Fixed compilation on the newest nightly when targeting `wasm32-unknown-unknown`\n      * New events:\n        * `PointerLockChangeEvent`\n        * `PointerLockErrorEvent`\n        * `MouseWheelEvent`\n      * New types:\n        * `MouseWheelDeltaMode`\n        * `XhrResponseType`\n      * New methods:\n        * `XmlHttpRequest::raw_response`\n        * `Window::device_pixel_ratio`\n        * `Document::pointer_lock_element`\n        * `Document::exit_pointer_lock`\n   * `0.4.7`\n      * New events:\n         * `AuxClickEvent`\n         * `MouseEnterEvent`\n         * `MouseLeaveEvent`\n         * `ContextMenuEvent`\n         * `SelectionChangeEvent`\n      * New types:\n        * `FileList`\n        * `FileReaderReadyState`\n      * Implement gamepad APIs:\n         * `Gamepad`\n         * `GamepadButton`\n         * `GamepadButtonMapping`\n         * `GamepadEvent`\n      * Fixed `CanvasRenderingContext2d::clear_rect`\n      * Fixed a leak when creating `TypedArray`s from\n        `Vec`s and `ArrayBuffer`s.\n   * `0.4.6`\n      * Fix `docs.rs` again\n      * New types:\n         * `SubmitEvent`\n         * `IChildNode`\n      * Fix `CanvasElement::to_data_url`\n   * `0.4.5`\n      * New types:\n         * `DocumentFragment`\n         * `SelectElement`\n         * `OptionElement`\n         * `HtmlCollection`\n      * New methods:\n         * `Node::from_html`\n         * `Value::is_null`\n      * Expose enums:\n         * `SocketMessageData`\n         * `NodeType`\n      * Update to `futures` 0.2\n   * `0.4.4`\n      * Fix `docs.rs` (hopefully).\n      * New methods:\n         * `Location::origin`\n         * `Location::protocol`\n         * `Location::host`\n         * `Location::hostname`\n         * `Location::port`\n         * `Location::pathname`\n         * `Location::search`\n      * These now return `SecurityError` in the error case:\n         * `Location::hash`\n         * `Location::href`\n   * `0.4.3`\n      * Objects which cannot be used as keys in a `WeakMap`\n        should be supported now (e.g. some of the WebGL-related objects under Firefox)\n      * New methods:\n         * `Element::get_bounding_client_rect`\n         * `Element::scroll_top`\n         * `Element::scroll_left`\n         * `Window::page_x_offset`\n         * `Window::page_y_offset`\n         * `NodeList::item`\n         * `Document::body`\n         * `Document::head`\n         * `Document::title`\n         * `Document::set_title`\n         * `IMouseEvent::offset_x`\n         * `IMouseEvent::offset_y`\n      * Expose more canvas related types:\n         * `CompositeOperation`\n         * `LineCap`\n         * `LineJoin`\n         * `Repetition`\n         * `TextAlign`\n         * `TextBaseline`\n      * Expose canvas related error types: `AddColorStopError`, `DrawImageError`, `GetImageDataError`\n      * New events:\n         * `MouseOverEvent`\n         * `MouseOutEvent`\n         * `PointerOverEvent`\n         * `PointerEnterEvent`\n         * `PointerDownEvent`\n         * `PointerMoveEvent`\n         * `PointerUpEvent`\n         * `PointerCancelEvent`\n         * `PointerOutEvent`\n         * `PointerLeaveEvent`\n         * `GotPointerCaptureEvent`\n         * `LostPointerCaptureEvent`\n      * New interface for pointer events: `IPointerEvent`\n   * `0.4.2`\n      * Fixed a leak when deserializing references\n      * Fixed `CanvasRenderingContext2d::get_canvas`\n      * Exposed `FillRule` and `SocketReadyState`\n      * New attribute related methods added to `IElement`\n      * New `Date` bindings\n   * `0.4.1`\n      * Support for newest nightly Rust on `wasm32-unknown-unknown`\n      * Exposed `SocketBinaryType` enum\n      * New canvas APIs:\n         * Numerous new methods for `CanvasRenderingContext2d`\n         * New types: `CanvasGradient`, `CanvasPattern`, `CanvasStyle`, `ImageData`, `TextMetrics`\n      * New error types: `IndexSizeError`, `NotSupportedError`, `TypeError`\n   * `0.4`\n      * (breaking change) Removed `Array` and `Object` variants from `Value`; these are now treated as `Reference`s\n      * (breaking change) The `Value` has an extra variant: `Symbol`\n      * (breaking change) Removed:\n         * `InputElement::set_kind`\n         * `InputElement::files`\n      * (breaking change) Renamed:\n         * `KeydownEvent` -> `KeyDownEvent`\n         * `KeyupEvent` -> `KeyUpEvent`\n         * `KeypressEvent` -> `KeyPressEvent`\n         * `ReadyState` -> `FileReaderReadyState`\n         * `InputElement::value` -> `InputElement::raw_value`\n         * `InputElement::set_value` -> `InputElement::set_raw_value`\n      * (breaking change) `ArrayBuffer::new` now takes an `u64` argument\n      * (breaking change) `InputElement::set_raw_value` now takes `&str` instead of `Into\u003C Value >`\n      * (breaking change) Changed return types:\n         * Every method which returned `usize` now returns `u32`\n         * `INode::remove_child` now returns `Node` in the `Ok` case\n         * The following now return an `u64`:\n            * `ArrayBuffer::len`\n         * The following now return an `i32` instead of `f64`:\n            * `IMouseEvent::client_x`\n            * `IMouseEvent::client_y`\n            * `IMouseEvent::movement_x`\n            * `IMouseEvent::movement_y`\n            * `IMouseEvent::screen_x`\n            * `IMouseEvent::screen_y`\n         * The following now return a `Result`:\n            * `INode::insert_before`\n            * `INode::replace_child`\n            * `INode::clone_node`\n            * `StringMap::insert`\n            * `TokenList::add`\n            * `TokenList::remove`\n            * `Document::create_element`\n            * `IEventTarget::dispatch_event`\n            * `FileReader::read_as_text`\n            * `FileReader::read_as_array_buffer`\n            * `FileReader::read_as_text`\n            * `History::replace_state`\n            * `History::go`\n            * `History::back`\n            * `History::forward`\n            * `Location::href`\n            * `Location::hash`\n            * `CanvasElement::to_data_url`\n            * `CanvasElement::to_blob`\n            * `ArrayBuffer::new`\n        * `INode::base_uri` now returns a `String` instead of `Option\u003C String >`\n        * `InputElement::raw_value` now returns a `String` instead of `Value`\n      * (breaking change) `INode::inner_text` was moved to `IHtmlElement::inner_text`\n      * (breaking change) `Document::query_selector` and `Document::query_selector_all` were moved to `IParentNode`\n      * (breaking change) `IElement::query_selector` and `IElement::query_selector_all` were moved to `IParentNode`\n      * (breaking change) `Document::get_element_by_id` was moved to `INonElementParentNode`\n      * (breaking change) A blanket impl for converting between arbitrary reference-like objects using\n        `TryFrom`\u002F`TryInto` has been removed\n      * When building using a recent `cargo-web` it's not necessary to call\n        `stdweb::initialize` nor `stdweb::event_loop` anymore\n      * Support for `cdylib` crates on `wasm32-unknown-unknown`\n      * New bindings:\n         * `XmlHttpRequest`\n         * `WebSocket`\n         * `MutationObserver`\n         * `History`\n         * `TextAreaElement`\n         * `CanvasElement`\n      * New event types:\n         * `MouseDownEvent`\n         * `MouseUpEvent`\n         * `MouseMoveEvent`\n         * `PopStateEvent`\n         * `ResizeEvent`\n         * `ReadyStateChange`\n         * `SocketCloseEvent`\n         * `SocketErrorEvent`\n         * `SocketOpenEvent`\n         * `SocketMessageEvent`\n      * Initial support for the Canvas APIs\n      * New traits: `ReferenceType` and `InstanceOf`\n      * Add `#[derive(ReferenceType)]` in `stdweb-derive` crate; it's now possible\n        to define custom API bindings outside of `stdweb`\n      * Add `#[js_export]` procedural attribute (`wasm32-unknown-unknown` only)\n      * Add `DomException` and subtypes for passing around JavaScript exceptions\n      * `IElement` now inherits from `INode`\n      * Every interface now inherits from `ReferenceType`\n      * Add `stdweb::traits` module to act as a prelude for `use`-ing all of our interface traits\n      * Add `console!` macro\n      * Most types now implement `PartialEq` and `Eq`\n\n   * `0.3`\n      * (breaking change) Deleted `ErrorEvent` methods\n      * (breaking change) Renamed:\n         * `LoadEvent` -> `ResourceLoadEvent`\n         * `AbortEvent` -> `ResourceAbortEvent`\n         * `ErrorEvent` -> `ResourceErrorEvent`\n      * Add `UnsafeTypedArray` for zero cost slice passing to `js!`\n      * Add `Once` for passing `FnOnce` closures to `js!`\n\n## License\n\nLicensed under either of\n\n  * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http:\u002F\u002Fwww.apache.org\u002Flicenses\u002FLICENSE-2.0)\n  * MIT license ([LICENSE-MIT](LICENSE-MIT) or http:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT)\n\nat your option.\n\nSnippets of documentation which come from [Mozilla Developer Network] are covered under the [CC-BY-SA, version 2.5] or later.\n\n[Mozilla Developer Network]: https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002F\n[CC-BY-SA, version 2.5]: https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FMDN\u002FAbout#Copyrights_and_licenses\n\n### Contributing\n\nSee [CONTRIBUTING.md](https:\u002F\u002Fgithub.com\u002Fkoute\u002Fstdweb\u002Fblob\u002Fmaster\u002FCONTRIBUTING.md)\n","koute\u002Fstdweb 是一个为客户端 Web 应用提供标准库的 Rust 项目。它通过 Rust 绑定到 Web API，实现 Rust 和 JavaScript 之间的高度互操作性，支持直接嵌入 JavaScript 代码、闭包传递以及使用 serde 进行结构体序列化。此外，该项目还提供了丰富的 Web API 访问功能，并允许将 Rust 函数暴露给 JavaScript 使用。适合于需要在浏览器环境中利用 Rust 语言优势进行开发的场景，如构建高性能 Web 应用或游戏。",2,"2026-06-11 03:30:32","top_topic"]