Skip to content

Add use_js macro #4309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open

Add use_js macro #4309

wants to merge 15 commits into from

Conversation

mcmah309
Copy link
Contributor

@mcmah309 mcmah309 commented Jun 22, 2025

This macro does compile time validation and creates rust bindings to javascript functions. Works like a regular use import statement. See example: https://github.com/DioxusLabs/dioxus/blob/40e21cb221754665c68473890360512ac23821f5/examples/use_js_macro.rs

example statement:

use_js!("examples/assets/example.js"::greeting);
// use_js!("examples/assets/example.js"::{ greeting, });
// use_js!("examples/assets/example.js"::*);

example macro expansion:

// Recursive expansion of use_js! macro
// =====================================

#[doc = " "]
#[doc = " This is a doc comment"]
#[doc = " second line"]
pub async fn greeting(
    from: impl serde::Serialize,
    to: impl serde::Serialize,
) -> Result<serde_json::Value, document::EvalError> {
    const MODULE: Asset = {
        const __ASSET_SOURCE_PATH: &'static str = "/workspaces/dioxus/examples/assets/example.js";
        const __ASSET_OPTIONS: manganis::AssetOptions =
            manganis::AssetOptions::Unknown.into_asset_options();
        const __ASSET_HASH: &'static str = "de4b2e9e300415dc";
        const __ASSET: manganis::BundledAsset =
            manganis::macro_helpers::create_bundled_asset(__ASSET_SOURCE_PATH, __ASSET_OPTIONS);
        const __BUFFER: manganis::macro_helpers::const_serialize::ConstVec<u8> =
            manganis::macro_helpers::serialize_asset(&__ASSET);
        const __BYTES: &[u8] = __BUFFER.as_ref();
        const __LEN: usize = __BYTES.len();
        #[unsafe(export_name = "__MANGANIS__de4b2e9e300415dc")]
        static __LINK_SECTION: [u8; __LEN] = manganis::macro_helpers::copy_bytes(__BYTES);
        static __REFERENCE_TO_LINK_SECTION: &'static [u8] = &__LINK_SECTION;
        manganis::Asset::new(__REFERENCE_TO_LINK_SECTION)
    };
    let js = alloc::__export::must_use({
        let res = alloc::fmt::format(alloc::__export::format_args!("const {{ greeting }} = await import(\"{}\");\nlet from = await dioxus.recv();\nlet to = await dioxus.recv();\nreturn greeting(from, to);",MODULE));
        res
    });
    let eval = document::eval(js.as_str());
    eval.send(from)?;
    eval.send(to)?;
    eval.await
}

closes #4302

@mcmah309 mcmah309 requested a review from a team as a code owner June 22, 2025 10:29
@jkelleyrtp
Copy link
Member

Thanks for the PR! We definitely need a better FFI solution in dioxus, but I want to wait until 0.7 is shipped before we start exploring the design space. So, sadly this PR might sit for a while.

We want a similar solution for:

  • Java
  • Kotlin
  • Swift
  • Objective C
  • C/C++
  • TypeScript

It would be ideal to wrap all this under a single interface and build system (ie maybe through buck2/bazel ?) and then integrated with dx. We probably aren't going to accept any adhoc system until then.

@jkelleyrtp jkelleyrtp added this to the 0.8.0 milestone Jul 1, 2025
@mcmah309
Copy link
Contributor Author

mcmah309 commented Jul 1, 2025

Thanks for the feedback. Do you think this might be a better fit in the sdk in the meantime or as a standalone repo/crate I own? I definitely will be using it until something comparable is implemented

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

More Seamless JS Interop
2 participants