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 inclass { ... }
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
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",
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()
})
src/pages/index/index.marko
Let's replace this file by this:
<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 />
.
<!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:
<h1>Hello, World!</h1>
<div>Marko says Hi!</div>
All this was a surprisingly boilerplate free experience!
Result
Here's the results:
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.
Top comments (0)