Svelte and making it into a REAL desktop Application!

Now isn't that a title! In all reality it is two separate frameworks that I have proto-typed and played with. The first (Node-GTK-Svelte) I'll discuss in this blog post.

First thing I want to clarify, there is NO BROWSER involved, these are all native GTK components! Again NO BROWSERS were harmed (or used) in the making of this!

First, I have a Node-GTK-Svelte framework that allows me to do this:

<script>
    let name = 'world';

    function handleTestClick(event) {
        name = " ! " + name + " ! ";
    }   
</script>

<main class="main">
    <div>Hello<img width="200" src="./assets/1.jpg"> {name}</div>
    <button class="button" on:click={handleTestClick}>Click Me</button>

    <table class="table">
        <tr><td class="td">1</td><td class="td tdnoleft">Text inside a Table</td>
            <td rowspan="2" class="td tdnoleft">2 Rows</td></tr>
        <tr><td colspan="2" class="td tonotop">Spanning 2 columns</td></tr>
    </table>
</main>

<style>
    .button {
        background: blue;
        color: white;
    }

    .table {
        margin: 3px;
    }

    .main {
        background-color: grey;
        padding: 5px;
    }

    .td {
        border: 1px solid #232121;
        padding-left: 5px;
        padding-right: 5px;
    }

    .tdnoleft {
        border-left: 0px;
    }

    .tonotop {
        border-top: 0px;
    }
</style>

With this as the bootstrap:

"use strict";

import {platform} from "node:process";
import {Application} from "../lib/application.mjs";
import SvelteApp from './App.svelte';

// Create the Application & Window
const app = new Application( {width: 400, height: 200, title: "Hi from a Svelte " +platform+ " desktop app"});

// Create your Svelte code and attach it to the application class
const RunningApp = new SvelteApp({
    // You can also just use "document.body" as it is globalized by the Application to provide HTML compatibility.
    target: app.document.body,
    props: {
    }
});

Very standard Svelte web based code, the only thing unique is the creation of the new Application FIRST and then passing app.document.body. (although as I mention in the comment, you can just use document.body, but I prefer my code to be more descriptive) And this is what I get out of it:

The grey screen is the app (as we used css to style it grey), the white screen is a GTK application inspector screen.

I have written a framework where Svelte thinks it is running in a Browser, it asks for a DIV element and I hand it a GtKBox layout that looks like a DIV. Same with everything else. So basically the objective is that I can run my Svelte app in a browser (like Electron) or in my Node-GTK-Svelte framework (as a native App) and hopefully the number of changes would be basically zero.

In addition to making it know about html, since I can add any elements I want -- I've also created a generic <gtk> component where I can do this in the same Svelte file.

And just like the above you see, with full Svelte interactivity:

To the Future and Beyond!

There is still a lot of pieces to be done to make this generic for everybody to use...

  • Adding bundling so that it can be packages into a single executable on each platform for production, including supporting binary v8 snapshots to protect your code.
  • Adding lots more html equivalent elements.
  • Supporting more properties on the elements I've already created.
  • Creating a page-able template system as GTK supports templates list (& other) views, to be much more memory efficient. There is no reason to create 200 lines in a table that only shows 20 lines. The other 180 lines can be easily paged in as they are visible even if you have all the data available up front, no need to waste the memory.
  • HMR & Caching support for the simple node loading system I've built (You can already run a svelte app right from node instantly, no bundlers are needed for development, making development quick and fast even without HMR. Having HMR support would be nice as your app get bigger.

Funding

I have my own purposes for this framework, so my goals aren't in line with what a community needs in general. I only need a couple more pieces built and I can proceed full tilt on my application that I built this framework for. However, rather than lock away this technology I've decided to try to do a Ko-fi membership (like patreon) system. If I hit a solid number of subscriptions then my focus will be to generate something that can be used by everyone and the code will be released to subscribers at different points in time and eventually be totally open sourced to the world. If there is no interest in helping fund it, then, I already have enough open source projects that take plenty of time to support that I don't need to add any more to my stack. So then this framework will just be another internally used project for the purposes that I need it for which allows me to keep it simple and just have lots of hacks for the pieces I need as I don't need most properties on most elements.

There is one interesting twist, I'm testing the water for two different directions with this framework. Over the last 6 years a lot of people have also asked for a NativeScript desktop framework. I have no idea if there is any real demand for it, but I figured since my base GTK framework actually can do this, I would see if the NativeScript community had enough desire for it. So I have two separate subscription groups, GTK-Svelte and NativeScript-Desktop.

f you are interested in helping fund the Svelte or the NativeScript-Desktop version; then click here and start a Ko-fi membership. If you have any questions please feel free to ask away.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.