Go

 

Go for Web Assembly: Building Web Apps with GoLang

In the ever-evolving landscape of web development, performance, and versatility are key factors in creating successful web applications. To meet these demands, developers are constantly exploring new technologies and approaches. One such technology that has gained momentum in recent years is WebAssembly, or simply, WebAssembly. It allows you to run high-performance code in web browsers at near-native speed, opening up a world of possibilities for web application development.

Go for Web Assembly: Building Web Apps with GoLang

In this blog, we’ll explore how to harness the power of WebAssembly with GoLang, a statically typed and compiled programming language known for its performance and simplicity. By combining these two technologies, you can build web applications that are not only fast but also maintainable and efficient.

1. Why WebAssembly?

Before we dive into the details of using GoLang for WebAssembly, let’s take a moment to understand why WebAssembly is a game-changer in web development.

1.1. Performance

WebAssembly allows you to run code written in languages like C, C++, and Rust at near-native speed in web browsers. This is achieved by compiling high-level code into low-level binary code that can be executed by the browser’s JavaScript engine. As a result, web applications can handle complex calculations and graphics-intensive tasks with ease, delivering a smoother user experience.

1.2. Versatility

WebAssembly is not limited to a specific programming language. You can compile code from various languages into WebAssembly, making it a versatile choice for web development. This means you can leverage your existing skills and codebase while benefiting from the performance gains offered by WebAssembly.

1.3. Security

WebAssembly runs in a sandboxed environment within the browser, providing an additional layer of security. This ensures that code executed on the user’s machine doesn’t have direct access to the underlying system, making it safer to run untrusted code.

2. Getting Started with GoLang and WebAssembly

Now that we understand the advantages of WebAssembly, let’s explore how to use GoLang to build web applications that take full advantage of this technology.

2.1. Setting Up Your Development Environment

To get started, you’ll need to set up your development environment. Ensure you have GoLang installed, and then install the following tools:

2.1.1. Go WebAssembly Compiler (GopherJS)

GopherJS is a Go to JavaScript compiler that allows you to compile your Go code into JavaScript, making it compatible with WebAssembly. You can install it using the following command:

bash
go get -u github.com/gopherjs/gopherjs

2.1.2. WebAssembly Binary Toolkit (WABT)

WABT is a suite of tools for WebAssembly, including wat2wasm which we’ll use to convert WebAssembly Text (WAT) files to WebAssembly Binary (WASM) files. You can download and install it from the official GitHub repository: https://github.com/WebAssembly/wabt

2.2. Creating Your First GoLang WebAssembly Project

Let’s create a simple “Hello, WebAssembly!” example to get started. Create a new directory for your project and navigate to it:

bash
mkdir wasm-hello-world
cd wasm-hello-world

Next, create a Go file, for example, main.go, and add the following code:

go
package main

import "fmt"

func main() {
    fmt.Println("Hello, WebAssembly!")
}

Now, let’s compile this Go code into JavaScript using GopherJS:

bash
gopherjs build main.go

This will generate a JavaScript file named main.js in your project directory.

2.3. Converting GoLang to WebAssembly

To use WebAssembly, we need to convert our GoLang code into WebAssembly format. Start by installing WABT, as mentioned earlier. Once it’s installed, use the following command to convert the JavaScript output into WebAssembly:

bash
wasm2wat main.wasm -o main.wat

This command will generate a WebAssembly Text (WAT) file named main.wat.

2.4. Creating the HTML Page

Now that we have our WebAssembly code, let’s create an HTML file to load and run it in the browser. Create an HTML file, for example, index.html, and add the following code:

html
<!DOCTYPE html>
<html>
<head>
    <title>Hello WebAssembly</title>
</head>
<body>
    <h1>Hello from WebAssembly!</h1>
    <script src="main.js"></script>
</body>
</html>

This HTML file includes a reference to our main.js file, which will load and run our WebAssembly code.

2.5. Testing Your WebAssembly Application

Open a terminal, navigate to your project directory, and start a local server to serve your HTML file. You can use Python’s built-in HTTP server for this:

bash
python -m http.server

Now, open your web browser and go to http://localhost:8000/index.html. You should see “Hello from WebAssembly!” displayed in your browser’s console.

Congratulations! You’ve just created a simple WebAssembly application using GoLang.

3. Building a Real-World Web Application

While the “Hello, WebAssembly!” example is a great way to get started, let’s dive deeper into building a more complex web application using GoLang and WebAssembly. In this section, we’ll develop a basic task manager application.

3.1. Project Setup

Create a new directory for your project:

bash
mkdir wasm-task-manager
cd wasm-task-manager

Next, initialize a GoLang module for your project:

bash
go mod init wasm-task-manager

3.2. Creating the Task Struct

In our task manager application, we’ll define a Task struct to represent individual tasks. Create a Go file, task.go, and define the Task struct as follows:

go
package main

type Task struct {
    ID      int
    Title   string
    Done    bool
}

3.3. Creating the Task Manager

Now, let’s create a TaskManager type that will manage our tasks. Create a Go file, task_manager.go, and add the following code:

go
package main

type TaskManager struct {
    tasks   []Task
}

func NewTaskManager() *TaskManager {
    return &TaskManager{
        tasks: []Task{},
    }
}

func (tm *TaskManager) AddTask(title string) {
    // Generate a unique ID (for simplicity, incrementing a counter)
    id := len(tm.tasks) + 1
    task := Task{
        ID:    id,
        Title: title,
        Done:  false,
    }
    tm.tasks = append(tm.tasks, task)
}

func (tm *TaskManager) GetTasks() []Task {
    return tm.tasks
}

3.4. Creating the WebAssembly Entry Point

Now, create the main entry point for our WebAssembly application in a Go file named main.go:

go
package main

import (
    "fmt"
    "syscall/js"
)

func main() {
    taskManager := NewTaskManager()

    // Register a JavaScript function that adds a task
    js.Global().Set("addTask", js.FuncOf(func(this js.Value, p []js.Value) interface{} {
        title := p[0].String()
        taskManager.AddTask(title)
        return nil
    }))

    // Register a JavaScript function that retrieves tasks
    js.Global().Set("getTasks", js.FuncOf(func(this js.Value, p []js.Value) interface{} {
        tasks := taskManager.GetTasks()
        return js.ValueOf(tasks)
    }))

    fmt.Println("WebAssembly application started.")
    select {}
}

In this code, we create a TaskManager instance, register JavaScript functions (addTask and getTasks) to interact with our Go code, and enter an infinite loop to keep our WebAssembly application running.

3.5. Building and Running the Application

To build our application, compile it to JavaScript using GopherJS:

bash
gopherjs build main.go

Next, convert the resulting main.wasm file to WebAssembly text format:

bash
wasm2wat main.wasm -o main.wat

Now, create an HTML file, index.html, to load and run our WebAssembly application:

html
<!DOCTYPE html>
<html>
<head>
    <title>Task Manager</title>
</head>
<body>
    <h1>Task Manager</h1>
    <input type="text" id="taskInput" placeholder="Enter a task">
    <button onclick="addTask()">Add Task</button>
    <ul id="taskList"></ul>
    <script src="main.js"></script>
    <script>
        // JavaScript functions to interact with Go code
        function addTask() {
            var title = document.getElementById("taskInput").value;
            addTask(title);
            document.getElementById("taskInput").value = "";
        }

        function displayTasks(tasks) {
            var taskList = document.getElementById("taskList");
            taskList.innerHTML = "";
            tasks.forEach(function(task) {
                var listItem = document.createElement("li");
                listItem.textContent = task.Title;
                taskList.appendChild(listItem);
            });
        }

        // Call Go functions to interact with the task manager
        addTask("Buy groceries");
        addTask("Write blog post");
        displayTasks(getTasks());
    </script>
</body>
</html>

This HTML file includes input fields and buttons to add tasks and display the task list. It also contains JavaScript code to interact with our Go code.

3.6. Testing the Task Manager Application

Serve your project using a local server as shown earlier, and open it in your web browser. You’ll have a simple task manager application that allows you to add and display tasks.

Conclusion

In this blog, we’ve explored the exciting world of WebAssembly and how you can use GoLang to build high-performance web applications. We began by setting up our development environment, created a “Hello, WebAssembly!” example, and then progressed to building a real-world task manager application.

WebAssembly, combined with the power and simplicity of GoLang, offers a promising future for web development. Whether you’re building complex applications or optimizing existing ones, WebAssembly and GoLang provide the tools you need to achieve outstanding performance and versatility in web development. So, go ahead and start exploring this powerful combination for your next web project. Happy coding!

Previously at
Flag Argentina
Mexico
time icon
GMT-6
Over 5 years of experience in Golang. Led the design and implementation of a distributed system and platform for building conversational chatbots.