Repository messaging and storage

ctrl+alt+d · repository channels, users, messages and the product origin object pool

L2 object pool

Guides

Launching

Run a machine in your browser, in your own app, or in a local terminal. A local ext4 image can also boot entirely offline, without brintos.io.

Choose live or a backup snapshot

Every machine repo starts with a writable live version. A clean shutdown or image import publishes the read-only latest snapshot. On the Launch tab, choose a version from the dropdown beside the repository name. Changing it stops the current machine and starts the selected version. Writers start on live; read-only viewers start on latest (or a named backup if latest has not been published). The Storage tab’s Write toggle restarts live with or without write access.

Embeds and cloud Node launches also support automatic selection:

Your access and the machine's stateAutomatic selection
You can write, and live is idleLive, with an exclusive usage lease
You can write, but live is already in useLatest published snapshot, read-only
You have read access only, including anonymous public accessLatest published snapshot, read-only

Only one engine may use live at a time, even if that engine chooses read-only access. Many people can boot a backup concurrently, subject to repository access. The usage lease excludes other engines; file edits, uploads, and downloads can still use live while an engine is running, with write access. Live is never exposed to read-only visitors.

For embeds, set data-snapshot="latest" or a backup name on the iframe. In Node, use --snapshot auto, --snapshot live, --snapshot latest, or --snapshot NAME. An explicit live launch refuses if live is busy. Owners save named copies using the controls inside latest on the Snapshots tab. This works while live is running and excludes unpublished live edits. Snapshot names use letters, numbers, dots, underscores or hyphens, starting and ending with a letter or number.

Browse files at /OWNER/REPO:SNAPSHOT-NAME/files. Opening /OWNER/REPO opens live for writers and a published snapshot for read-only visitors.

latest is a protected, read-only snapshot, refreshed after a clean machine shutdown and completed filesystem flush, or a successful ext4 image import. Admins can also use Update from Live inside latest on the Snapshots tab while live is stopped. This immediately replaces latest with a copy of live, leaving live and named snapshots unchanged. Latest cannot be renamed or deleted. Crashes, interrupted page teardown, expired leases, and failed imports do not automatically publish it. Running readers retain their existing immutable snapshot when latest advances. Shutdown publication requires HardwareJS 0.1.0-dev.3 or later; older runtime releases do not send a clean-shutdown signal.

1. Launch in this browser

  1. Open a machine from Explore or your repositories.
  2. Click Launch live to open /OWNER/REPO:live. A backup launches at /OWNER/REPO:SNAPSHOT-NAME.
  3. Check the selected version, then click Power on if it has not started automatically.

The launch page has an interactive console, a kernel log, a screen, and telemetry tabs. A machine configured to power on when opened starts automatically. Public backups can launch without an account; sign in for private machines or writable live access. Fork a backup if you want your own writable copy.

Browser launches select the most recently modified kernel in the chosen snapshot’s /boot directory, then infer its official HardwareJS release from the filename. The runtime stays inside an isolated machine iframe. The root filesystem is read from cloud storage as needed; writes to live persist there.

2. Embed this machine in your own app

Open Settings → Launching this machine → Embed this machine in your own app for a ready-to-copy snippet. In the example below, replace your-machine-host.example with the hostname under Settings → Machine subdomain, without adding another https://. Use the hostname from the same website environment as the script.

<script src="https://brintos.io/brintos.js" crossorigin="anonymous"></script>
<iframe data-brintos
  data-snapshot="auto"
  src="https://your-machine-host.example/hardwarejs/0.1.0-dev.2/hardwarejs.html"
  title="brintOS machine"
  allow="cross-origin-isolated; fullscreen; usb; clipboard-write"
  referrerpolicy="origin"
  sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-downloads allow-forms allow-modals allow-pointer-lock allow-orientation-lock"
  style="width: 100%; height: 100%; border: 0"
></iframe>

Serve the embedding page over HTTPS with these response headers. Give the iframe's container an explicit height so that height: 100% has space to fill.

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

Public access needs no token and launches a read-only backup. For private access or writes, pass a personal access token from Settings → Tokens. The token needs repo:read for reads and repo:write for writes, and its account must have corresponding access to the repo. For an app that receives a token at runtime, configure it before adding the marked iframe:

Brintos.configure({ pat: token });

You can also put data-pat="YOUR_PAT" on the script element. The loader uses the PAT in the parent page; it does not grant your website visitors permissions beyond that token. Use user-specific tokens for authenticated embeds rather than publishing your own token in a public page.

The loader attaches new data-brintos frames and releases their mounts when removed. For explicit control, use an iframe without data-brintos:

const machine = Brintos.mount(frame, {
  pat: token,
  snapshot: 'latest'
});
await machine.ready;
// When your app closes the machine:
machine.dispose();

Listen for brintos:ready, brintos:error, brintos:log, and brintos:disposed on the iframe. If your app sets a Content Security Policy, allow the loader in script-src, 'wasm-unsafe-eval', the machine in frame-src, blob: in worker-src, and the brintOS API and presigned storage URLs in connect-src. No domain registration or DNS TXT record is required to embed a machine.

3. Launch locally with Node and cloud storage

Install Node.js 22 or newer and curl. Download brintos.js from the website that owns your machine, then supply the machine URL. Replace your-machine-host.example below with its Machine subdomain; repository settings also provide commands with that hostname already filled in.

The launcher loads the website's filesystem client from /brintos.wasm and the official HardwareJS release selected in Settings → Machine spec. The same settings apply to browser and cloud-service launches, including backups. Missing, unknown or revoked runtime versions refuse launch. Repository JavaScript never executes.

Public machine (one line)

curl --fail --show-error --silent 'https://brintos.io'/brintos.js -o brintos.js && node brintos.js --api-url 'https://brintos.io' --snapshot 'auto' --url 'https://your-machine-host.example'

Private access or writes (Bash)

MACHINE_URL='https://your-machine-host.example'
read -rsp 'Personal access token: ' BRINTOS_TOKEN; printf '\n'
export BRINTOS_TOKEN
curl --fail --show-error --silent 'https://brintos.io'/brintos.js -o brintos.js
node brintos.js --api-url 'https://brintos.io' --snapshot 'auto' --url "$MACHINE_URL"
unset BRINTOS_TOKEN

Choose a cache directory and force read-only access

node brintos.js --api-url 'https://brintos.io' --snapshot 'auto' --url 'https://your-machine-host.example' --cache-dir "$HOME/brintos-machine-cache" --read-only

The examples use https://brintos.io. The CLI's default API origin is https://brintos.io; --api-url selects another website origin. Use a separate cache directory for each concurrent Node session. Supply BRINTOS_TOKEN or --pat when needed.

Exit with Ctrl-] (Control + right bracket). This powers off the engine, flushes pending cloud writes, and releases its usage lease. Ctrl-C interrupts the guest program and leaves Node running. Ctrl-\ prints diagnostics.

brintos.js command-line arguments

ArgumentMeaning
--url <machine-url>Machine URL identifying the cloud repository. Select exactly one of --url, --fs, or --image.
--fs <directory>Local root filesystem. Infers HardwareJS from the versioned /boot kernel and verifies the official runtime. Guest writes modify this directory.
--image <file.img>Local ext4 image. The shared filesystem WASM discovers and reads its versioned /boot kernel with bounded memory. Node is the only prerequisite.
--hardwarejs-version <version>Override HardwareJS selection with an exact approved release. Otherwise the selected kernel filename identifies the release. Cannot combine with Developer mode.
--developer-modeExecute /boot/hardwarejs.js from the selected directory, ext4 image, or repository with Node privileges. For --url, also enable Developer mode in repository settings. Failures never fall back to an official release.
--image-kernel </boot/file.wasm>Select a kernel inside the ext4 image when /boot contains multiple kernels. --kernel instead selects a local host file.
--snapshot <auto|live|latest|name>Version to launch. Default: auto (live when you have write access and it is idle, otherwise the latest backup). Backup snapshots are read-only. Explicit live refuses if busy.
--api-url <origin>Website and API origin. Default: https://brintos.io. Set this to the website that owns your machine.
--pat <token>Personal access token for private access or writes. Alternatively set BRINTOS_TOKEN. Public reads need no token.
--cache-dir <directory>Persistent cloud filesystem cache. Default: ~/.brintos. Use separate directories for concurrent sessions.
--read-onlyRefuse cloud filesystem mutations, even when the token permits writes.
--kernel <path>, -k <path>Use a local wasm32 kernel instead of the cloud machine's configured kernel.
--init <path>, -i <path>Program to run as PID 1. Default: the cloud machine's configured init.
--vcpus <N>Process CPU count (1..128). Requires a current image runtime. Cloud boot defaults follow the website machine specification.
--ram <MiB>Kernel memory limit. Cloud launches use the machine RAM setting, bounded by the selected kernel's limit. Local directories and images default to 256 MiB.
--machine-ram <MiB>Aggregate RAM reported to the guest, including kernel and user memory. Cloud launches default to the machine RAM setting; local launches default to --ram. Must be at least --ram.
--user-ram <MiB>Initial memory per guest process. Cloud launches default to 2 MiB; local launches default to 64 MiB. Clamped to --user-max when larger.
--user-max <MiB>Maximum memory per guest process. Default: 256 MiB.
--cmdline <text>Extra kernel command-line text. Quote values containing spaces. Default: none.
--gateway-origin <origin>Enable the guest HTTP gateway and allow this origin. Repeat for additional origins. Default: gateway disabled.
--gateway-app-origin <origin>Identify the brintOS API origin among the allowed gateway origins so read-only gateway rules recognize this machine's filesystem API.
--gateway-read-onlyMake the HTTP gateway refuse repository mutations. This is separate from the cloud filesystem's --read-only option.
--help, -hPrint all options and terminal controls, then exit. Works offline.

Run node brintos.js --help to read the same options offline.

4. Launch a local ext4 image

Install Node.js 22 or newer. The same brintos.js command discovers and reads the versioned kernel in /boot through the shared filesystem WASM. Its filename selects HardwareJS; --hardwarejs-version explicitly overrides that selection with an approved release. No native filesystem helper or 7-Zip installation is needed. Runtime verification requires a website connection; guest file data stays in the local image.

curl -fsS https://brintos.io/brintos.js -o brintos.js && node brintos.js --api-url https://brintos.io --image ./machine.img

The image must be a clean ext4 filesystem starting at byte zero, with wasm32 userland, a kernel named vmlinux-<kernel>-wasm32-<portversion>-hwjs-<hwversion>.wasm in /boot, and directories /dev, /proc, /sys, and /tmp. The kernel needs ext4 and virtio-blk support. For example, vmlinux-6.12.0-wasm32-0.1.0-hwjs-0.1.0-dev.2.wasm selects HardwareJS 0.1.0-dev.2. Find approved runtime versions at /hardwarejs.

One versioned kernel in /boot is selected automatically. With several, use --image-kernel /boot/<name>.wasm. The image opens read-write by default, and guest changes persist in your local .img file. Add --read-only to open the file and mount ext4 read-only. /tmp is temporary. Use --kernel ./custom.wasm --hardwarejs-version 0.1.0-dev.2 to override the kernel or --init /bin/bash to choose the initial program. Press Ctrl-] to exit; Ctrl-C still goes to the guest.

Run sync inside the guest before exiting a writable image to submit its buffered filesystem writes. Node flushes submitted disk writes when it closes the image file. Changing a downloaded image does not modify the hosted backup it came from.

Download an immutable backup as an .img. On the machine's Files page, use the Offline image panel, or find the same download controls in Settings under the local ext4 launch instructions. Choose the latest backup or an older snapshot. The live image cannot be downloaded. Downloading a private backup requires access to its repository. Local launch verifies its runtime against the current website release catalog.

The image preserves file contents, hard links, ownership, permissions, timestamps, symlinks, device nodes and supported extended attributes. It includes missing boot mountpoint directories and the backup's kernel when present. Downloads support up to 1 TiB and 250,000 entries. A backup without a compatible kernel or userland can be downloaded but needs those files before boot.

Runtime selection and official releases

Hosted machines choose the most recently modified regular vmlinux-*.wasm file directly in the selected snapshot’s /boot. Equal modification times use ascending filename order. The -hwjs-<version>.wasm suffix selects HardwareJS. Both appear in About and Settings → Machine spec as read-only values. A red notice identifies an invalid version or missing official runtime files; the launch refuses instead of trying an older kernel. Embeds follow this snapshot-specific selection even when their initial URL names another version. Local roots and ext4 images infer the version from their selected kernel; use --hardwarejs-version for an explicit approved override. Images contain no runtime manifest.

brintOS hosts the actual hardwarejs.js, hardwarejs.html and release.json files as public static assets at /hardwarejs/<version>/. The descriptor records artifact sizes and SHA-256 hashes. Each Node launch checks current approval at /api/hardwarejs/<version>, then verifies the downloaded release before executing it. These public requests carry no access token; an internet connection is required even when your disk image is local. Revoked files may remain downloadable, but cannot authorize a new launch.

Browser machines continue to run in a sandboxed iframe on their own machine domain. Its authorized document handler verifies the same static HTML before serving it there. The public HTML URL is a download, not a page for running a machine on the website's domain. Files named hardwarejs.js or hardwarejs.html inside a repository are never executed by the launcher. Machine subdomains expose only these official runtime assets. Repository files and kernels are downloaded through the website.

Download or resume from the command line

Create an export, save its ID, then download its signed URL. These examples use a public repository; for a private one, add an Authorization: Bearer header with a token that has repository read access to the API requests. Keep signed download URLs private.

BRINTOS_SERVER=https://brintos.io
REPO=brintos/linux-6.12-glibc-bash-coreutils
curl -fsS -X POST "$BRINTOS_SERVER/api/repos/$REPO/image-exports" \
  -H 'Content-Type: application/json' -d '{"snapshot":"latest"}' > export.json
curl -fL --output machine.img "$(jq -r .url export.json)"

Export identities last 24 hours. Download grants last 15 minutes and can be renewed against the same export after checking access again. If a download is interrupted, keep export.json and resume with a renewed URL:

EXPORT_ID=$(jq -r .exportId export.json)
curl -fsS "$BRINTOS_SERVER/api/repos/$REPO/image-exports/$EXPORT_ID" > renewed.json
curl -fL -C - --output machine.img "$(jq -r .url renewed.json)"

Renewal keeps the same filesystem even if the live image changes, a new backup is captured, or the selected backup is renamed. Start a new local image file when creating a different export. Byte ranges and If-Range are supported. Resuming inside a large unchunked file can require reading that whole object again to verify its integrity.

Local development directory

The same launcher can boot a local directory instead of an ext4 image. If your prepared root filesystem contains its versioned kernel under boot/, run:

node brintos.js --fs ./rootfs

This directory is writable, so guest changes modify the local files. It needs a matching wasm32 kernel with virtio-fs support. The website supplies its verified official runtime at launch. See Build locally, run locally for the development workflow.

hardwarejs.js command-line arguments

ArgumentMeaning
--image <path>Boot a local ext4 image read-write by default. Guest changes persist in the .img file. Discovers the versioned kernel under /boot using 7z or 7zz unless --kernel is supplied.
--read-onlyOpen the local image and mount ext4 read-only. Requires --image.
--fs <directory>, -f <directory>Boot a local development filesystem directory instead of --image. Discovers a single versioned kernel under /boot by default.
--kernel <path>, -k <path>Use a local wasm32 kernel file. With both --kernel and --init supplied, booting an image does not need 7-Zip after the launcher has been extracted.
--init <path>, -i <path>Program inside the guest to run as PID 1. Image default: /bin/bash when present, otherwise /bin/sh. Directory default: /bin/sh.
--ram <MiB>Kernel memory limit. Cloud launches use the machine RAM setting, bounded by the selected kernel's limit. Local directories and images default to 256 MiB.
--machine-ram <MiB>Aggregate RAM reported to the guest, including kernel and user memory. Cloud launches default to the machine RAM setting; local launches default to --ram. Must be at least --ram.
--user-ram <MiB>Initial memory per guest process. Cloud launches default to 2 MiB; local launches default to 64 MiB. Clamped to --user-max when larger.
--user-max <MiB>Maximum memory per guest process. Default: 256 MiB.
--cmdline <text>Extra kernel command-line text. Quote values containing spaces. Default: none.
--gateway-origin <origin>Enable the guest HTTP gateway and allow this origin. Repeat for additional origins. Default: gateway disabled.
--gateway-app-origin <origin>Identify the brintOS API origin among the allowed gateway origins so read-only gateway rules recognize this machine's filesystem API.
--gateway-read-onlyMake the optional HTTP gateway refuse repository mutations. This does not change the local image write mode.
--help, -hPrint the launcher options and terminal controls, then exit. Works offline.

These options belong to the verified HardwareJS runtime loaded by brintos.js. Choose either --image or --fs on the shared launcher; use node brintos.js --help for its supported options. The selected kernel filename determines the official runtime version.