DEV Community

Cover image for What does you do, when you need a desktop version of your existing SPA web app? 💡
Vic Shóstak
Vic Shóstak

Posted on • Updated on

What does you do, when you need a desktop version of your existing SPA web app? 💡

Introduction

Well, hello! Today is good day, which means it's time for a interesting story for your project this week! 😅 Alright, without too much foreplay, let's get started.

📝 Table of contents

What have we got yet?

Let's imagine, that we already have a well working SPA web application in production. Let it be a simple service for listening to podcasts on all kinds of development topics. And your client is satisfied...

fiber rest api

💥 One day, your client comes to you and asks you to develop a native version of his website for macOS, Windows 10 and Ubuntu Linux. But web app have frontend on Svelte, which successful works with REST API, based on Fiber.

— What's Fiber? 😐

Fiber is a web framework that was inspired by Express.js and based on Fasthttp, the fastest HTTP engine written on Go. The framework was designed to simplify the process of fast development of high-performance web applications with zero memory allocation.

If you interested, please go to Fiber documentation, repository or my own introduction article for more details!

Yeah, maybe a little unrealistic situation, but we're still dreaming! 😁

What's to be done?

✅ App must run in its own system window.
✅ App must support for all media keys on keyboard.
✅ There must be a single code base with web version of app.
✅ Development and maintenance of app should not take too long time.

Trials and errors

Yep, you may take something, like Electron, but this will broke 3 and 4 rules above and will mean, that you'll have to translate all entire code base of your SPA (remember, already working in the production) to Electron.

electron

If we developed our web app from scratch, this approach would be one of the best, but we have what we have. Such an approach would be longer and more expensive, than described below.

Golang way

As you might have known from my previous article, Go has a good package for displaying web pages zserge/webview. Also, we will need a tool to cross-compiling for all necessary operating systems — XGO (karalabe/xgo).

So, here's what we need to do 👇

  • Install packages:


$ go get -u github.com/zserge/webview
$ go get -u github.com/karalabe/xgo


Enter fullscreen mode Exit fullscreen mode
  • Write simple Go code:


package main

import "github.com/zserge/webview"

func main() {
    // Define webview settings
    settings := webview.Settings{
        Title:     "SPA Desktop App",     // title for window
        URL:       "https://example.com", // open URL
        Width:     1280,                  // window width (px)
        Height:    720,                   // window height (px)
        Resizable: true,                  // enable resize window
        Debug:     false,                 // disable debug
    }

    // Create new webview app with settings
    window := webview.New(settings)

    // Run webview app
    window.Run()
}


Enter fullscreen mode Exit fullscreen mode
  • Compile desktop app for Windows 10 to ./build folder:


$ xgo -out ./build/spa_desktop \
    -ldflags="-H windowsgui" \
    --targets=windows-10/amd64 \
    github.com/user/spa-desktop-app


Enter fullscreen mode Exit fullscreen mode
  • Compile desktop app for Linux and macOS to ./build folder:


$ xgo -out ./build/spa_desktop \
    --targets=linux/amd64,darwin/amd64 \
    github.com/user/spa-desktop-app


Enter fullscreen mode Exit fullscreen mode

⚠️ All compiled for 64-bit systems.

Hint for macOS

How to prepare files for .app file, I have already told in this article. For shipping your desktop app to macOS users in usual manner (drag'n'drop installer on .dmg format), we can use node-appdmg:

GitHub logo LinusU / node-appdmg

💾 Generate your app dmgs

I like this Node.js library, because it have simple install and understandable configuration. If you have some design skills, result may be something like this:

Yandex.Music Desktop

Windows 10 problem

For a visual demonstration problem, I'll use my own Yandex.Music Desktop:

GitHub logo koddr / yandex-music-desktop

🎵 Yandex.Music Desktop (un-official port of website). Please note: this is only webview port of Yandex.Music website as desktop app for macOS, Windows 10 and GNU/Linux!

So, desktop app build this way always running from the default OS webview layer. That means, if you removed Edge browser — webview layer will be Internet Explorer 11 and not Chrome (FireFox, Opera, etc.), because it's third-party software for Windows!

I check it from my test-stand with Windows 10 Pro x64 (version 1903, OS build 18362.535). On screenshot below (from left to right):

Yandex.Music Desktop app, Internet Explorer 11, MS Edge 18 👇

Windows 10 main problem

How to solve this?

I have no answer to that question... Therefore, the best option is to warn, that service will not work, if Edge browser is not on the user's system.

You can set up a message, if catch User-Agent like this:



Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko


Enter fullscreen mode Exit fullscreen mode

What's next?

I advise you to experiment with this knowledge. For example, in the direction of porting your favorite websites in native apps as the same way. 👍

Questions

  • What is happen with app window, when you change webview.Settings.Resizable to false on your Go app?
  • How to disguise a Windows 10 problem by Golang (hint: use HTTP headers and make redirect to ie-block.html page, if IE detected)?

Exercises

  • Build your Go app to other OS (and arch), using XGO package.
  • Solve a Windows 10 (Internet Explorer) problem, by catch UserAgent by JavaScript or Go (hint: see above hint).

Photo by

[Title] Med Badr Chemmaoui https://unsplash.com/photos/ZSPBhokqDMc
[1, 2] Somewhere from Google Search 🤷️
[3, 4] Vic Shóstak https://github.com/koddr/yandex-music-desktop

P.S.

If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻

❗️ You can support me on Boosty, both on a permanent and on a one-time basis. All proceeds from this way will go to support my OSS projects and will energize me to create new products and articles for the community.

support me on Boosty

And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!

My main projects that need your help (and stars) 👇

  • 🔥 gowebly: A next-generation CLI tool that makes it easy to create amazing web applications with Go on the backend, using htmx, hyperscript or Alpine.js and the most popular CSS frameworks on the frontend.
  • create-go-app: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.

Other my small projects: yatr, gosl, json2csv, csv2api.

Top comments (2)

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt • Edited

You can put web server (of any programming languages) inside Electron too. If not Node-based server, you will need to both spawn on start and kill on exit.

polvcode.dev/post/2019/07/electron...

I do know one thing that is impossible for Electron, though. You cannot opt out bundling of Chromium.

Collapse
 
koddr profile image
Vic Shóstak

Thx for comment and link 😉