webview
Version, currently 0.2.213 versions
- 0.2.6latestJun 24, 2026
- 0.2.5not indexedJun 24, 2026
- 0.2.4not indexedJun 24, 2026
- 0.2.3not indexedJun 24, 2026
- 0.2.2not indexedJun 24, 2026
- 0.2.1not indexedJun 24, 2026
- 0.2.0not indexedJun 24, 2026
- 0.1.5not indexedJun 24, 2026
- 0.1.4not indexedJun 24, 2026
- 0.1.3not indexedJun 24, 2026
- 0.1.2not indexedJun 24, 2026
- 0.1.1not indexedJun 24, 2026
- 0.1.0not indexedJun 24, 2026
github.com/naqvis/webview
Crystal bindings to the zserge's tiny cross-platform Webview library.
107 stars
0 dependents
License: MIT
Nothing has been indexed for 0.2.2 yet. The tag is recorded, its shard.yml has not been read, so the manifest and dependency list below are empty because they are unknown rather than because they are absent.
Installation
# Add this to your shard.yml
dependencies:
webview:
github: naqvis/webview
version: ~> 0.2.2Then run:
shards installshard.yml
No shard.yml has been indexed for 0.2.2. You can read it on the repository.
Dependencies
Unknown: the shard.yml for this version has not been read yet.
README
This README is the one indexed from the repository at its latest ref, not from the tag for this version.
[](https://github.com/naqvis/webview/actions/workflows/linux.yml)
[](https://github.com/naqvis/webview/actions/workflows/macos.yml)
[](https://github.com/naqvis/webview/actions/workflows/windows.yml)
# Crystal Webview
Crystal language bindings for [zserge's Webview](https://github.com/zserge/webview) which is an excellent cross-platform single-header webview library for C/C++ using Gtk, Cocoa, or MSHTML/Edge, depending on the host OS.
**Webview** relies on default rendering engine of host Operating System, thus binaries generated with this Shard will be much more leaner as compared to [Electron](https://github.com/electron/electron) which bundles Chromium with each distribution.
This shard supports **two-way bindings** between Crystal and JavaScript. You can invoke JS code via `Webview::Webview#eval` and calling Crystal code from JS is done via `WebView::Webview#bind` (refer to Examples 3 & 4 for samples on how to invoke Crystal functions from JS).
Webview-supported platforms and the engines you can expect to render your application content are as follows:
| Operating System | Browser Engine Used |
| ---------------- | ------------------------------------------------- |
| macOS | Cocoa, [WebKit][webkit] |
| Linux | [GTK 3][gtk], [WebKitGTK][webkitgtk] |
| Windows | [Windows API][win32-api], [WebView2][ms-webview2] |
## Pre-requisite
If you're planning on targeting Linux or BSD you must ensure that [WebKit2GTK][webkitgtk] is already installed and available for discovery via the pkg-config command.
Debian-based systems:
- Packages:
- Development: `apt install libgtk-3-dev libwebkit2gtk-4.1-dev`
- Production: `apt install libgtk-3-0 libwebkit2gtk-4.1-0`
BSD-based systems:
- FreeBSD packages: `pkg install webkit2-gtk3`
- Execution on BSD-based systems may require adding the `wxallowed` option (see [mount(8)](https://man.openbsd.org/mount.8)) to your fstab to bypass [W^X](https://en.wikipedia.org/wiki/W%5EX "write xor execute") memory protection for your executable. Please see if it works without disabling this security feature first.
Microsoft Windows:
- You should have Visual C++ Build tools already as it's a pre-requisite for crystal compiler
- `git clone https://github.com/webview/webview` to get WebView sources
- `webview\script\build.bat` to compile them (it will download required nuget package)
- copy `webview\dll\x64\webview.lib` to `<your crystal installation>\lib`
- copy `webview\dll\x64\webview.dll` to directory with your program
## Installation
1. Add the dependency to your `shard.yml`:
```yaml
dependencies:
webview:
github: naqvis/webview
```
2. Run `shards install`
## New Features
### Type-Safe Bindings
Use `bind_typed` for compile-time type safety and automatic JSON conversion:
```crystal
wv.bind_typed("add", Int32, Int32) do |a, b|
a + b # Clean, automatic conversion!
end
```
Instead of manual JSON handling:
```crystal
wv.bind("add", Webview::JSProc.new { |args|
a = args[0].as_i.to_i32 # Manual conversion
b = args[1].as_i.to_i32
JSON::Any.new(a + b) # Manual wrapping
})
```
### RAII Resource Management
Automatic cleanup with `with_window`:
```crystal
Webview.with_window(800, 600, Webview::SizeHints::NONE, "My App") do |wv|
wv.html = "<h1>Hello</h1>"
wv.run
end # Automatically destroyed
```
### Lifecycle Hooks
React to page events:
```crystal
wv.on_load = -> { puts "Page loaded!" }
wv.on_navigate = ->(url : String) { puts "Navigating to #{url}" }
```
### Async/Fiber Support
Non-blocking JavaScript evaluation:
```crystal
wv.eval_async("console.log('Hello')") do
puts "JavaScript executed"
end
# Or with channels
channel = wv.eval_with_channel("someCode()")
channel.receive # Wait for completion
```
### Multi-Window Management
Manage multiple windows easily:
```crystal
Webview::WindowManager.with_manager do |manager|
window1 = manager.create_window(800, 600, Webview::SizeHints::NONE, "Window 1")
window2 = manager.create_window(800, 600, Webview::SizeHints::NONE, "Window 2")
# All windows automatically cleaned up
end
```
### Better Error Handling
Errors now include context:
```crystal
# Errors show what operation failed
wv.navigate("invalid://url") # Error: "navigating to invalid://url"
```
### Native Handle Access
Access platform-specific handles:
```crystal
window_handle = wv.window
ui_widget = wv.native_handle(Webview::NativeHandleKind::UI_WIDGET)
```
See the `examples/` directory for complete working examples.
## Usage
### Example 1: Loading URL
```crystal
require "webview"
wv = Webview.window(640, 480, Webview::SizeHints::NONE, "Hello WebView", "http://crystal-lang.org")
wv.run
wv.destroy
```
### Example 2: Loading HTML
```crystal
require "webview"
html = <<-HTML
<!DOCTYPE html><html lang="en-US">
<head>
<title>Hello,World!</title>
</head>
<body>
<div class="container">
<header>
<!-- Logo -->
<h1>City Gallery</h1>
</header>
<nav>
<ul>
<li><a href="/London">London</a></li>
<li><a href="/Paris">Paris</a></li>
<li><a href="/Tokyo">Tokyo</a></li>
</ul>
</nav>
<article>
<h1>London</h1>
<img src="pic_mountain.jpg" alt="Mountain View" style="width:304px;height:228px;">
<p>London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.</p>
<p>Standing on the River Thames, London has been a major settlement for two millennia, its history going back to its founding by the Romans, who named it Londinium.</p>
</article>
<footer>Copyright © W3Schools.com</footer>
</div>
</body>
</html>
HTML
wv = Webview.window(640, 480, Webview::SizeHints::NONE, "Hello WebView")
wv.html = html
wv.run
wv.destroy
```
### Example 3: Calling Crystal code from JavaScript
```crystal
require "webview"
html = <<-HTML
<!doctype html>
<html>
<body>hello</body>
<script>
window.onload = function() {
document.body.innerText = "Javascript calling Crystal code";
noop().then(function(res) {
console.log('noop res', res);
add(1, 2).then(function(res) {
console.log('add res', res);
});
});
};
</script>
</html>
HTML
wv = Webview.window(640, 480, Webview::SizeHints::NONE, "Hello WebView", true)
wv.html = html
wv.bind("noop", Webview::JSProc.new { |a|
pp "Noop called with arguments: #{a}"
JSON::Any.new("noop")
})
wv.bind("add", Webview::JSProc.new { |a|
pp "add called with arguments: #{a}"
ret = 0_i64
a.each do |v|
ret += v.as_i64
end
JSON::Any.new(ret)
})
wv.run
wv.destroy
```
### Example 4: Calling Crystal code from JavaScript and executing JavaScript from Crystal
```crystal
require "webview"
html = <<-HTML
<!DOCTYPE html><html lang="en-US">
<head>
<title>Hello,World!</title>
</head>
<body>
<button onClick="add(document.body.children.length)">Add</button>
</body>
</html>
HTML
inject = <<-JS
elem = document.createElement('div');
elem.innerHTML = "hello webview %s";
document.body.appendChild(elem);
JS
wv = Webview.window(640, 480, Webview::SizeHints::NONE, "Hello WebView", true)
wv.html = html
wv.bind("add", Webview::JSProc.new { |n|
wv.eval(sprintf(inject, n))
JSON::Any.new(nil)
})
wv.run
wv.destroy
```
### Example 5: Running your web app in another thread
```crystal
Thread.new do
get "/" do
"hello from kemal"
end
Kemal.run
end
wv = Webview.window(640, 480, Webview::SizeHints::NONE, "WebView with local webapp!", "http://localhost:3000")
wv.run
wv.destroy
```
### Example 6: Type-Safe Bindings (New!)
```crystal
require "webview"
html = <<-HTML
<!DOCTYPE html>
<html>
<body>
<button onclick="testAdd()">Test Add</button>
<div id="result"></div>
<script>
async function testAdd() {
const result = await add(5, 3);
document.getElementById('result').textContent = 'Result: ' + result;
}
</script>
</body>
</html>
HTML
Webview.with_window(640, 480, Webview::SizeHints::NONE, "Type-Safe Demo") do |wv|
wv.html = html
# Type-safe binding - automatic conversion!
wv.bind_typed("add", Int32, Int32) do |a, b|
a + b
end
wv.run
end # Automatically destroyed
```
## App Distribution
Distribution of your app is outside the scope of this library but we can give some pointers for you to explore.
### macOS Application Bundle
On macOS you would typically create a bundle for your app with an icon and proper metadata.
A minimalistic bundle typically has the following directory structure:
```
example.app bundle
└── Contents
├── Info.plist information property list
├── MacOS
| └── example executable
└── Resources
└── example.icns icon
```
Read more about the [structure of bundles][macos-app-bundle] at the Apple Developer site.
> Tip: The `png2icns` tool can create icns files from PNG files. See the `icnsutils` package for Debian-based systems.
### Windows Apps
You would typically create a resource script file (`*.rc`) with information about the app as well as an icon. Since you should have MinGW-w64 readily available then you can compile the file using `windres` and link it into your program. If you instead use Visual C++ then look into the [Windows Resource Compiler][win32-rc].
The directory structure could look like this:
```
my-project/
├── icons/
| ├── application.ico
| └── window.ico
├── basic.cc
└── resources.rc
```
`resources.rc`:
```
100 ICON "icons\\application.ico"
32512 ICON "icons\\window.ico"
```
> **Note:** The ID of the icon resource to be used for the window must be `32512` (`IDI_APPLICATION`).
## Limitations
### Browser Features
Since a browser engine is not a full web browser it may not support every feature you may expect from a browser. If you find that a feature does not work as expected then please consult with the browser engine's documentation and [open an issue on webview library][issues-new] if you think that the library should support it.
For example, the `webview` library does not attempt to support user interaction features like `alert()`, `confirm()` and `prompt()` and other non-essential features like `console.log()`.
## Contributing
1. Fork it (<https://github.com/naqvis/webview/fork>)
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request
## Contributors
- [Ali Naqvi](https://github.com/naqvis) - creator and maintainer
[macos-app-bundle]: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html
[gtk]: https://docs.gtk.org/gtk3/
[issues-new]: https://github.com/webview/webview/issues/new
[webkit]: https://webkit.org/
[webkitgtk]: https://webkitgtk.org/
[ms-webview2]: https://developer.microsoft.com/en-us/microsoft-edge/webview2/
[ms-webview2-sdk]: https://www.nuget.org/packages/Microsoft.Web.WebView2
[ms-webview2-rt]: https://developer.microsoft.com/en-us/microsoft-edge/webview2/
[win32-api]: https://docs.microsoft.com/en-us/windows/win32/apiindex/windows-api-list
[win32-rc]: https://docs.microsoft.com/en-us/windows/win32/menurc/resource-compiler
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.2.2- Tagged
- Jun 24, 2026
- Commit
8b4fd395d250- Indexed
- not yet
Dependents
No indexed shard depends on this one yet.
Repository
github.com/naqvis/webview
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 13, 2026
- Synced
- Aug 13, 2026
- Versions
- 13