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 state | Automatic selection |
|---|---|
| You can write, and live is idle | Live, with an exclusive usage lease |
| You can write, but live is already in use | Latest published snapshot, read-only |
| You have read access only, including anonymous public access | Latest 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
- Open a machine from Explore or your repositories.
- Click Launch live to open
/OWNER/REPO:live. A backup launches at/OWNER/REPO:SNAPSHOT-NAME. - 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_TOKENChoose 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.
brintos.js command-line arguments
| Argument | Meaning |
|---|---|
--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-mode | Execute /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-only | Refuse 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-only | Make the HTTP gateway refuse repository mutations. This is separate from the cloud filesystem's --read-only option. |
--help, -h | Print 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.
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
| Argument | Meaning |
|---|---|
--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-only | Open 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-only | Make the optional HTTP gateway refuse repository mutations. This does not change the local image write mode. |
--help, -h | Print 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.