How Mattrbld Works

Illustrated drawing of Amadeus Maxmimilian StadlerIllustrated drawing of Amadeus Maxmimilian Stadler

Amadeus Stadler

Last updated December 28, 2021

In this article you’ll get a technical overview of how Mattrbld works. This should give you an insight into what goes on behind the UI and serve as a starting point for explaining potential gotchas and performing initial troubleshooting. As such the text might become a bit more technical than in other parts of this documentation.

Basics

When you open Mattrbld for the first time, it downloads the assets initially needed and depending on whether you’re using an Invite Link or not, will either create a local user from the data in the invite link, or put you through the onboarding process.

This will create a local filesystem in your browser’s IndexedDB that will serve as a stand-in to your device’s local filesystem since accessing that through the browser isn’t reliably possible yet. The project import itself is simply a git clone of the provided repository—just like you would call it from your local shell, except that instead of storing the files straight on your disk it will save them in the virtual filesystem that was created in the step before. To save bandwidth and storage space, Mattrbld will also only clone a single branch and not fetch the entire commit history, i.e. create a shallow clone.

Once the process is finished, Mattrbld checks if the hidden .mattrbld directory exists for the project that was just imported. If it does and contains a configuration file, the project was set up to work with Mattrbld before and you will be taken to the Dashboard, if not the project will still need to be configured and you’ll be taken to the Project Settings to do so—you can learn more about that process in the Configuration article and its related content.

Any change you make, be it to an existing file, or by creating a new file, will be written to the virtual filesystem just like it would if Mattrbld would be running directly on your device. Since everything happens locally on your hardware, it works offline and is often much faster than interfacing with a remote server. It’s also great for your privacy. 😉

To get all your changes back into your remote Git repository, i.e. to do what you would usually do via git add, git commit and git push, you can simply head to the Dashboard and click the “Synchronise Changes” button. This will present you with an entire list of changes that have not yet been pushed back to the remote repository as well as a text field for entering a commit message.

You are free to select which files you would like to include in that given push, or to see what changed within them (think a very simple form of git diff) or even discard all local changes to them via the context / overflow menu on every individual changed file.

In order to keep things simple for non-technical users, the pull, add, commit and push steps have all been unified in one common action. So all you need to do after selecting your changes and writing a message is hit the “Sync xyz changes” button and Mattrbld will do the rest:

  • Perform a git pull to ensure the local files are up-to-date with the remote ones and the following push will be a simple fast-forward merge

  • git add all your selected changes and git commit them with your message, using your local user as the commit author and committer

  • Perform a git push to push all the local changes back to the server

If you have Mattrbld’s drafts functionality enabled, Mattrbld will first add, commit and push all files in the drafts directory appending (drafts) to the commit message, and then separately add, commit and push the rest of the changes. This is intentionally split up so you can configure your CI to only run when the drafts folder is unchanged, which also ensures that it won’t unnecessarily run when you just modify a draft.

After a successful sync the list of local changes is reset and the status indicator at the top of the project sidebar turns green (if you opted to sync all changes) until you make another local change. To ensure that you’re always working on the most recent version of the content when opening a project from the Home screen, Mattrbld will perform a initial pull in the background while you get started working.

If that should fail for any reason, the status indicator will turn red and be labelled “Error” clicking on it will then show details about the error and offer an option for retrying the action. Should you be offline when the initial pull is attempted, you will be warned instead, but can continue working without a problem.

Authentication

Mattrbld does not handle authentication and authorisation—this task is handed off to your Git provider. So just like when using Git from the terminal, you will be asked for a username / email and password whenever you try accessing a private repository or perform an action that requires you to be authenticated. You can learn more about this in the dedicated article on authentication.

The Tech Stack

Mattrbld is written in Vue 3 and runs directly in your browser as a progressive web app—which means that to host it yourself you’d only need a simple webserver serving the static files, but more on that in another article. Routing is done with Vue Router, while Vuex handles the application state at runtime.

Powering the virtual file system is a library called “lightning-fs”, which is by the same author that created the ingenious piece of code that makes Mattrbld possible: Isomorphic Git, a Git client written and running in Javascript.

js-yaml, gray-matter, markdown-it and Turndown handle content parsing and serialising, while helpers such as TinyColor, jsdiff, date-fns, Color Thief, uuid, slugify, Pluralize and Lodash make general tasks much less painful. The rich text editors are powered by the awesome Prosemirror.

Of course this is just a shallow overview of all the technology that goes into Mattrbld, since even the libraries above use their own set of dependencies, not to mention all the libraries and helpers that make development more enjoyable. They all have my deepest respect for their hard work and dedication. Projects like Mattrbld would be infinitely harder without them.

Filesystem Structure

The virtual file system Mattrbld generates in IndexedDB is rather simple:

root
├── projects
│   ├── your-project
│   │   ├── .mattrbld
│   │   └── (all other files in your repository)
│   └── (repeat for every other imported project)
├── users
│   ├── user-at-example-com.json
│   ├── user-at-example-com.jpg
│   └── (repeat for every other local user)
└── mattrbld.config

Global Mattrbld configuration is stored in mattrbld.config at the root of the filesystem, as well as information and an avatar for every local user in the /users directory. All imported projects end up in the /projects directory and contain all the files that are in their respective Git repositories. Once set up for Mattrbld, they will also contain a .mattrbld directory which houses project specific configuration. Other than that special folder, which always has to be at the root of the repository, you are free to structure your repository however you see fit.

Local Users

Just like Git on your device, Mattrbld needs to know name and email address of the person making a commit. On top of that, Mattrbld also stores project unrelated information such as theme and UI scaling preferences, on a per user basis locally on your device. That’s what the files in the /users folder are for. Think of them as local profiles, say a profile for your private projects with one and a profile for your professional projects with another email address.

This structure also allows for Mattrbld to be used by multiple people on a shared device in a trusted environment such as an agency or a family.

None of this data is ever stored anywhere but your device. Be aware, however, that name and email address will be visible to anyone who has access to your Git repository.

Content Structure

You are free to structure your content however you want, more on that in the Data Modelling section. In broad terms, Mattrbld groups different types of content into Collections—files of the same type that live in a specific folder and its subfolders. These Collections can have one or more valid Schemas which dictate the shape of the data within each individual file. Schemas consist of a set of Fields, each of which has their own type.

For example let’s assume you have a set of markdown files in a folder called “posts” which represent blog posts. To make these posts editable from within Mattrbld, you’d create a new Collection “Blog Posts” which sources markdown files from the “posts” directory.

So Mattrbld knows what fields should be editable within those files, you define a Schema called “Blog Post”, which has at least a field (typically of type “rich text”) with a key of “content” for the text that makes up the body of the markdown document. If it also has a frontmatter, you could define additional fields with keys matching the keys in the frontmatter to be able to edit those as well.

This same principle can be applied to any type of content, such as menus, authors, employees, pages, etc. There are a variety of default fields, which you can additionally group and customise and save as reusable custom fields.

All of this information is stored in plaintext JSON within the .mattrbld directory of your project, allowing you to even edit and modify the files from within your favourite IDE or text editor (or copy-paste them between projects 😉).

That Sounds too Good to be True…

It really is not, although there are a couple of limitations that you should be aware of and will be able to read up on and evaluate in the Limitations article. If you’re already convinced, however, and just haven’t found the right type of project to use Mattrbld for quite yet, feel free to check out one of the other articles in this section, which provide you with some examples.