Skip to content
BETACurrent release v0.4.0-betaRelease notesGitHub

Tech stack and build

Home Screen is a small Rust server with the web interface compiled into it. This page lists what is inside and how the pieces fit.

flowchart LR
  browser([Browser]) -->|HTTP| hs
  subgraph hs[home_screen: one program]
    srv[HTTP server<br/>127.0.0.1:7878]
    ui[Web interface<br/>embedded in the binary]
    db[(SQLite file<br/>bundled library)]
    srv --- ui
    srv --- db
  end

There is no separate web server, no Node.js at run time and no database service to install.

Piece Used for
std::net (our own server.rs) The HTTP/1.1 server: one thread per connection, keep-alive, strict limits. About 400 lines instead of an async web framework. See Binary size
rusqlite (bundled SQLite) The database. SQLite is compiled in, so nothing is installed, with the optional parts (full-text search, R-tree, JSON, extension loading and more) switched off
build.rs Embeds the web interface: the web build leaves a gzip copy of each file, and the server sends those bytes unchanged with Content-Encoding: gzip, so the program needs no decompressor
serde / serde_json JSON for the API
http_client.rs + native-tls The curl runner’s outgoing requests: our own small HTTP/1.1 client over native-tls. Windows uses schannel and macOS uses Security.framework (the operating system’s own TLS and certificate store); on Linux, OpenSSL is compiled in, so the Linux binary is static

The server has 4 direct dependencies and 55 crates in total. It is about 3734 lines of Rust.

Piece Used for
Preact + @preact/signals The UI, in a tiny runtime
Tailwind CSS 4 + DaisyUI 5 Styling and components, with the dim theme
Vite 6 Build tool
marked Parses Markdown tokens for the previewer (it never produces HTML)
qrcode-generator QR code encoding

Only 4 npm packages ship in the web interface. The rest of the launcher, from the calculator and unit converter to the cron parser, diff, regex and colour maths, is written in plain JavaScript in this repository: about 13618 lines.

The web source is split in two. web/src/core/ is the app itself: the grid, tile editor, launcher window and state. web/src/extensions/ holds 34 extensions, one folder each, that provide the 47 widgets and 40 launcher tools. Each extension has a manifest, an entry, and an engine of pure functions. The build makes every extension its own file, and the browser fetches it the first time a tile or the launcher needs it, so a dashboard of notes and bookmarks never downloads the cron parser, the QR encoder or the Markdown tokenizer. All the files are still embedded in the program. How to add one: Extending Home Screen.

On Windows, build.ps1 does two things (on Linux and macOS you run the same two commands by hand):

  1. npm ci && npm run build in web/ produces the web interface (web/dist).
  2. cargo build --release compiles the server and embeds those files.

The result is copied to dist\home_screen.exe. Releases for every platform are built by GitHub Actions; see Releasing. The release profile is tuned for size:

[profile.release]
opt-level = "z" # optimise for size
lto = true # link-time optimisation
codegen-units = 1
panic = "abort"
strip = true # no debug symbols

A clean release build takes about 47 seconds on the measurement machine.

619 automated tests run on every change: 555 in Vitest (parsers, converters, the launcher engines, widgets) and 64 in Rust (the database layer and SVG sanitiser). The QR generator is checked by decoding its output with an independent QR reader.

Only when a feature is used, and only from your browser: Iconify (icons), Google’s favicon service (link icons), Open-Meteo (weather) and Frankfurter (currency rates). Everything else works offline. See Privacy and security.

The site you are reading is built with Astro and its Starlight theme from Markdown files in the docs/ folder of the repository. The screenshots are generated by a script from a fictional workspace and stored as WebP.

Support the project: Buy Me a Coffee or GitHub Sponsors.