DEV Community

Tomasz Wegrzanowski
Tomasz Wegrzanowski

Posted on

Electron Adventures: Episode 41: Marko

This episode was created in collaboration with the amazing Amanda Cavallaro.

There are many Javascript frameworks, and even if you never used most of them, you've probably overheard their names. Then there's Marko.

I'm actually not sure how popular it is - it has very respectable 10k github stars, which should indicate a moderately popular one. On the other hand, nobody even mentioned it in State of JS survey, and blogging sites like dev.to and hashnode don't even have "marko" tag.

So what is Marko even?

Marko is a framework somewhat similar to Svelte or Vue. Each component lives in .marko file, and there's a compiler that turns it into Javascript a browser or Electron can run.

There are some big differences:

  • Svelte wants you to import components like regular JS files. Marko apparently uses custom html elements, which save you the importing - but every component, and therefore every file, needs to have - in the name. This isn't completely unique, and a few other frameworks do something similar.
  • .svelte files are clearly separated into <script> / <style> and template part - and script part is just a function. In .marko you put your code in class { ... } or use loose $ reactive lines and Marko compiler just figures out which lines are code and which are HTML.
  • Marko components are generally classes, and state lives in this.state etc. Svelte components just have all functions, props, state variables and so on at top level.
  • Marko does a lot more things implicitly, while Svelte tends to be more explicit - so Marko wins here by having fewer lines of boilerplate.
  • And of course there's a ton of syntactic differences, even if conceptually things are often quite similar. Which style you find more readable is up to you.
  • Svelte has a lot better documentation.

Getting started

We'll follow the usual order - first create app, then add Electron to it.

To create marko app:

$ npx @marko/create episode-41-marko
✔ Choose a template · Default starter app
✔ Project created! To get started, run:

    cd episode-41-marko
    npm run dev

$ cd episode-41-marko
$ npm i --save-dev electron
Enter fullscreen mode Exit fullscreen mode

We need to stop it from launching web browser, as we want to use Electron instead, so edit package.json and fix the dev line by adding --no-browser:

    "dev": "marko-serve ./src/pages --no-browser",
Enter fullscreen mode Exit fullscreen mode

index.js

It just needs to launch the app in Electron. It's identical to what we had with other frameworks, just port number is 3000 this time:

let { app, BrowserWindow } = require("electron")

function createWindow() {
  let win = new BrowserWindow({})
  win.maximize()
  win.loadURL("http://localhost:3000/")
}

app.on("ready", createWindow)

app.on("window-all-closed", () => {
  app.quit()
})
Enter fullscreen mode Exit fullscreen mode

src/pages/index/index.marko

Let's replace this file by this:

<app-layout title="Hello Electron">
  <hello-world />
</app-layout>
Enter fullscreen mode Exit fullscreen mode

This means we have app-layout responsible for stuff like html headers, and then hello-world is our main component.

As these are custom HTML elements, they all must contain -. You cannot just call your component <app />.

src/components/app-layout.marko

This file is already created by the @marko/create command, but we need to tweak it a bit by adjusting top level styling more to your liking.

input is where props go. input.title is the prop we passed in <app-layout title="Hello Electron">. input.renderBody is the prop passed inside the tag - in our case <hello-world />.

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${input.title}</title>
</head>
<body>
  <${input.renderBody}/>
</body>
</html>

style {
  html, body {
    font-family: system-ui;
    padding: 0;
    margin: 0;
    background-color: #444;
    color: #eee;
    text-align: center;
  }
}
Enter fullscreen mode Exit fullscreen mode

src/components/hello-world.marko

And since it's just a Hello World, here's a very simple app component:

<h1>Hello, World!</h1>
<div>Marko says Hi!</div>
Enter fullscreen mode Exit fullscreen mode

All this was a surprisingly boilerplate free experience!

Result

Here's the results:

Episode 41 Screenshot

In the next episodes, we'll try to port our file manager app to Marko.

As usual, all the code for the episode is here.

Discussion (0)