Everything between your
code and the device.

ArdaForm is four pieces that only make sense together: an application folder in your own git repository, a runtime that runs it on the device, the portal you manage everything from, and the device images that put the runtime on hardware. This page walks the whole loop — from a commit on your laptop to a screen on a counter three hundred miles away, and back.

git push to deployPacked on the serverSealed on the deviceOffline firstAdopt over LAN or BluetoothLive screen and consoleReverse SSH
01 / Composition

Four pieces,
one loop.

Each part is useful on its own. Together they close the gap between "the demo works on my desk" and "two hundred of them work in customer sites".

The application

A folder in your git repository: app/index.html, its assets, and an optional manifest.json declaring datasets and settings.

The runtime

ArdaPlayer — one static Go binary that draws your page straight on the display hardware and hands it window.Arda.

The portal

Where you manage it all from a browser: projects, branches, devices, data, files, settings, the device screen. Behind it, ArdaForm's servers (the control plane), which every device keeps in touch with.

Deploy →Working

The device images

A Raspberry Pi image, a PC image and a USB installer stick from the portal's Downloads. Flash, boot, adopt. No Linux administration.

●
You only write the first piece If you can write basic HTML and JavaScript, you can build an app and run it on one device — or hundreds. The other three pieces are ArdaForm's: you download them, click through them, or simply use them. The rest of this page is how they work underneath, for anyone who wants to know.
02 / From push to device

How a commit
reaches a device.

You push to GitHub; the devices take it from there. Nothing needs opening on the customer's network: each device keeps its own secure connection out to ArdaForm, and checks every instruction that comes down it — a signed message — before it acts.

A / git push
</>

Your repository

The ArdaForm GitHub App reads the branch you connected to a project. Push, and ArdaForm hears about it.

B / Pack
.ARDA●

Sealed on the server

The commit's app folder becomes one encrypted file (AES-256-GCM). Nothing from the repository is ever run.

C / Instruct

A signed instruction

Addressed to one device, carrying the file's fingerprint (SHA-256) and the key that opens it. It waits until the device is there to take it.

D / Apply

Verify, stage, swap

The device downloads it, checks the fingerprint, opens it in memory, gets it ready — and your app picks the moment to switch.

Checked on the device (SHA-256) Container opened in memory only App chooses when to reload

No build step, by design

ArdaForm packs files; it never runs them. No npm install, no scripts, nothing executed from a customer's repository on our infrastructure. Symlinks, dotfiles and .env files are refused at the door.

Per branch, per project

A project has branches; each branch is fed by one connection to one git ref. A device follows one branch, so "what is on the device" always has exactly one answer.

The app picks the moment

An update arrives staged. The page is asked; five seconds of silence and it applies. An app mid-transaction can pause it, up to five times. A branch can also be set to a time window, or to apply only when the app says so.

03 / Data

Offline is the
normal case.

Shop Wi-Fi drops. A router reboots. Somebody unplugs the wrong thing. A device that stops working because a DNS lookup failed is not a product — it's an incident.

So ArdaForm assumes the network will drop. Your app reads its data — a price list, a member list, today's bookings — from a copy kept on the device (a dataset), and saves what happens — a sale, a check-in — into a queue on the disk (the outbox) that survives a power cut and sends itself when the connection is back. Pictures and documents (files) are synced the same way and served from /storage/. The copy on the device always catches up with the portal's.

Under the hood: datasets are sealed on the device's disk; the outbox delivers at least once and is acknowledged by sequence number; files are content-addressed and hash-checked; nothing on the device is ever authoritative.

  1. 01
    DatasetsListed in the app's manifest, edited in the portal or through the HTTP API. Each device can be given only its own share — one site, one till (its partition). Asking for one keeps it up to date.
  2. 02
    OutboxOne call queues a record; it travels when it can. A record over 128 KB is refused where your code can still see it.
  3. 03
    SettingsFields the developer declares, values the operator sets — per project, with per-device overrides — delivered as a frozen object before your first line runs. A change saved in the portal reaches a running device in about three seconds.
sale.js an app on a till
// Server truth, already on the disk, sealed
const catalogue = await Arda.db.dataset('catalogue')

// Re-read when a sync lands
Arda.on('sync', (name) => {
  if (name === 'catalogue') render()
})

// Durable — queued locally, delivered later if the line is down
const { seq } = await Arda.db.push('sales', {
  till:  Arda.config.till_no ?? 1,
  items, total,
})

// A picture the file plane has synced
img.src = '/storage/catalogue/' + item.image
04 / Looking after it

What the fleet
tells you back.

Support is where device businesses lose money. Everything below exists so that "it's frozen again" can be answered without a two-hour drive — from the device's screen in the portal.

Presence

Online or offline, from the device's own regular check-in (its heartbeat). A device that reboots or shuts down on purpose says goodbye first, so the portal shows it offline at once instead of after a missed check-in.

Machine snapshot

Hostname, board, OS, player version, local IP, the screens attached and what model each panel is, inputs, audio, printers and serial adapters — refreshed as things change.

Log capture

Switch it on and the app's own console.* lines stream in — including the last few hundred lines from before you asked. It switches itself off again.

Device view

A picture of the screen, on demand or every few seconds; the live console; one expression evaluated in the page; the page source — and a lossless, full-resolution screenshot of every connected screen, with a download button.

Controls

Brightness, contrast and volume sliders that move the real screen as you drag, and a scale per screen; reboot, shut down, apply a waiting update, approve a device an install code held back, issue a new device password — and Remove, which wipes it.

SSH

A terminal on the device from your browser, even behind the shop's router — a reverse tunnel over the connection it already holds. It reaches only what the device itself offers, never another machine on the network. Ordinary SSH from the shop's network stays shut behind the device's firewall until you open it from the same tab, for a set time.

i
Adoption, too A new device on the same network as your browser appears in the project's Adopt tab with nothing typed. A headless one can be found over Bluetooth, handed its Wi-Fi and adopted from Chrome. And an install code on a USB stick or an image registers a device before anyone has seen it. How registration works.
05 / Honesty

What works today.

ArdaForm is under active development. Most of it is running on deployed hardware right now; some of it is a design we haven't finished. Here is the split.

PieceStatusNotes
ArdaPlayer runtimeWorkingPure-Go binary, WPE WebKit on the bare display, x86-64 and ARM64, in production on Raspberry Pi tablets and an x86 till.
git push → deviceWorkingGitHub App, per-branch connections, server-side packing, signed instructions, staged apply with the app choosing the moment.
Datasets, outbox, files, settingsWorkingSealed on the device, partition-scoped, gzip on the wire, at-least-once outbox, content-addressed files.
Device images & USB installerWorkingRaspberry Pi image, PC image, installer stick with a touch install app. Published from the portal's Downloads.
Adoption: code, LAN, Bluetooth, install codesWorkingActivation code on screen; same-network adopt; Web Bluetooth with Wi-Fi hand-over; install codes with optional approval.
Android playerWorkingThe same runtime as an Android app — one APK for tablets, displays and TV boxes (Android 7 or newer; arm64, armv7, x86-64), downloaded from this site and the portal’s Downloads, not from Google Play. Activation, sync, Wi-Fi printers, the battery and the portal’s device page work as on Linux; a box set up as device owner gets kiosk mode from the portal. Installing it.
Remote supportWorkingLog capture, screen pictures, console, screenshots, sliders, reverse SSH, peripherals tab, alerts per device. A firewall on every device; External SSH opened from the portal for a set time, with keys installed from there.
Player self-updateWorkingPushed as a signed instruction, tried once before it is armed, three-start rollback guard.
Printers, serial, scanners, screens, audioWorkingRaw ESC/POS, ZPL, Star, TSPL and ESC/P (dot-matrix) printers; USB-serial; keyboard-wedge readers; backlight and DDC/CI; ALSA volume.
Cameras on screensWorkingRTSP and IP cameras shown live in the app — the camera's own video, hardware-decoded where the board can, with a motion-JPEG fallback.
WebhooksWorkingThe app calls your server; ArdaForm makes the request — signed when you give it a key, verifiable when Verify is on — and logs every delivery. The key never reaches a device.
Public sign-upWorkingAnyone can create an account on the order page. The free plan needs no card; Basic and Pro are paid by card. Sign in with a password, or with Google or GitHub.
Public Bluetooth setup pageIn progressA device with no network already points to ble.ardaform.net, where a phone gives it a Wi-Fi network (ArdaPlayer v1.2.3). Changing the Wi-Fi of a device that is online, behind the device's password, is not built.
MarketplaceIn progressListing an app from a project's tab and installing it from the shop front work. Paid apps — per device or per install; monthly, yearly or one-off — are paid to the seller's own Stripe account. A per-device app is bought as licences: more at any time, charged for the rest of the period; fewer from the next renewal. Built and tested in Stripe's test mode; real payments for apps are not switched on yet.
GPIO, camera capture, face matchingPlannedDesigned around; not started. (Showing a network camera already works — above.)
Next

Look inside
the runtime.

ArdaPlayer is the part that actually meets the hardware — one Go binary, a WebKit surface on the bare display, and a deliberately narrow bridge between them.