Skip to content


Read the Git structure page, then go see an area of contribution below:

Mirroring Docs

Git Structure#

Our repositories are split across multiple places, this is the average contribution path:

flowchart TD
    A[New User] -->|Wants to contribute| B(Needs source code)
    B -->|Google results bring up Github| C{Where?}
    C -->|Newer v4-related repos| D(Impossible-to-find <a href="" target="_blank" rel="noopener noreferrer">Gitlab instance</a>)
    C -->|Old + 'meant to be forked' repos| E(<a href="" target="_blank" rel="noopener noreferrer">Our Github organization</a>, user always goes here first)
    D --> F[User forks]
    E --> G[User forks]

Most users will never find the Gitlab and will see old decrepit repos alongside newer ones on our Github organization. Please remember all new repos are on our Gitlab CE instance, except for "meant to be forked" repos.

You should already know how to use both services depending on what you're contributing to. For things like the tracks repo, view the Github start guide. For all v4-related repos on our Gitlab, see Gitlab's start guide.


If you'd like to mirror our package repo and/or ISOs, here's the basics for it.

Current (ish) stats#

  • Size: 3 GB (repo and current testing ISO)
  • Number of files: 36
  • Mirrors: 7 (excluding cloud storage services)
  • Coverage: NA, EU, AU/NZ, KP
  • Rsync: (available from other mirrors)

A mirror list is available on the download page.


If you'd like to mirror, great! Here's the steps:

  1. Note down your mirror's bandwidth (in Gbps), country, name, and what you'll be serving (ISO-only, repo-only or both)
  2. Clone the master package repo mirror via wget and grab the latest ISO (or rsync with another mirror)
  3. Contact Asterisk via one of our chatrooms (in the footer of this page) to get your mirror listed
wget mirroring for the package repo

Otus has provided a cronjob for this:

0 * * * * wget --mirror --no-parent --no-host-directories -P $WEB_FOLDER && find $WEB_FOLDER -type f -name 'index.html*' -delete

Where $WEB_FOLDER is your web data folder.

This tells wget to download everything without any parent or domain folders, then we use find to remove all the index.html files.

I wish we had rsync too, but here we are. 😑

To sync our ISOs you can use the script below:


download_iso() {
    rm -rf $LOCAL_ISO_PATH
    wget -O "$LOCAL_ISO_PATH" "$ISO_URL"

get_remote_version() {
    wget -O - "$ISO_VERSION_URL"


if [ "$REMOTE_VERSION" != "$LOCAL_VERSION" ]; then
    echo "New ISO version detected. Downloading..."
    echo "ISO is up-to-date."

Replace LOCAL_ISO_PATH and LOCAL_VERSION_FILE with the path to your webserver followed by blendOS.iso and version respectively. Keep the file names as-is.

Set this up to a systemd timer unit or cronjob, and it will keep everything up-to-date.


You will be asked if you'd like to be used as a webseed for the FOSS Torrents torrent. This is totally up to you.

You will be added to our status page and pinged every 60 seconds. Please give us details if we need to ping something specific or if you want notifications.

If you have any questions, just contact us.


Gitlab - CC BY-SA 4.0 - Material for MkDocs


If you would like to add to our docs (please do), you should follow these simple rules.

  1. Keep it local. If you use any external assets, download them. Only do not download something if it is dynamic (like a status badge) or there is no other way (like emoji). Static badges, script links pointing to fixed versions, fonts, images, files, download them all. Save them in the right category in the docs/assets folder. This is to minimize external requests.
  2. Link code properly. Any code snippets you add should be snippet links to the original file if applicable. You can pull specific lines or even create sections to do this. Only do not do this if it would be way too cumbersome.
  3. External links should open in a new tab with no referrer. (unless you have a specific reason not to) Make links like this:{ target="_blank" relk="noopener noreferrer" }
    [link text]({ target="_blank" rel="noopener noreferrer" }
  4. Use frontmatter. Set an icon and description for every page (examples can be seen in the source of any page). Include all pages in the nav: component of mkdocs.yml unless there is a reason not to.
  5. Be descriptive. When writing config and CLI references especially, try to show, not tell. A full description of this approach can be seen in the Diátaxis framework:
  6. Follow the format. We have established formats for directory pages and references. Follow them. Headers have icons. References begin with a reference card. Config references need to use code annotations. CLI references should be easy-to-read lists (showing the code like in the bpkg reference is optional). Directory pages should use cards to show what users can click on.
  7. Keep it navigateable. Mobile users should not have to open the hamburger menu to get anywhere on the site from the root (they can still use it to go back or to skip directory pages).
  8. Be semi-casual. For guides, you may find it better to be less distant from the reader. However, you need to also offer a reliable explanation of steps. You can decide what that looks like. References however, should always be distant (rule 5).
  9. Use the features given to you. Be expressive! You are writing with one of the most powerful documentation frameworks out there, so use it! Don't be afraid to try something new in your writing, style or layout.
  10. Always have a Javascript-free option. You can use the noJs system to pull this off.
  11. Always give your headers icons. This helps them look nice, and will be even nicer once the typeset plugin hits the community edition.
  12. Header titles must match page titles. Each page will have one level 1 header. Make your header like this: # :<icon-you-used>: <nav-title>
  13. Merge to dev. This way you can preview everything before pushing it out.

Local Development#

Local development is quite easy. You'll only need:

  • Python ≥ 3.8
  • pip package manager (included with Python on Windows)
Using pipenv if pip cannot be used directly

Install pipenv from pypi or your package manager.

Then do the following in the project folder:

pipenv install

Then, as pipenv says, you can use pipenv shell and pipenv run:

pipenv run mkdocs serve

Simply cd in and run (this command only has to be run once):

pip install -r requirements.txt

From there, start the dev server:

mkdocs serve

The server will reload after every save.

If you want to build the website into static HTML, run this command (this isn't required for contribution, the CI/CD server does it automatically):

mkdocs build


To learn how to write with Material for MkDocs, consult their reference and extension list to see its special components.

Looking for examples?

Just click the on any page to view its source code!

Images and internal links are created relative to the file you're currently editing. Links should link to the markdown file itself, not a path. (e.x. reference/ ../assets/img/file.png)

An overview of a few cool features you can use ( denotes a custom feature):

Admonitions (admonition)#

!!! <type> "<title>"

??? warning "collapsable"

!!! note inline end <!-- or inline --> "Inline"

??? abstract follow "󰩳 This one's header will follow you down the page!"
    looooong text












In addition to the regular admonition types, we have also added a code admonition for making collapsable codeblocks:

??? code "󰩳 file_name.ext"     <-- 󰩳 This has follow on by default
    code here, no space between admonition and code
code here

As well as a collapse admonition:

??? collapse "󰩳 X lines collapsed"    <-- 󰩳 This also has follow on by default


X lines collapsed




And video:

??? video "󰩳 Video Guide"
    <video src="/assets/vid/example.webm" controls></video>
    <p>You should set a width and height if the video is too big, 
    and muted if it has no sound. 
    This p section can be omitted if no caption is required.<p>
Video Guide

You should set a width and height if the video is too big, and muted if it has no sound. This p section can be omitted if no caption is required.

Emojis/Icons (emoji)#

Call them via their shortcode:



Call icons the same way:


One thing that is a bit different on these docs vs. other sites is you can use icons in codeblocks. Our codeblocks use a Nerd Font, which allows you to use icons within your code.

󰩳 I'm an icon!

Visit the cheatsheet:

Find the icon you want and hover over it. In the copy section, hit Icon. Your editor will probably not be able to render the icon as it is not using a Nerd Font. Rest assured, it will render in your preview.

CSS in Markdown (attr_list & pm_attr_list)#

[link](url){ option=value .class #id }

Markdown in HTML (md_in_html)#

<div markdown>
  **Markdown works** __just fine!__{ .someclass }

Markdown works just fine!

Code Snippets (snippets)#

File paths are relative to the repo root.

--8<-- "link_or_file.ext"
  --8<-- "link_or_file.ext"

We use this to make reusable Markdown snippets, and pull the latest version of a code file.

Keybinds (keys)#



Inline Syntax Highlighting (inlinehilite)#

`#!lang code`

`#!python print("Hello World!")`

print("Hello World!")

It also works for Github/Gitlab/Bitbucket links too!

Legend: ! = PR # = Issue ? = discussion ... = Compare

MagicLink supports shorthand references for GitHub, GitLab, and Bitbucket issues (#1), pull/merge requests (!100), GitHub Discussion 
(, commits (23bb7083b4699703241d7552ff666cf8cef61337), and compares 
(23bb7083b4699703241d7552ff666cf8cef61337...0abca9679ec09ca289c345cc8843497fc0f8be9b). You can also reference repositories (https:// and users (@facelessuser). Mentions also works for social media (only Twitter is supported 
at this time).

MagicLink supports shorthand references for GitHub, GitLab, and Bitbucket issues (#1), pull/merge requests (!100), GitHub Discussion (facelessuser/pymdown-extensions?1173), commits (23bb708), and compares (23bb708...0abca96). You can also reference repositories (facelessuser/pymdown-extensions) and users (@facelessuser). Mentions also works for social media (only Twitter is supported at this time).

If you do not specify a repo, the default repo will be used (here, it's blend-os/blendos (Github)).

You can also specify links to our git server:

Gitlab subgroups do not work.

󰩳 @blendgit:asterisk
󰩳 @blendgit:blendos/docs

There's a lot more!

See the full reference and extension list for more cool features.


If you add custom HTML elements with Javascript, please use the noJs system to provide a Javascript-free option.

Add this section to the page:

    var styleSheet = document.createElement("style")
    styleSheet.innerText = '.noJs { display: revert !important }'

This script will show noJs elements (which are hidden by default) and will not run if Javascript is disabled.

Next, give the element using the Javascript (i.e. if it uses a <div> or <span>) the noJs class.

Now, if you have a Javascript-free replacement (a warning saying you need Javascript or a replacement button), put it in a <noscript> tag.

    document.getElementById('someDiv').innerHTML = "html goes here"

<span id="someDiv" class="noJs"></span>

[Button](javascript:history.forward){ .noJs .md-button }

<noscript>You need Javascript for this.</noscript>


    var styleSheet = document.createElement("style")
    styleSheet.innerText = '.noJs { display: revert !important }'


We have set up mkdocs-macros to turn MkDocs into more of a wiki engine.

We have created the following macros:

Package links (v4 containers only)

{{ aur("aur-package") }}
{{ archpkg("some-package") }}
{{ ubpkg("some-ubuntu-thing") }}
{{ debpkg("some-debian-thing") }}
{{ fedorapkg("some-fedora-thing") }}

URL schemas

{{ track("track-from-our-repo-without-extension") }}
{{ custom_track("your-impl-url", "your-track-name-without-extension") }}
{{ reference("folder", "page") }}

CSS classes#

CSS classes you can use:

/* .icon classes are computed using
.icon-x-misc classes are for multi-color images and icons. 
.icon-x classes are for monochrome images and icons */

.icon-white {
    filter: invert(100%) sepia(2%) saturate(0%) hue-rotate(148deg) brightness(102%) contrast(106%);

.icon-blend-misc {
    filter: brightness(0) saturate(100%) invert(63%) sepia(95%) saturate(356%) hue-rotate(115deg) brightness(85%) contrast(88%);;

.info {
    color: #00B8D4;

.tip {
    color: #00BFA5;

.green {
    color: #00C853;

.blend {
    color: #21af90;

.orange {
    color: #FFA724;

.red {
    color: #ff0000;

.mt-1 {
    margin-top: 0.1em;

.mega {
    color: #D9272E;

.yellow {
    color: #FFD600;

.pink {
    color: #FF00DE;
.purple {
    color: #ad05ad;

.red {
    color: #FF1744;

.text-lg {
    font-size: large;

.ccc {
    display: flex;
    align-items: center;
    justify-content: center;

.circle {
    border: 1px solid white;
    border-radius: 100px;


.windows {
    color: #0078d6;

.warning {
    color: #ff9100;


.wide-table {
    width: 100%;

You can apply CSS to a whole block like this:

some text
{ .yellow }

some text

to icons:

:material-cog:{ .yellow }

or even to bits of text:

Hi this text is <span class="yellow">**yellow**</span> but this text is normal!

Hi this text is yellow but this text is normal!

Tables too:

| 1 | 2 |
| I HATE MARKDOWN TABLES 󰩳 { .yellow } | a |
1 2

as well as lists:

1. 󰩳 a
{ .someclass }
1. 󰩳 b
{ #id }
  1. a
  2. b

Extra features in attr_list

We use a fork of attr_list to support lists and tables. More info is here.