Important: requires Rust 1.30 stable or newer.
This library provides a Rust binding to the original implementation of webview, a tiny cross-platform library to render web-based GUIs as desktop applications.
Two-way binding between your Rust and JavaScript code is made simple via the external
JS object and webview.eval
Rust function. We have full working examples, but the core is as follows:
// ... Simplified for the sake of brevity.
web_view::builder()
.invoke_handler(|webview, arg| {
match arg {
"test_one" => {
// Do something in Rust!
}
"test_two" => {
// Invoke a JavaScript function!
webview.eval(&format!("myFunction({}, {})", 123, 456))
}
_ => unimplemented!(),
};
})
// Executes our "invoke_handler" - passing the value "test_one" as the second parameter.
external.invoke('test_one');
// Executes our "invoke_handler", which in turn calls "myFunction" below.
external.invoke('test_two');
function myFunction(paramOne, paramTwo) {
console.log(paramOne);
console.log(paramTwo);
}
In addition, by relying on the default rendering engine of the host Operating System, you should be met with a significantly leaner binary to distribute compared to alternatives such as Electron which have to bundle Chromium with each distribution.
You should also see comparatively less memory usage, and this section will be updated with benchmarks to highlight this in due course.
Finally, the supported platforms and the engines you can expect to render your application content are as follows:
Operating System | Browser Engine Used |
---|---|
Windows | MSHTML or EdgeHTML |
Linux | Gtk-webkit2 |
OSX | Cocoa/WebKit |
Note: by default the MSHTML (IE) rendering engine is used to display the application on Windows. If you want to make use of EdgeHTML (Edge) then you'll need to enable it with a feature switch (see the installation and configuration section).
If you're planning on targeting Linux you must ensure that Webkit2gtk
is already installed and available for discovery via the pkg-config command.
If you skip this step you will see a similarly formatted error message as below informing you of what's missing:
Compiling webview-sys v0.3.3
error: failed to run custom build command for `webview-sys v0.3.3`
Caused by:
process didn't exit successfully: `/home/username/rust-projects/my-project/target/debug/build/webview-sys-9020ddaf41e4df7d/build-script-build` (exit code: 101)
--- stderr
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Command { command: "\"pkg-config\" \"--libs\" \"--cflags\" \"webkit2gtk-4.0\" \"webkit2gtk-4.0 >= 2.8\"", cause: Os { code: 2, kind: NotFound, message: "No such file or directory" } }', src/libcore/result.rs:1165:5
Let's start off with the basic Rust application. Run cargo new my-project
in a shell of your choice and change into the my-project
directory.
As this library can be found as a crate on the Rust Community Registry all you have to do to add this as a dependency is update your Cargo.toml
file to have the following under its dependencies section:
[dependencies]
web-view = { version = "0.7" }
If you want to make use of Edge on Windows environments, you will need to have Windows 10 SDK installed through Visual Studio Installer and you'll need to use the following syntax instead:
[dependencies]
web-view = { version = "0.7", features = ["edge"] }
Now let's write some Rust code that makes use of the library. Open up the main.rs
file in an editor of your choice:
vim src/main.rs
And replace the contents with the following:
use web_view::*;
fn main() {
let html_content = "<html><body><h1>Hello, World!</h1></body></html>";
web_view::builder()
.title("My Project")
.content(Content::Html(html_content))
.size(320, 480)
.resizable(false)
.debug(true)
.user_data(())
.invoke_handler(|_webview, _arg| Ok(()))
.run()
.unwrap();
}
You should now be able to run cargo build
and see something similar to the output below:
$ cargo build
Updating crates.io index
Compiling pkg-config v0.3.17
Compiling cc v1.0.47
Compiling boxfnonce v0.1.1
Compiling urlencoding v1.0.0
Compiling webview-sys v0.3.3
Compiling web-view v0.5.4
Compiling my-project v0.1.0 (C:\Users\Username\source\rust-projects\my-project)
Finished dev [unoptimized + debuginfo] target(s) in 8.36s
Assuming you get a successful build all you have to do now is run it with: cargo run
. Hopefully you'll see the same as below:
For more usage info please check out the examples and the original README.
Edge
feature switch not working on Windows 10 if run as Administrator
. This was the root cause of the issue raised in #96 and is the result of a bug in Microsoft.Toolkit.Win32
which is tracked here.
Edge
sandbox restrictions. If you decide to make use of an embedded Web Server to return your content you will need to run the following command to bypass the restriction that prevents communication with localhost
:
$ # Requires administrative privileges.
$ CheckNetIsolation.exe LoopbackExempt -a -n="Microsoft.Win32WebViewHost_cw5n1h2txyewy"
This is usually used with Windows IoT Core, when allowing TCP/IP connections between two processes. You can read some more about this in the Microsoft Documentation here.
IE
rendering content in a legacy, compatibility format. By default, content rendered inside a Web Browser Control will be done so in compatibility mode (specifically IE7). To get round this on Windows systems where Edge is not available you can force the use of the highest version of IE installed via a Registry tweak.
include_str!()
.* The free PureScript By Example book contains several practical projects for PureScript beginners.
Feel free to open a PR if you want your project to be listed here!
Contributions and feedback welcome :)