{"id":1459,"date":"2023-11-10T17:31:06","date_gmt":"2023-11-10T17:31:06","guid":{"rendered":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/"},"modified":"2023-11-10T17:31:06","modified_gmt":"2023-11-10T17:31:06","slug":"webassembly-with-go-taking-web-apps-to-the-next-level","status":"publish","type":"post","link":"https:\/\/dev95.site\/ar\/webassembly-with-go-taking-web-apps-to-the-next-level\/","title":{"rendered":"WebAssembly with Go: Taking Web Apps to the Next Level"},"content":{"rendered":"<div id=\"dev95-3799705992\" class=\"dev95-- dev95-entity-placement\"><script async=\"async\" data-cfasync=\"false\" src=\"https:\/\/pl27862732.profitableratecpmnetwork.com\/2ad7a50e0bbc23ac6801d7b77c501463\/invoke.js\"><\/script>\r\n<div id=\"container-2ad7a50e0bbc23ac6801d7b77c501463\"><\/div><\/div><div>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/1000\/1%2Ab4sFFT3X6e0dVCvKAAtMIg.png?w=1280&#038;ssl=1\"><\/figure>\n<p>You might\u2019ve noticed the increasing chatter around <a href=\"https:\/\/webassembly.org\/\">WebAssembly (WASM)<\/a> in the dev community. Its potential is vast, and we\u2019ve found it invaluable in enhancing our open source\u00a0project!<\/p>\n<p>Hi everyone, I\u2019m part of the team behind <a href=\"https:\/\/github.com\/Permify\/permify\">Permify<\/a>, an open-source infra that helps developers to create and manage granular permissions throughout their applications.<\/p><div id=\"dev95-512639066\" class=\"dev95- dev95-entity-placement\"><center>\r\n<script>\r\n  atOptions = {\r\n    'key' : '4ba6b6513c00e0ba76511f798ae56401',\r\n    'format' : 'iframe',\r\n    'height' : 50,\r\n    'width' : 320,\r\n    'params' : {}\r\n  };\r\n<\/script>\r\n<script src=\"https:\/\/www.highrevenueformat.com\/4ba6b6513c00e0ba76511f798ae56401\/invoke.js\"><\/script>\r\n\t<\/center><\/div>\n<p>In this article, I\u2019ll demonstrate why and how we integrated WebAssembly (WASM) into our <a href=\"https:\/\/play.permify.co\/\">Playground<\/a> and gained benefits from its collaboration with\u00a0Golang.<\/p>\n<p>What does this playground do? Well, without diving too deep, its a interactive module of Permify which used for creating and testing authorization models.<\/p>\n<p>Throughout this post, I\u2019ll be\u00a0sharing:<\/p>\n<ul>\n<li><strong><em>A brief explanation of WASM and the benefits of using it with\u00a0Go.<\/em><\/strong><\/li>\n<li><strong><em>A peek into what spurred our choice to integrate WASM in\u00a0Permify.<\/em><\/strong><\/li>\n<li><strong><em>WASM Implementation, including<\/em><\/strong><\/li>\n<li><strong><em>Quick Warm Up: WASM Implementation with\u00a0Go<\/em><\/strong><\/li>\n<li><strong><em>Deeper Dive: Permify\u2019s WASM Code Breakdown<\/em><\/strong><\/li>\n<li><strong><em>Frontend: Steps to Embed Go WASM in a React Application<\/em><\/strong><\/li>\n<\/ul>\n<p>By the end, you should have a clearer understanding of why and how we leveraged WASM\u2019s capabilities for our\u00a0project.<\/p>\n<h3>Understanding WebAssembly<\/h3>\n<p>WebAssembly (Wasm) has established itself as a pivotal technology, enabling quick and efficient code execution in web browsers and forming a robust bridge between web applications and the high-performance typically associated with native applications.<\/p>\n<h3>1. Unveiling WebAssembly:<\/h3>\n<p>Wasm acts as a low-level virtual machine, executing a compact binary code that\u2019s translated from high-level languages.<\/p>\n<p>Primary Advantages:<\/p>\n<ul>\n<li>Universal Browser Support: Thanks to its support from all major browsers, Wasm delivers consistent performance across diverse platforms.<\/li>\n<li>Near-Native Performance: Intentionally designed to execute binary code at a speed akin to native applications, Wasm enhances the responsiveness of web applications considerably.<\/li>\n<\/ul>\n<p>In our open-source project, Permify, we strategically incorporated Go (also known as Golang) into its foundational core, selecting it for its widely recognized static typing, concurrency handling, and performance optimization. When the development journey led us to craft the Permify Playground, WebAssembly stepped into the spotlight as a crucial\u00a0element.<\/p>\n<h3>2. Blending Go &amp; WebAssembly:<\/h3>\n<ul>\n<li>Characteristics of Go: Celebrated for its optimal performance and concurrency handling capabilities, Go has carved a sturdy standing within the developer community.<\/li>\n<li>Synergy with WebAssembly: The translation of Go code into WebAssembly enables developers to effectively utilize Go\u2019s robust performance and concurrency management directly within the browser, propelling the creation of powerful, efficient, and scalable web applications.<\/li>\n<\/ul>\n<p>Our journey isn\u2019t just about melding Go and WebAssembly. Moving forward, we\u2019ll unearth why Wasm was pinpointed as the technology of choice for the Permify Playground development and what significant benefits were reaped from this decision.<\/p>\n<h3>Why WebAssembly?<\/h3>\n<p>The inception of the Permify Playground brought with it a key question: How to showcase our capabilities without being entwined in the complexities and maintenance woes of traditional server architectures? WebAssembly appeared as a shining answer. Adopting this binary instruction format allowed us\u00a0to:<\/p>\n<ul>\n<li>Execute In-Browser: Permify\u2019s playground could operate straight within the browser, sidestepping server maintenance overheads and repetitive API calls, and notably, making ongoing maintenance a breeze in comparison to older server-based approaches.<\/li>\n<li>Achieve Peak Performance: Employing WebAssembly ensures that our Go application operates with a level of performance that competes with native applications, enhancing user interactions and bolstering response\u00a0times.<\/li>\n<\/ul>\n<h3>Harvesting Technical Benefits and Gathering User\u00a0Feedback<\/h3>\n<p>Utilizing WebAssembly in our Permify Playground led us down a path of discernible technical advantages and an embrace from the community:<\/p>\n<ul>\n<li>Swift Execution: By side-stepping server interactions and deploying WebAssembly in-browser, we\u2019ve been able to deliver ultra-fast response\u00a0times.<\/li>\n<li>Uncomplicated User Interface: Centralizing our playground in the browser, we\u2019ve dispelled complexities associated with multi-tool workflows, delivering a clean and straightforward user experience.<\/li>\n<li>Community Validation: The affirming feedback and positive reception from the developer community stand as validation of our technological choices and implementations.<\/li>\n<\/ul>\n<p>Join us in the following sections as we delve deeper into the technicalities, feedback, and learnings from our adventure, providing a thorough exploration of our endeavours with WebAssembly.<\/p>\n<h3>WASM Implementation with\u00a0Go<\/h3>\n<p>Before we explore Permify\u2019s use of WebAssembly (WASM) and Go, let\u2019s understand their combination in a sample app. What follows is a step-by-step guide to bringing them together, setting the stage for our deeper dive into Permify\u2019s implementation.<\/p>\n<h3>1. Transforming Go into WebAssembly:<\/h3>\n<ul>\n<li><strong>Steps:<\/strong><\/li>\n<\/ul>\n<ol>\n<li>To get started, ensure you\u2019ve set the WebAssembly build target in\u00a0Go:<\/li>\n<\/ol>\n<pre>GOOS=js GOARCH=wasm go build -o main.wasm main.go<\/pre>\n<ol>\n<li>Next, apply optimizations to reduce the file size and enhance performance:<\/li>\n<\/ol>\n<pre>wasm-opt main.wasm --enable-bulk-memory -Oz -o play.wasm<\/pre>\n<ul>\n<li><strong>Handling Events:<\/strong><\/li>\n<\/ul>\n<p>Suppose you want your Go function to react to a button click from your web\u00a0page:<\/p>\n<pre>package main<br><br>import \"syscall\/js\"<br><br>func registerCallbacks() {<br>    js.Global().Set(\"handleClick\", js.FuncOf(handleClick))<br>}<br><br>func handleClick(this js.Value, inputs []js.Value) interface{} {<br>    println(\"Button clicked!\")<br>    return nil<br>}<\/pre>\n<p>In your HTML, after loading your WebAssembly module:<\/p>\n<pre>&lt;button onclick=\"window.handleClick()\"&gt;Click me&lt;\/button&gt;<\/pre>\n<h3>2. Integrating with Web\u00a0Pages:<\/h3>\n<ul>\n<li><strong>Initializing Wasm:<\/strong><\/li>\n<\/ul>\n<p>Ensure you have the wasm_exec.js script linked, then instantiate your Wasm\u00a0module:<\/p>\n<pre>&lt;script src=\"wasm_exec.js\"&gt;&lt;\/script&gt;<br>&lt;script&gt;<br>    const go = new Go();<br>    WebAssembly.instantiateStreaming(fetch(\"play.wasm\"), go.importObject).then((result) =&gt; {<br>        go.run(result.instance);<br>    });<br>&lt;\/script&gt;<\/pre>\n<ul>\n<li><strong>Interacting with the\u00a0DOM:<\/strong><\/li>\n<\/ul>\n<p>Accessing and modifying web elements is fundamental. For instance, changing the content of a paragraph element from Go would look something like\u00a0this:<\/p>\n<pre>func updateDOMContent() {<br>    document := js.Global().Get(\"document\")<br>    element := document.Call(\"getElementById\", \"myParagraph\")<br>    element.Set(\"innerText\", \"Updated content from Go!\")<br>}<\/pre>\n<h3>3. The Gains: Efficiency &amp;\u00a0Speed:<\/h3>\n<ul>\n<li><strong>Go\u2019s Goroutines in the\u00a0Browser:<\/strong><\/li>\n<\/ul>\n<p>Imagine having multiple data fetch operations that can run simultaneously without blocking the main\u00a0thread:<\/p>\n<pre>func fetchData(url string, ch chan string) {<br>    \/\/ Simulate data fetch.<br>    ch &lt;- \"Data from \" + url<br>}<br><br>func main() {<br>    ch := make(chan string)<br>    go fetchData(\"&lt;https:\/\/api.example1.com&gt;\", ch)<br>    go fetchData(\"&lt;https:\/\/api.example2.com&gt;\", ch)<br><br>    data1 := &lt;-ch<br>    data2 := &lt;-ch<br>    println(data1, data2)<br>}<\/pre>\n<p>Navigating through Go and WebAssembly (WASM) showcases a powerful union, merging Go\u2019s concurrent processing with WASM\u2019s rapid client-side execution. The depth explored in our sample app lights the way forward into Permify, where we apply these technological strengths into a scalable, real-world authorization system.<\/p>\n<h3>Deeper Dive: Permify\u2019s WASM Code Breakdown<\/h3>\n<p>Let\u2019s dive a bit deeper into the heart of our WebAssembly integration by exploring the key segments of our Go-based WASM\u00a0code.<\/p>\n<h3>1. Setting up the Go-to-WASM Environment<\/h3>\n<p>involves preparing and specifying our Go code to be compiled for a WebAssembly runtime.<\/p>\n<pre>\/\/ go:build wasm<br>\/\/ +build wasm<\/pre>\n<p>These lines serve as directives to the Go compiler, signaling that the following code is designated for a WebAssembly runtime environment. Specifically:<\/p>\n<ul>\n<li>\/\/go:build wasm: A build constraint ensuring the code is compiled only for WASM targets, adhering to modern\u00a0syntax.<\/li>\n<li>\/\/ +build wasm: An analogous constraint, utilizing older syntax for compatibility with prior Go versions.<\/li>\n<\/ul>\n<p>In essence, these directives guide the compiler to include this code segment only when compiling for a WebAssembly architecture, ensuring an appropriate setup and function within this specific\u00a0runtime.<\/p>\n<h3>2. Bridging JavaScript and Go with the run\u00a0Function<\/h3>\n<pre>package main<br><br>import (<br> \"context\"<br> \"encoding\/json\"<br> \"syscall\/js\"<br><br> \"google.golang.org\/protobuf\/encoding\/protojson\"<br><br> \"github.com\/Permify\/permify\/pkg\/development\"<br>)<br><br>var dev *development.Development<br><br>func run() js.Func {<br>  \/\/ The `run` function returns a new JavaScript function<br>  \/\/ that wraps the Go function.<br> return js.FuncOf(func(this js.Value, args []js.Value) interface{} {<br><br>  \/\/ t will be used to store the unmarshaled JSON data.<br>  \/\/ The use of an empty interface{} type means it can hold any type of value.<br>  var t interface{}<br><br>  \/\/ Unmarshal JSON from JavaScript function argument (args[0]) to Go's data structure (map).<br>  \/\/ args[0].String() gets the JSON string from the JavaScript argument,<br>  \/\/ which is then converted to bytes and unmarshaled (parsed) into the map `t`.<br>  err := json.Unmarshal([]byte(args[0].String()), &amp;t)<br><br>  \/\/ If an error occurs during unmarshaling (parsing) the JSON,<br>  \/\/ it returns an array with the error message \"invalid JSON\" to JavaScript.<br>  if err != nil {<br>   return js.ValueOf([]interface{}{\"invalid JSON\"})<br>  }<br><br>  \/\/ Attempt to assert that the parsed JSON (`t`) is a map with string keys.<br>  \/\/ This step ensures that the unmarshaled JSON is of the expected type (map).<br>  input, ok := t.(map[string]interface{})<br><br>  \/\/ If the assertion is false (`ok` is false),<br>  \/\/ it returns an array with the error message \"invalid JSON\" to JavaScript.<br>  if !ok {<br>   return js.ValueOf([]interface{}{\"invalid JSON\"})<br>  }<br><br>  \/\/ Run the main logic of the application with the parsed input.<br>  \/\/ It\u2019s assumed that `dev.Run` processes `input` in some way and returns any errors encountered during that process.<br>  errors := dev.Run(context.Background(), input)<br><br>  \/\/ If no errors are present (the length of the `errors` slice is 0),<br>  \/\/ return an empty array to JavaScript to indicate success with no errors.<br>  if len(errors) == 0 {<br>   return js.ValueOf([]interface{}{})<br>  }<br><br>  \/\/ If there are errors, each error in the `errors` slice is marshaled (converted) to a JSON string.<br>  \/\/ `vs` is a slice that will store each of these JSON error strings.<br>  vs := make([]interface{}, 0, len(errors))<br><br>  \/\/ Iterate through each error in the `errors` slice.<br>  for _, r := range errors {<br>   \/\/ Convert the error `r` to a JSON string and store it in `result`.<br>   \/\/ If an error occurs during this marshaling, it returns an array with that error message to JavaScript.<br>   result, err := json.Marshal(r)<br>   if err != nil {<br>    return js.ValueOf([]interface{}{err.Error()})<br>   }<br>   \/\/ Add the JSON error string to the `vs` slice.<br>   vs = append(vs, string(result))<br>  }<br><br>  \/\/ Return the `vs` slice (containing all JSON error strings) to JavaScript.<br>  return js.ValueOf(vs)<br> })<br>}<\/pre>\n<p>Within the realm of Permify, the run function stands as a cornerstone, executing a crucial bridging operation between JavaScript inputs and Go&#8217;s processing capabilities. It orchestrates real-time data interchange in JSON format, safeguarding that Permify&#8217;s core functionalities are smoothly and instantaneously accessible via a browser interface.<\/p>\n<p>Digging into\u00a0run:<\/p>\n<ul>\n<li>JSON Data Interchange: Translating JavaScript inputs into a format utilizable by Go, the function unmarshals JSON, transferring data between JS and Go, assuring that the robust processing capabilities of Go can seamlessly manipulate browser-sourced inputs.<\/li>\n<li>Error Handling: Ensuring clarity and user-awareness, it conducts meticulous error-checking during data parsing and processing, returning relevant error messages back to the JavaScript environment to ensure user-friendly interactions.<\/li>\n<li>Contextual Processing: By employing dev.Run, it processes the parsed input within a certain context, managing application logic while handling potential errors to assure steady data management and user feedback.<\/li>\n<li>Bidirectional Communication: As errors are marshaled back into JSON format and returned to JavaScript, the function ensures a two-way data flow, keeping both environments in synchronized harmony.<\/li>\n<\/ul>\n<p>Thus, through adeptly managing data, error-handling, and ensuring a fluid two-way communication channel, run serves as an integral bridge, linking JavaScript and Go to ensure the smooth, real-time operation of Permify within a browser interface. This facilitation of interaction not only heightens user experience but also leverages the respective strengths of JavaScript and Go within the Permify environment.<\/p>\n<h3>3. Main Execution and Initialization<\/h3>\n<pre>\/\/ Continuing from the previously discussed code...<br><br>func main() {<br>  \/\/ Instantiate a channel, 'ch', with no buffer, acting as a synchronization point for the goroutine.<br>  ch := make(chan struct{}, 0)<br><br>  \/\/ Create a new instance of 'Container' from the 'development' package and assign it to the global variable 'dev'.<br>  dev = development.NewContainer()<br><br>  \/\/ Attach the previously defined 'run' function to the global JavaScript object,<br>  \/\/ making it callable from the JavaScript environment.<br>  js.Global().Set(\"run\", run())<br><br>  \/\/ Utilize a channel receive expression to halt the 'main' goroutine, preventing the program from terminating.<br>  &lt;-ch<br>}<\/pre>\n<ol>\n<li>ch\u00a0:= make(chan struct{}, 0): A synchronization channel is created to coordinate the activity of goroutines (concurrent threads in\u00a0Go).<\/li>\n<li>dev = development.NewContainer(): Initializes a new container instance from the development package and assigns it to\u00a0dev.<\/li>\n<li>js.Global().Set(&#8220;run&#8221;, run()): Exposes the Go run function to the global JavaScript context, enabling JavaScript to call Go functions.<\/li>\n<li>&lt;-ch: Halts the main goroutine indefinitely, ensuring that the Go WebAssembly module remains active in the JavaScript environment.<\/li>\n<\/ol>\n<p>In summary, the code establishes a Go environment running within WebAssembly that exposes specific functionality (run function) to the JavaScript side and keeps itself active and available for function calls from JavaScript.<\/p>\n<h3>Building the Go Code into a WASM\u00a0Module<\/h3>\n<p>Before we delve into Permify\u2019s rich functionalities, it\u2019s paramount to elucidate the steps of converting our Go code into a WASM module, priming it for browser execution.<\/p>\n<p>For enthusiasts eager to delve deep into the complete Go codebase, don\u2019t hesitate to browse our GitHub repository: <a href=\"https:\/\/github.com\/Permify\/permify\/tree\/master\/pkg\/development\">Permify Wasm\u00a0Code<\/a>.<\/p>\n<h3>1. Compiling to\u00a0WASM<\/h3>\n<p>Kickstart the transformation of our Go application into a WASM binary with this\u00a0command:<\/p>\n<pre>GOOS=js GOARCH=wasm go build -o permify.wasm main.go<\/pre>\n<p>This directive cues the Go compiler to churn out a\u00a0.wasm binary attuned for JavaScript environments, with main.go as the source. The output, permify.wasm, is a concise rendition of our Go capabilities, primed for web deployment.<\/p>\n<h3>2. WASM Exec\u00a0JS<\/h3>\n<p>In conjunction with the WASM binary, the Go ecosystem offers an indispensable JavaScript piece named wasm_exec.js. It&#8217;s pivotal for initializing and facilitating our WASM module within a browser setting. You can typically locate this essential script inside the Go installation, under misc\/wasm.<\/p>\n<p>However, to streamline your journey, we\u2019ve hosted wasm_exec.js right here for direct access: <a href=\"https:\/\/github.com\/Permify\/permify\/tree\/master\/playground\/src\/loadWasm\">wasm_exec<\/a>.<\/p>\n<pre>cp \"$(go env GOROOT)\/misc\/wasm\/wasm_exec.js\" .<\/pre>\n<p>Equipped with these pivotal assets\u200a\u2014\u200athe WASM binary and its companion JavaScript\u200a\u2014\u200athe stage is set for its amalgamation into our frontend.<\/p>\n<h3>Steps to Embed Go WASM in a React Application<\/h3>\n<h3>1. Setting Up the React Application Structure<\/h3>\n<p>To kick things off, ensure you have a directory structure that clearly separates your WebAssembly-related code from the rest of your application. Based on your given structure, the loadWasm folder seems to be where all the magic\u00a0happens:<\/p>\n<pre>loadWasm\/<br>\u2502<br>\u251c\u2500\u2500 index.tsx            \/\/ Your main React component that integrates WASM.<br>\u251c\u2500\u2500 wasm_exec.js         \/\/ Provided by Go, bridges the gap between Go's WASM and JS.<br>\u2514\u2500\u2500 wasmTypes.d.ts       \/\/ TypeScript type declarations for WebAssembly.<\/pre>\n<p>To view the complete structure and delve into the specifics of each file, refer to the <a href=\"https:\/\/github.com\/Permify\/permify\/tree\/master\/playground\/src\/loadWasm\">Permify Playground on\u00a0GitHub<\/a>.<\/p>\n<h3>2. Establishing Type Declarations<\/h3>\n<p>Inside the wasmTypes.d.ts, global type declarations are made which expand upon the Window interface to acknowledge the new methods brought in by Go&#8217;s WebAssembly:<\/p>\n<pre>declare global {<br>  export interface Window {<br>    Go: any;<br>    run: (shape: string) =&gt; any[];<br>  }<br>}<br>export {};<\/pre>\n<p>This ensures TypeScript recognizes the Go constructor and the run method when called on the global window\u00a0object.<\/p>\n<h3>3. Preparing the WebAssembly Loader<\/h3>\n<p>In index.tsx, several critical tasks are accomplished:<\/p>\n<ul>\n<li><strong>Import Dependencies:<\/strong> First off, we import the required JS and TypeScript declarations:<\/li>\n<\/ul>\n<pre>import \".\/wasm_exec.js\";<br>import \".\/wasmTypes.d.ts\";<\/pre>\n<ul>\n<li><strong>WebAssembly Initialization:<\/strong> The asynchronous function loadWasm takes care of the entire\u00a0process:<\/li>\n<\/ul>\n<pre>async function loadWasm(): Promise&lt;void&gt; {<br>  const goWasm = new window.Go();<br>  const result = await WebAssembly.instantiateStreaming(<br>    fetch(\"play.wasm\"),<br>    goWasm.importObject<br>  );<br>  goWasm.run(result.instance);<br>}<\/pre>\n<p>Here, new window.Go() initializes the Go WASM environment. WebAssembly.instantiateStreaming fetches the WASM module, compiles it, and creates an instance. Finally, goWasm.run activates the WASM\u00a0module.<\/p>\n<ul>\n<li><strong>React Component with Loader UI:<\/strong> The LoadWasm component uses the useEffect hook to asynchronously load the WebAssembly when the component mounts:<\/li>\n<\/ul>\n<pre>export const LoadWasm: React.FC&lt;React.PropsWithChildren&lt;{}&gt;&gt; = (props) =&gt; {<br>  const [isLoading, setIsLoading] = React.useState(true);<br><br>  useEffect(() =&gt; {<br>    loadWasm().then(() =&gt; {<br>      setIsLoading(false);<br>    });<br>  }, []);<br><br>  if (isLoading) {<br>    return (<br>      &lt;div className=\"wasm-loader-background h-screen\"&gt;<br>        &lt;div className=\"center-of-screen\"&gt;<br>          &lt;SVG src={toAbsoluteUrl(\"\/media\/svg\/rocket.svg\")} \/&gt;<br>        &lt;\/div&gt;<br>      &lt;\/div&gt;<br>    );<br>  } else {<br>    return &lt;React.Fragment&gt;{props.children}&lt;\/React.Fragment&gt;;<br>  }<br>};<\/pre>\n<p>While loading, SVG rocket is displayed to indicate that initialization is ongoing. This feedback is crucial as users might otherwise be uncertain about what\u2019s transpiring behind the scenes. Once loading completes, children components or content will\u00a0render.<\/p>\n<h3>4. Calling WebAssembly Functions<\/h3>\n<p>Given your Go WASM exposes a method named run, you can invoke it as\u00a0follows:<\/p>\n<pre>function Run(shape) {<br>  return new Promise((resolve) =&gt; {<br>    let res = window.run(shape);<br>    resolve(res);<br>  });<br>}<\/pre>\n<p>This function essentially acts as a bridge, allowing the React frontend to communicate with the Go backend logic encapsulated in the\u00a0WASM.<\/p>\n<h3>5. Implementing the Run Button in\u00a0React<\/h3>\n<p>To integrate a button that triggers the WebAssembly function when clicked, follow these\u00a0steps:<\/p>\n<ol>\n<li><strong>Creating the Button Component<\/strong><\/li>\n<\/ol>\n<p>First, we\u2019ll create a simple React component with a\u00a0button:<\/p>\n<pre>import React from \"react\";<br><br>type RunButtonProps = {<br>  shape: string;<br>  onResult: (result: any[]) =&gt; void;<br>};<br><br>function RunButton({ shape, onResult }: RunButtonProps) {<br>  const handleClick = async () =&gt; {<br>    let result = await Run(shape);<br>    onResult(result);<br>  };<br><br>  return &lt;button onClick={handleClick}&gt;Run WebAssembly&lt;\/button&gt;;<br>}<\/pre>\n<p>In the code above, the RunButton component accepts two\u00a0props:<\/p>\n<ul>\n<li>shape: The shape argument to pass to the WebAssembly run function.<\/li>\n<li>onResult: A callback function that receives the result of the WebAssembly function and can be used to update the state or display the result in the\u00a0UI.<\/li>\n<\/ul>\n<ol>\n<li>Integrating the Button in the Main Component<\/li>\n<\/ol>\n<p>Now, in your main component (or wherever you\u2019d like to place the button), integrate the RunButton:<\/p>\n<pre>import React, { useState } from \"react\";<br>import RunButton from \".\/path_to_RunButton_component\"; \/\/ Replace with the actual path<br><br>function App() {<br>  const [result, setResult] = useState&lt;any[]&gt;([]);<br><br>  \/\/ Define the shape content<br>  const shapeContent = {<br>    schema: `|-<br>    entity user {}<br><br>    entity account {<br>        relation owner @user<br>        relation following @user<br>        relation follower @user<br><br>        attribute public boolean<br>        action view = (owner or follower) or public  <br>    }<br><br>    entity post {<br>        relation account @account<br><br>        attribute restricted boolean<br><br>        action view = account.view<br><br>        action comment = account.following not restricted<br>        action like = account.following not restricted<br>    }`,<br>    relationships: [<br>      \"account:1#owner@user:kevin\",<br>      \"account:2#owner@user:george\",<br>      \"account:1#following@user:george\",<br>      \"account:2#follower@user:kevin\",<br>      \"post:1#account@account:1\",<br>      \"post:2#account@account:2\",<br>    ],<br>    attributes: [<br>      \"account:1$public|boolean:true\",<br>      \"account:2$public|boolean:false\",<br>      \"post:1$restricted|boolean:false\",<br>      \"post:2$restricted|boolean:true\",<br>    ],<br>    scenarios: [<br>      {<br>        name: \"Account Viewing Permissions\",<br>        description:<br>          \"Evaluate account viewing permissions for 'kevin' and 'george'.\",<br>        checks: [<br>          {<br>            entity: \"account:1\",<br>            subject: \"user:kevin\",<br>            assertions: {<br>              view: true,<br>            },<br>          },<br>        ],<br>      },<br>    ],<br>  };<br><br>  return (<br>    &lt;div&gt;<br>      &lt;RunButton shape={JSON.stringify(shapeContent)} onResult={setResult} \/&gt;<br>      &lt;div&gt;<br>        Results:<br>        &lt;ul&gt;<br>          {result.map((item, index) =&gt; (<br>            &lt;li key={index}&gt;{item}&lt;\/li&gt;<br>          ))}<br>        &lt;\/ul&gt;<br>      &lt;\/div&gt;<br>    &lt;\/div&gt;<br>  );<br>}<\/pre>\n<p>In this example, App is a component that contains the RunButton. When the button is clicked, the result from the WebAssembly function is displayed in a list below the\u00a0button.<\/p>\n<h3>Conclusion<\/h3>\n<p>Throughout this exploration, the integration of WebAssembly with Go was unfolded, illuminating the pathway toward enhanced web development and optimal user interactions within browsers.<\/p>\n<p>The journey involved setting up the Go environment, converting Go code to WebAssembly, and executing it within a web context, ultimately giving life to the interactive platform showcased at <a href=\"https:\/\/play.permify.co\/\">play.permify.co<\/a>.<\/p>\n<p>This platform stands not only as an example but also as a beacon, illustrating the concrete and potent capabilities achievable when intertwining these technological domains.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/medium.com\/_\/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=8d81fccd8250\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<hr>\n<p><a href=\"https:\/\/medium.com\/better-programming\/webassembly-with-go-taking-web-apps-to-the-next-level-8d81fccd8250\">WebAssembly with Go: Taking Web Apps to the Next Level<\/a> was originally published in <a href=\"https:\/\/betterprogramming.pub\/\">Better Programming<\/a> on Medium, where people are continuing the conversation by highlighting and responding to this story.<\/p>\n<\/div>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_1459\" class=\"pvc_stats total_only  \" data-element-id=\"1459\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" version=\"1.0\" viewBox=\"0 0 502 315\" preserveAspectRatio=\"xMidYMid meet\"><g transform=\"translate(0,332) scale(0.1,-0.1)\" fill=\"\" stroke=\"none\"><path d=\"M2394 3279 l-29 -30 -3 -207 c-2 -182 0 -211 15 -242 39 -76 157 -76 196 0 15 31 17 60 15 243 l-3 209 -33 29 c-26 23 -41 29 -80 29 -41 0 -53 -5 -78 -31z\"\/><path d=\"M3085 3251 c-45 -19 -58 -50 -96 -229 -47 -217 -49 -260 -13 -295 52 -53 146 -42 177 20 16 31 87 366 87 410 0 70 -86 122 -155 94z\"\/><path d=\"M1751 3234 c-13 -9 -29 -31 -37 -50 -12 -29 -10 -49 21 -204 19 -94 39 -189 45 -210 14 -50 54 -80 110 -80 34 0 48 6 76 34 21 21 34 44 34 59 0 14 -18 113 -40 219 -37 178 -43 195 -70 221 -36 32 -101 37 -139 11z\"\/><path d=\"M1163 3073 c-36 -7 -73 -59 -73 -102 0 -56 133 -378 171 -413 34 -32 83 -37 129 -13 70 36 67 87 -16 290 -86 209 -89 214 -129 231 -35 14 -42 15 -82 7z\"\/><path d=\"M3689 3066 c-15 -9 -33 -30 -42 -48 -48 -103 -147 -355 -147 -375 0 -98 131 -148 192 -74 13 15 57 108 97 206 80 196 84 226 37 273 -30 30 -99 39 -137 18z\"\/><path d=\"M583 2784 c-38 -19 -67 -74 -58 -113 9 -42 211 -354 242 -373 16 -10 45 -18 66 -18 51 0 107 52 107 100 0 39 -1 41 -124 234 -80 126 -108 162 -133 173 -41 17 -61 16 -100 -3z\"\/><path d=\"M4250 2784 c-14 -9 -74 -91 -133 -183 -95 -150 -107 -173 -107 -213 0 -55 33 -94 87 -104 67 -13 90 8 211 198 130 202 137 225 78 284 -27 27 -42 34 -72 34 -22 0 -50 -8 -64 -16z\"\/><path d=\"M2275 2693 c-553 -48 -1095 -270 -1585 -649 -135 -104 -459 -423 -483 -476 -23 -49 -22 -139 2 -186 73 -142 361 -457 571 -626 285 -228 642 -407 990 -497 242 -63 336 -73 660 -74 310 0 370 5 595 52 535 111 1045 392 1455 803 122 121 250 273 275 326 19 41 19 137 0 174 -41 79 -309 363 -465 492 -447 370 -946 591 -1479 653 -113 14 -422 18 -536 8z m395 -428 c171 -34 330 -124 456 -258 112 -119 167 -219 211 -378 27 -96 24 -300 -5 -401 -72 -255 -236 -447 -474 -557 -132 -62 -201 -76 -368 -76 -167 0 -236 14 -368 76 -213 98 -373 271 -451 485 -162 444 86 934 547 1084 153 49 292 57 452 25z m909 -232 c222 -123 408 -262 593 -441 76 -74 138 -139 138 -144 0 -16 -233 -242 -330 -319 -155 -123 -309 -223 -461 -299 l-81 -41 32 46 c18 26 49 83 70 128 143 306 141 649 -6 957 -25 52 -61 116 -79 142 l-34 47 45 -20 c26 -10 76 -36 113 -56z m-2057 25 c-40 -58 -105 -190 -130 -263 -110 -324 -59 -707 132 -981 25 -35 42 -64 37 -64 -19 0 -241 119 -326 174 -188 122 -406 314 -532 468 l-58 71 108 103 c185 178 428 349 672 473 66 33 121 60 123 61 2 0 -10 -19 -26 -42z\"\/><path d=\"M2375 1950 c-198 -44 -350 -190 -395 -379 -18 -76 -8 -221 19 -290 114 -284 457 -406 731 -260 98 52 188 154 231 260 27 69 37 214 19 290 -38 163 -166 304 -326 360 -67 23 -215 33 -279 19z\"\/><\/g><\/svg><\/i> <img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/i0.wp.com\/dev95.site\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif?resize=16%2C16&#038;ssl=1\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>You might\u2019ve noticed the increasing chatter around WebAssembly (WASM) in the dev community. Its potential is vast, and we\u2019ve found it invaluable in enhancing our open source\u00a0project! Hi everyone, I\u2019m part of the team behind Permify, an open-source infra that<\/p>\n<div class=\"hosteria-entry-more\"><a href=\"https:\/\/dev95.site\/ar\/webassembly-with-go-taking-web-apps-to-the-next-level\/\" class=\"no-underline font-light  group-hover:text-primary-800 dark:group-hover:text-primary-300 py-1\">Read more &gt;&gt;&gt;<\/a><\/div>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_1459\" class=\"pvc_stats total_only\" data-element-id=\"1459\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" version=\"1.0\" viewbox=\"0 0 502 315\" preserveaspectratio=\"xMidYMid meet\"><g transform=\"translate(0,332) scale(0.1,-0.1)\" fill=\"\" stroke=\"none\"><path d=\"M2394 3279 l-29 -30 -3 -207 c-2 -182 0 -211 15 -242 39 -76 157 -76 196 0 15 31 17 60 15 243 l-3 209 -33 29 c-26 23 -41 29 -80 29 -41 0 -53 -5 -78 -31z\"\/><path d=\"M3085 3251 c-45 -19 -58 -50 -96 -229 -47 -217 -49 -260 -13 -295 52 -53 146 -42 177 20 16 31 87 366 87 410 0 70 -86 122 -155 94z\"\/><path d=\"M1751 3234 c-13 -9 -29 -31 -37 -50 -12 -29 -10 -49 21 -204 19 -94 39 -189 45 -210 14 -50 54 -80 110 -80 34 0 48 6 76 34 21 21 34 44 34 59 0 14 -18 113 -40 219 -37 178 -43 195 -70 221 -36 32 -101 37 -139 11z\"\/><path d=\"M1163 3073 c-36 -7 -73 -59 -73 -102 0 -56 133 -378 171 -413 34 -32 83 -37 129 -13 70 36 67 87 -16 290 -86 209 -89 214 -129 231 -35 14 -42 15 -82 7z\"\/><path d=\"M3689 3066 c-15 -9 -33 -30 -42 -48 -48 -103 -147 -355 -147 -375 0 -98 131 -148 192 -74 13 15 57 108 97 206 80 196 84 226 37 273 -30 30 -99 39 -137 18z\"\/><path d=\"M583 2784 c-38 -19 -67 -74 -58 -113 9 -42 211 -354 242 -373 16 -10 45 -18 66 -18 51 0 107 52 107 100 0 39 -1 41 -124 234 -80 126 -108 162 -133 173 -41 17 -61 16 -100 -3z\"\/><path d=\"M4250 2784 c-14 -9 -74 -91 -133 -183 -95 -150 -107 -173 -107 -213 0 -55 33 -94 87 -104 67 -13 90 8 211 198 130 202 137 225 78 284 -27 27 -42 34 -72 34 -22 0 -50 -8 -64 -16z\"\/><path d=\"M2275 2693 c-553 -48 -1095 -270 -1585 -649 -135 -104 -459 -423 -483 -476 -23 -49 -22 -139 2 -186 73 -142 361 -457 571 -626 285 -228 642 -407 990 -497 242 -63 336 -73 660 -74 310 0 370 5 595 52 535 111 1045 392 1455 803 122 121 250 273 275 326 19 41 19 137 0 174 -41 79 -309 363 -465 492 -447 370 -946 591 -1479 653 -113 14 -422 18 -536 8z m395 -428 c171 -34 330 -124 456 -258 112 -119 167 -219 211 -378 27 -96 24 -300 -5 -401 -72 -255 -236 -447 -474 -557 -132 -62 -201 -76 -368 -76 -167 0 -236 14 -368 76 -213 98 -373 271 -451 485 -162 444 86 934 547 1084 153 49 292 57 452 25z m909 -232 c222 -123 408 -262 593 -441 76 -74 138 -139 138 -144 0 -16 -233 -242 -330 -319 -155 -123 -309 -223 -461 -299 l-81 -41 32 46 c18 26 49 83 70 128 143 306 141 649 -6 957 -25 52 -61 116 -79 142 l-34 47 45 -20 c26 -10 76 -36 113 -56z m-2057 25 c-40 -58 -105 -190 -130 -263 -110 -324 -59 -707 132 -981 25 -35 42 -64 37 -64 -19 0 -241 119 -326 174 -188 122 -406 314 -532 468 l-58 71 108 103 c185 178 428 349 672 473 66 33 121 60 123 61 2 0 -10 -19 -26 -42z\"\/><path d=\"M2375 1950 c-198 -44 -350 -190 -395 -379 -18 -76 -8 -221 19 -290 114 -284 457 -406 731 -260 98 52 188 154 231 260 27 69 37 214 19 290 -38 163 -166 304 -326 360 -67 23 -215 33 -279 19z\"\/><\/g><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/dev95.site\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=\"0\" \/><\/p>\n<div class=\"pvc_clear\"><\/div>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"fp_fajr_begins":"","fp_fajr_iqamah":"","fp_dhuhr_begins":"","fp_dhuhr_iqamah":"","fp_asr_begins":"","fp_asr_iqamah":"","fp_maghrib_begins":"","fp_maghrib_iqamah":"","fp_isha_begins":"","fp_isha_iqamah":"","fp_midnight":"","fp_midnight_name":"","fp_sunrise":"","fp_single_prayer_begins_title":"","fp_single_prayer_iqamah_title":"","fp_prayer_times_for_today":"","fp_hijra_date":"","fp_fajr_name":"","fp_dhuhr_name":"","fp_asr_name":"","fp_maghrib_name":"","fp_isha_name":"","fp_sunrise_name":"","fp_currentDate":"","fp_current_time":"","fp_current_title":"","fp_current_location":"","fp_masjid_name":"","fp_prayer_title":"","fp_next_prayer_iqamah_time":"","fp_next_prayer_iqamah_title":"","fp_next_prayer_begins_time":"","fp_next_prayer_begins_title":"","fp_next_prayer_title":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[37],"tags":[],"class_list":["post-1459","post","type-post","status-publish","format-standard","hentry","category-posts"],"a3_pvc":{"activated":true,"total_views":0,"today_views":0},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>WebAssembly with Go: Taking Web Apps to the Next Level - Dev95<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/dev95.site\/ar\/webassembly-with-go-taking-web-apps-to-the-next-level\/\" \/>\n<meta property=\"og:locale\" content=\"ar_AR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"WebAssembly with Go: Taking Web Apps to the Next Level - Dev95\" \/>\n<meta property=\"og:description\" content=\"You might\u2019ve noticed the increasing chatter around WebAssembly (WASM) in the dev community. Its potential is vast, and we\u2019ve found it invaluable in enhancing our open source\u00a0project! Hi everyone, I\u2019m part of the team behind Permify, an open-source infra thatRead more &gt;&gt;&gt;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/dev95.site\/ar\/webassembly-with-go-taking-web-apps-to-the-next-level\/\" \/>\n<meta property=\"og:site_name\" content=\"Dev95\" \/>\n<meta property=\"article:published_time\" content=\"2023-11-10T17:31:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn-images-1.medium.com\/max\/1000\/1*b4sFFT3X6e0dVCvKAAtMIg.png\" \/>\n<meta name=\"author\" content=\"dev95\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u0643\u064f\u062a\u0628 \u0628\u0648\u0627\u0633\u0637\u0629\" \/>\n\t<meta name=\"twitter:data1\" content=\"dev95\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u0648\u0642\u062a \u0627\u0644\u0642\u0631\u0627\u0621\u0629 \u0627\u0644\u0645\u064f\u0642\u062f\u0651\u0631\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 \u062f\u0642\u064a\u0642\u0629\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/\"},\"author\":{\"name\":\"dev95\",\"@id\":\"https:\\\/\\\/dev95.site\\\/#\\\/schema\\\/person\\\/b807805ffe2916206b04d0938bce0298\"},\"headline\":\"WebAssembly with Go: Taking Web Apps to the Next Level\",\"datePublished\":\"2023-11-10T17:31:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/\"},\"wordCount\":2106,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/dev95.site\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/cdn-images-1.medium.com\\\/max\\\/1000\\\/1*b4sFFT3X6e0dVCvKAAtMIg.png\",\"articleSection\":[\"Posts\"],\"inLanguage\":\"ar\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/\",\"url\":\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/\",\"name\":\"WebAssembly with Go: Taking Web Apps to the Next Level - Dev95\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/dev95.site\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/cdn-images-1.medium.com\\\/max\\\/1000\\\/1*b4sFFT3X6e0dVCvKAAtMIg.png\",\"datePublished\":\"2023-11-10T17:31:06+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/#breadcrumb\"},\"inLanguage\":\"ar\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ar\",\"@id\":\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/#primaryimage\",\"url\":\"https:\\\/\\\/cdn-images-1.medium.com\\\/max\\\/1000\\\/1*b4sFFT3X6e0dVCvKAAtMIg.png\",\"contentUrl\":\"https:\\\/\\\/cdn-images-1.medium.com\\\/max\\\/1000\\\/1*b4sFFT3X6e0dVCvKAAtMIg.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/dev95.site\\\/webassembly-with-go-taking-web-apps-to-the-next-level\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/dev95.site\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"WebAssembly with Go: Taking Web Apps to the Next Level\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/dev95.site\\\/#website\",\"url\":\"https:\\\/\\\/dev95.site\\\/\",\"name\":\"Dev95\",\"description\":\"A comprehensive platform for data and knowledge, delivering reliable content that meets the aspirations of readers and enthusiasts.\",\"publisher\":{\"@id\":\"https:\\\/\\\/dev95.site\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/dev95.site\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ar\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/dev95.site\\\/#organization\",\"name\":\"Dev95\",\"url\":\"https:\\\/\\\/dev95.site\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ar\",\"@id\":\"https:\\\/\\\/dev95.site\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/dev95.site\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/rbrrbr-6.png?fit=512%2C512&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/dev95.site\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/rbrrbr-6.png?fit=512%2C512&ssl=1\",\"width\":512,\"height\":512,\"caption\":\"Dev95\"},\"image\":{\"@id\":\"https:\\\/\\\/dev95.site\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/dev95.site\\\/#\\\/schema\\\/person\\\/b807805ffe2916206b04d0938bce0298\",\"name\":\"dev95\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ar\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a70a73d950838b20cd80d7ebdc955737e802e8cd896044c5473b32b946c0662a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a70a73d950838b20cd80d7ebdc955737e802e8cd896044c5473b32b946c0662a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a70a73d950838b20cd80d7ebdc955737e802e8cd896044c5473b32b946c0662a?s=96&d=mm&r=g\",\"caption\":\"dev95\"},\"url\":\"https:\\\/\\\/dev95.site\\\/ar\\\/author\\\/mohammad\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"WebAssembly with Go: Taking Web Apps to the Next Level - Dev95","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/dev95.site\/ar\/webassembly-with-go-taking-web-apps-to-the-next-level\/","og_locale":"ar_AR","og_type":"article","og_title":"WebAssembly with Go: Taking Web Apps to the Next Level - Dev95","og_description":"You might\u2019ve noticed the increasing chatter around WebAssembly (WASM) in the dev community. Its potential is vast, and we\u2019ve found it invaluable in enhancing our open source\u00a0project! Hi everyone, I\u2019m part of the team behind Permify, an open-source infra thatRead more &gt;&gt;&gt;","og_url":"https:\/\/dev95.site\/ar\/webassembly-with-go-taking-web-apps-to-the-next-level\/","og_site_name":"Dev95","article_published_time":"2023-11-10T17:31:06+00:00","og_image":[{"url":"https:\/\/cdn-images-1.medium.com\/max\/1000\/1*b4sFFT3X6e0dVCvKAAtMIg.png","type":"","width":"","height":""}],"author":"dev95","twitter_card":"summary_large_image","twitter_misc":{"\u0643\u064f\u062a\u0628 \u0628\u0648\u0627\u0633\u0637\u0629":"dev95","\u0648\u0642\u062a \u0627\u0644\u0642\u0631\u0627\u0621\u0629 \u0627\u0644\u0645\u064f\u0642\u062f\u0651\u0631":"16 \u062f\u0642\u064a\u0642\u0629"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/#article","isPartOf":{"@id":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/"},"author":{"name":"dev95","@id":"https:\/\/dev95.site\/#\/schema\/person\/b807805ffe2916206b04d0938bce0298"},"headline":"WebAssembly with Go: Taking Web Apps to the Next Level","datePublished":"2023-11-10T17:31:06+00:00","mainEntityOfPage":{"@id":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/"},"wordCount":2106,"commentCount":0,"publisher":{"@id":"https:\/\/dev95.site\/#organization"},"image":{"@id":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/#primaryimage"},"thumbnailUrl":"https:\/\/cdn-images-1.medium.com\/max\/1000\/1*b4sFFT3X6e0dVCvKAAtMIg.png","articleSection":["Posts"],"inLanguage":"ar","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/","url":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/","name":"WebAssembly with Go: Taking Web Apps to the Next Level - Dev95","isPartOf":{"@id":"https:\/\/dev95.site\/#website"},"primaryImageOfPage":{"@id":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/#primaryimage"},"image":{"@id":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/#primaryimage"},"thumbnailUrl":"https:\/\/cdn-images-1.medium.com\/max\/1000\/1*b4sFFT3X6e0dVCvKAAtMIg.png","datePublished":"2023-11-10T17:31:06+00:00","breadcrumb":{"@id":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/#breadcrumb"},"inLanguage":"ar","potentialAction":[{"@type":"ReadAction","target":["https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/"]}]},{"@type":"ImageObject","inLanguage":"ar","@id":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/#primaryimage","url":"https:\/\/cdn-images-1.medium.com\/max\/1000\/1*b4sFFT3X6e0dVCvKAAtMIg.png","contentUrl":"https:\/\/cdn-images-1.medium.com\/max\/1000\/1*b4sFFT3X6e0dVCvKAAtMIg.png"},{"@type":"BreadcrumbList","@id":"https:\/\/dev95.site\/webassembly-with-go-taking-web-apps-to-the-next-level\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/dev95.site\/"},{"@type":"ListItem","position":2,"name":"WebAssembly with Go: Taking Web Apps to the Next Level"}]},{"@type":"WebSite","@id":"https:\/\/dev95.site\/#website","url":"https:\/\/dev95.site\/","name":"Dev95","description":"A comprehensive platform for data and knowledge, delivering reliable content that meets the aspirations of readers and enthusiasts.","publisher":{"@id":"https:\/\/dev95.site\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/dev95.site\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ar"},{"@type":"Organization","@id":"https:\/\/dev95.site\/#organization","name":"Dev95","url":"https:\/\/dev95.site\/","logo":{"@type":"ImageObject","inLanguage":"ar","@id":"https:\/\/dev95.site\/#\/schema\/logo\/image\/","url":"https:\/\/i0.wp.com\/dev95.site\/wp-content\/uploads\/2026\/07\/rbrrbr-6.png?fit=512%2C512&ssl=1","contentUrl":"https:\/\/i0.wp.com\/dev95.site\/wp-content\/uploads\/2026\/07\/rbrrbr-6.png?fit=512%2C512&ssl=1","width":512,"height":512,"caption":"Dev95"},"image":{"@id":"https:\/\/dev95.site\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/dev95.site\/#\/schema\/person\/b807805ffe2916206b04d0938bce0298","name":"dev95","image":{"@type":"ImageObject","inLanguage":"ar","@id":"https:\/\/secure.gravatar.com\/avatar\/a70a73d950838b20cd80d7ebdc955737e802e8cd896044c5473b32b946c0662a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/a70a73d950838b20cd80d7ebdc955737e802e8cd896044c5473b32b946c0662a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a70a73d950838b20cd80d7ebdc955737e802e8cd896044c5473b32b946c0662a?s=96&d=mm&r=g","caption":"dev95"},"url":"https:\/\/dev95.site\/ar\/author\/mohammad\/"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/dev95.site\/ar\/wp-json\/wp\/v2\/posts\/1459","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev95.site\/ar\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev95.site\/ar\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev95.site\/ar\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev95.site\/ar\/wp-json\/wp\/v2\/comments?post=1459"}],"version-history":[{"count":0,"href":"https:\/\/dev95.site\/ar\/wp-json\/wp\/v2\/posts\/1459\/revisions"}],"wp:attachment":[{"href":"https:\/\/dev95.site\/ar\/wp-json\/wp\/v2\/media?parent=1459"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev95.site\/ar\/wp-json\/wp\/v2\/categories?post=1459"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev95.site\/ar\/wp-json\/wp\/v2\/tags?post=1459"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}