How to Use js-sys for JavaScript APIs from Rust

Web
Use `js-sys` to access JavaScript APIs by importing the specific function or object you need from the crate and calling it with `wasm-bindgen`'s `JsValue` types, ensuring your project is configured with the `wasm-bindgen` and `wasm-bindgen-macro` dependencies.

Use js-sys to access JavaScript APIs by importing the specific function or object you need from the crate and calling it with wasm-bindgen's JsValue types, ensuring your project is configured with the wasm-bindgen and wasm-bindgen-macro dependencies. This crate provides a safe, typed Rust interface to the entire JavaScript standard library, allowing you to call global functions like console.log or access DOM elements without writing unsafe FFI code manually.

First, ensure your Cargo.toml includes the necessary dependencies. You typically need wasm-bindgen for the macro and js-sys for the API bindings. If you are building a web application, you will also likely need web-sys for DOM access, though js-sys handles the core language features.

[dependencies]
wasm-bindgen = "0.2"
js-sys = "0.3"

Once dependencies are set, import the specific function you want to use from the js_sys module. For example, to log a message to the browser console, you import console and call its log_1 method. Note that js-sys functions often have specific names ending in _1, _2, etc., to indicate the number of arguments they accept, or you can use the generic call method for dynamic invocation.

use wasm_bindgen::prelude::*;
use js_sys::console;

#[wasm_bindgen]
pub fn greet(name: &str) {
    // Call console.log with one argument
    console::log_1(&JsValue::from_str(&format!("Hello from Rust, {}", name)));
}

For more complex interactions, such as calling a global function that isn't explicitly defined in js-sys or accessing a property dynamically, you can use JsValue to bridge the gap. You can convert Rust types into JsValue and pass them to JavaScript functions, or retrieve results and convert them back to Rust types.

use wasm_bindgen::prelude::*;
use js_sys::Date;
use wasm_bindgen::JsCast;

#[wasm_bindgen]
pub fn get_current_time() -> f64 {
    // Create a new JavaScript Date object
    let date = Date::new_0();
    
    // Call the getTime() method on the Date object
    let time = date.get_time();
    
    time
}

Remember that js-sys functions return Result types or JsValue that must be handled carefully to avoid panicking in the browser. Always check for errors when calling functions that might fail, and ensure you are running your code in a web environment where the JavaScript runtime is available.