Electron Adventures: Episode 41: Marko
Tags: javascript, electron, marko
Published: 2021-09-04 03:04:09

This episode was created in collaboration with the amazing [Amanda Cavallaro](https://www.amandacavallaro.com/).

There are many Javascript frameworks, and even if you never used most of them, you've probably overheard their names. Then there's [Marko](https://markojs.com/).

I'm actually not sure how popular it is - [it has very respectable 10k github stars](https://github.com/marko-js/marko), which should indicate a moderately popular one. On the other hand, [nobody even mentioned it in State of JS survey](https://2020.stateofjs.com/en-US/technologies/front-end-frameworks/), 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:

```shell
$ 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
```

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`:

```json
    "dev": "marko-serve ./src/pages --no-browser",
```

### `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:

```javascript
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()
})
```

### `src/pages/index/index.marko`

Let's replace this file by this:

```html
<app-layout title="Hello Electron">
  <hello-world />
</app-layout>
```

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 />`.

```html
<!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;
  }
}
```

### `src/components/hello-world.marko`

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

```html
<h1>Hello, World!</h1>
<div>Marko says Hi!</div>
```

All this was a surprisingly boilerplate free experience!

### Result

Here's the results:

![Episode 41 Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/55a4c8mh5gclriug7neo.png)

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](https://github.com/taw/electron-adventures/tree/master/episode-41-marko).