{"id":13727895,"url":"https://github.com/naqvis/webview","last_synced_at":"2025-04-15T16:43:04.349Z","repository":{"id":45114783,"uuid":"266604114","full_name":"naqvis/webview","owner":"naqvis","description":"Crystal bindings to Webview library","archived":false,"fork":false,"pushed_at":"2023-04-24T06:44:40.000Z","size":128,"stargazers_count":96,"open_issues_count":3,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-28T22:35:13.698Z","etag":null,"topics":["crystal","crystal-bindings","crystal-lang","crystal-language","shard","webview","webview-library"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/naqvis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-05-24T18:48:35.000Z","updated_at":"2025-01-07T11:27:53.000Z","dependencies_parsed_at":"2024-01-07T16:30:16.892Z","dependency_job_id":null,"html_url":"https://github.com/naqvis/webview","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naqvis%2Fwebview","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naqvis%2Fwebview/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naqvis%2Fwebview/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naqvis%2Fwebview/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/naqvis","download_url":"https://codeload.github.com/naqvis/webview/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249110608,"owners_count":21214362,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crystal","crystal-bindings","crystal-lang","crystal-language","shard","webview","webview-library"],"created_at":"2024-08-03T02:00:34.593Z","updated_at":"2025-04-15T16:43:04.333Z","avatar_url":"https://github.com/naqvis.png","language":"C++","funding_links":[],"categories":["C++","👓 Alternatives to the [Electron.js](https://electronjs.org) ⚛"],"sub_categories":["Crystal"],"readme":"[![Linux CI](https://github.com/naqvis/webview/actions/workflows/linux.yml/badge.svg)](https://github.com/naqvis/webview/actions/workflows/linux.yml)\n[![MacOSX CI](https://github.com/naqvis/webview/actions/workflows/macos.yml/badge.svg)](https://github.com/naqvis/webview/actions/workflows/macos.yml)\n[![Windows CI](https://github.com/naqvis/webview/actions/workflows/windows.yml/badge.svg)](https://github.com/naqvis/webview/actions/workflows/windows.yml)\n# Crystal Webview\n\nCrystal 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.\n\n**Webview** relys 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.\n\nThis 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 \u0026 4 for samples on how to invoke Crystal functions from JS).\n\nWebview-supported platforms and the engines you can expect to render your application content are as follows:\n\n| Operating System | Browser Engine Used |\n| ---------------- | ------------------- |\n| macOS            | Cocoa, [WebKit][webkit] |\n| Linux            | [GTK 3][gtk], [WebKitGTK][webkitgtk]|\n| Windows          | [Windows API][win32-api], [WebView2][ms-webview2]  |\n\n## Pre-requisite\nIf 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.\n\nDebian-based systems:\n\n* Packages:\n  * Development: `apt install libgtk-3-dev libwebkit2gtk-4.0-dev`\n  * Production: `apt install libgtk-3-0 libwebkit2gtk-4.0-37`\n\nBSD-based systems:\n\n* FreeBSD packages: `pkg install webkit2-gtk3`\n* 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.\n\nMicrosoft Windows:\n\n* You should have Visual C++ Build tools already as it's a pre-requisite for crystal compiler\n* `git clone https://github.com/webview/webview` to get WebView sources\n* `webview\\script\\build.bat` to compile them (it will download required nuget package)\n* copy `webview\\dll\\x64\\webview.lib` to `\u003cyour crystal installation\u003e\\lib`\n* copy `webview\\dll\\x64\\webview.dll` to directory with your program\n  \n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n   ```yaml\n   dependencies:\n     webview:\n       github: naqvis/webview\n   ```\n\n2. Run `shards install`\n\n## Usage\n\n### Example 1: Loading URL\n\n```crystal\nrequire \"webview\"\n\nwv = Webview.window(640, 480, Webview::SizeHints::NONE, \"Hello WebView\", \"http://crystal-lang.org\")\nwv.run\nwv.destroy\n```\n\n### Example 2: Loading HTML\n\n```crystal\nrequire \"webview\"\n\nhtml = \u003c\u003c-HTML\n\u003c!DOCTYPE html\u003e\u003chtml lang=\"en-US\"\u003e\n\u003chead\u003e\n\u003ctitle\u003eHello,World!\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n\u003cdiv class=\"container\"\u003e\n\u003cheader\u003e\n\t\u003c!-- Logo --\u003e\n   \u003ch1\u003eCity Gallery\u003c/h1\u003e\n\u003c/header\u003e\n\u003cnav\u003e\n  \u003cul\u003e\n    \u003cli\u003e\u003ca href=\"/London\"\u003eLondon\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"/Paris\"\u003eParis\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"/Tokyo\"\u003eTokyo\u003c/a\u003e\u003c/li\u003e\n  \u003c/ul\u003e\n\u003c/nav\u003e\n\u003carticle\u003e\n  \u003ch1\u003eLondon\u003c/h1\u003e\n  \u003cimg src=\"pic_mountain.jpg\" alt=\"Mountain View\" style=\"width:304px;height:228px;\"\u003e\n  \u003cp\u003eLondon 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.\u003c/p\u003e\n  \u003cp\u003eStanding 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.\u003c/p\u003e\n\u003c/article\u003e\n\u003cfooter\u003eCopyright \u0026copy; W3Schools.com\u003c/footer\u003e\n\u003c/div\u003e\n\u003c/body\u003e\n\u003c/html\u003e\nHTML\n\nwv = Webview.window(640, 480, Webview::SizeHints::NONE, \"Hello WebView\")\nwv.html = html\nwv.run\nwv.destroy\n```\n\n### Example 3: Calling Crystal code from JavaScript\n```crystal\nrequire \"webview\"\n\nhtml = \u003c\u003c-HTML\n\u003c!doctype html\u003e\n\u003chtml\u003e\n  \u003cbody\u003ehello\u003c/body\u003e\n  \u003cscript\u003e\n    window.onload = function() {\n      document.body.innerText = \"Javascript calling Crystal code\";\n      noop().then(function(res) {\n        console.log('noop res', res);\n        add(1, 2).then(function(res) {\n          console.log('add res', res);\n        });\n      });\n    };\n  \u003c/script\u003e\n\u003c/html\u003e\nHTML\n\nwv = Webview.window(640, 480, Webview::SizeHints::NONE, \"Hello WebView\", true)\nwv.html = html\nwv.bind(\"noop\", Webview::JSProc.new { |a|\n  pp \"Noop called with arguments: #{a}\"\n  JSON::Any.new(\"noop\")\n})\n\nwv.bind(\"add\", Webview::JSProc.new { |a|\n  pp \"add called with arguments: #{a}\"\n  ret = 0_i64\n  a.each do |v|\n    ret += v.as_i64\n  end\n  JSON::Any.new(ret)\n})\n\n\nwv.run\nwv.destroy\n```\n\n### Example 4: Calling Crystal code from JavaScript and executing JavaScript from Crystal\n\n```crystal\nrequire \"webview\"\n\nhtml = \u003c\u003c-HTML\n\u003c!DOCTYPE html\u003e\u003chtml lang=\"en-US\"\u003e\n\u003chead\u003e\n\u003ctitle\u003eHello,World!\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003cbutton onClick=\"add(document.body.children.length)\"\u003eAdd\u003c/button\u003e\n\u003c/body\u003e\n\u003c/html\u003e\nHTML\n\n\ninject = \u003c\u003c-JS\n  elem = document.createElement('div');  \n  elem.innerHTML = \"hello webview %s\";\n  document.body.appendChild(elem);\nJS\n\nwv = Webview.window(640, 480, Webview::SizeHints::NONE, \"Hello WebView\", true)\nwv.html = html\n\nwv.bind(\"add\", Webview::JSProc.new { |n|\n  wv.eval(sprintf(inject, n))\n  JSON::Any.new(nil)\n})\n\nwv.run\nwv.destroy\n```\n\n### Example 5: Running your web app in another thread\n\n```crystal\nThread.new do\n  get \"/\" do\n    \"hello from kemal\"\n  end\n  Kemal.run\nend\n\nwv = Webview.window(640, 480, Webview::SizeHints::NONE, \"WebView with local webapp!\", \"http://localhost:3000\")\nwv.run\nwv.destroy\n```\n\n## App Distribution\n\nDistribution of your app is outside the scope of this library but we can give some pointers for you to explore.\n\n### macOS Application Bundle\n\nOn macOS you would typically create a bundle for your app with an icon and proper metadata.\n\nA minimalistic bundle typically has the following directory structure:\n\n```\nexample.app                 bundle\n└── Contents\n    ├── Info.plist          information property list\n    ├── MacOS\n    |   └── example         executable\n    └── Resources\n        └── example.icns    icon\n```\n\nRead more about the [structure of bundles][macos-app-bundle] at the Apple Developer site.\n\n\u003e Tip: The `png2icns` tool can create icns files from PNG files. See the `icnsutils` package for Debian-based systems.\n\n### Windows Apps\n\nYou 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].\n\nThe directory structure could look like this:\n\n```\nmy-project/\n├── icons/\n|   ├── application.ico\n|   └── window.ico\n├── basic.cc\n└── resources.rc\n```\n\n`resources.rc`:\n```\n100 ICON \"icons\\\\application.ico\"\n32512 ICON \"icons\\\\window.ico\"\n```\n\n\u003e **Note:** The ID of the icon resource to be used for the window must be `32512` (`IDI_APPLICATION`).\n\n## Limitations\n\n### Browser Features\n\nSince 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.\n\nFor 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()`.\n## Contributing\n\n1. Fork it (\u003chttps://github.com/naqvis/webview/fork\u003e)\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Ali Naqvi](https://github.com/naqvis) - creator and maintainer\n\n\n[macos-app-bundle]:  https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html\n[gtk]:               https://docs.gtk.org/gtk3/\n[issues-new]:        https://github.com/webview/webview/issues/new\n[webkit]:            https://webkit.org/\n[webkitgtk]:         https://webkitgtk.org/\n[ms-webview2]:       https://developer.microsoft.com/en-us/microsoft-edge/webview2/\n[ms-webview2-sdk]:   https://www.nuget.org/packages/Microsoft.Web.WebView2\n[ms-webview2-rt]:    https://developer.microsoft.com/en-us/microsoft-edge/webview2/\n[win32-api]:         https://docs.microsoft.com/en-us/windows/win32/apiindex/windows-api-list\n[win32-rc]:          https://docs.microsoft.com/en-us/windows/win32/menurc/resource-compiler","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnaqvis%2Fwebview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnaqvis%2Fwebview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnaqvis%2Fwebview/lists"}