"Technology is best when it disappears."

— adapted from Mark Weiser

Bare is not a small web browser. It is a reading instrument that happens to speak HTTP, Gemini and Gopher. Every engineering decision serves a single goal: turn whatever a server sends into clean, consistent, private text — and then get out of your way.

This page explains how that is built, honestly, including the things Bare deliberately does not do.


🏗ïļ The shape of the program

Bare is a Tauri 2 application: a Rust core wrapped in the operating system's own WebView, with no bundled browser engine.

ðŸŽĻ

Frontend

Vanilla HTML/CSS/JavaScript — renders finished, sanitized HTML

🌉

Bridge

Tauri IPC — message passing only, no shared network access

⚙ïļ

Rust core

fetch · extract · sanitize · render

Why this split matters:

  • All networking, parsing and sanitization happen in Rust — never inside the page.
  • The WebView only ever receives finished, already-sanitized HTML. It never talks to the network itself.
  • There is no Chromium to ship, so the entire application is a few megabytes instead of a few hundred.

🛠ïļ Main Components

ðŸĶ€

Rust

Rust is the programming language powering Bare's backend.

Why Rust?

  1. Memory safety: Rust's ownership rules prevent memory errors like buffer overflows
  2. Performance: Compiled to native code, as fast as C/C++
  3. Security: No garbage collection, no runtime overhead
  4. Concurrency: Excellent support for asynchronous programming
  5. Ecosystem: Rich package ecosystem (crates.io)

Rust libraries used in Bare:

ðŸŠķ

Tauri 2.0

Tauri is the foundational framework that makes Bare possible.

Why Tauri?

Tauri Electron
App size ~2-5 MB ~100-200 MB
Memory usage Low High
Security High (Rust) Medium (JS)
Performance High Medium
Platform support Windows, macOS, Linux Windows, macOS, Linux

Tauri advantage: 20-100x smaller, 5x less RAM, memory safety, native speed.

🌐

Vanilla Web Technologies

Bare's frontend is built with pure web technologies:

  • HTML5: Semantic markup for structure
  • CSS3: Minimal styling, focused on readability
  • JavaScript (ES6+): Clean, efficient code without frameworks

Advantages of this approach:

  1. No dependencies: No npm packages, no build steps
  2. Fast loading: No frameworks to load
  3. Easy maintenance: No version conflicts
  4. Long lifespan: Standards that don't change radically

🌐 Protocol Support

Bare supports a range of protocols to offer a rich text-based browsing experience.

🌍

HTTP/HTTPS

Standard web protocols with full support for GET, HEAD, redirects, SSL/TLS.

Special for Markdown: Bare sends an Accept header that signals preference for Markdown:

Accept: text/markdown, text/plain;q=0.9, text/html;q=0.5
🊐

Gemini

Gemini is a modern, text-based protocol with mandatory TLS encryption.

Bare's Gemini support includes:

  • Full protocol implementation (RFC)
  • TOFU (Trust On First Use) certificate handling
  • Gemtext to Markdown conversion
  • Interactive pages (input dialog)

Gemtext format:

# Heading 1
## Heading 2

This is a paragraph.

=> https://example.com Link description
ðŸŋïļ

Gopher

Gopher is the classic protocol from 1991.

Bare's Gopher support includes:

  • Full RFC 1436 implementation
  • Gophermap to Markdown conversion
  • Support for text files, menus, and search
  • Emoji icons for different content types
  • Search dialog for interactive Gopher queries
📁

Local files

Bare can open Markdown files directly from your computer via file:// protocol.


📖 The reading pipeline

The heart of Bare is what happens between "you click a link" and "you see text." For an ordinary HTML page it is four stages, all in Rust:

1. Fetch

reqwest over rustls + ring (no OpenSSL, no native-tls), capped at 5 MB, sending an Accept header that politely asks the server for Markdown first:

Accept: text/markdown, text/plain;q=0.9, text/html;q=0.5

2. Extract

A real DOM-based readability pass scores the document tree, lifts out the article, and discards navigation, sidebars, ad slots and comment threads. This replaced an earlier naive string-search method in v0.1.6 — content extraction is the core promise, so it had to be done properly, not approximated.

3. Sanitize

The result is run through ammonia, an allowlist-based Rust HTML sanitizer, stripping scripts, event handlers and anything that could carry a payload. This runs on the Markdown path too, so untrusted content is cleaned in depth, not only fenced off by policy.

4. Render

pulldown-cmark turns the cleaned Markdown into HTML with CommonMark + GitHub extensions (tables, task lists, strikethrough), and syntect adds syntax highlighting to code blocks.

Gemtext and gophermaps skip the extraction stage entirely — they are already clean by design and go straight to dedicated converters.


⚡ Speed by subtraction

Bare is fast because it does less, not because it works harder. An LRU render cache in the Rust core makes returning to a recently visited page instant; typical pages stripped to their content are 5–50 KB rather than multi-megabyte payloads; and async I/O (tokio) means fetching never blocks the interface.

Design targets the project measures itself against:

Metric Target
Cached re-render ≈ one frame (~16 ms)
Typical page, fetch → readable well under half a second
External network calls beyond the document zero
Application binary single-digit megabytes
Resident memory ~10–20 MB

🔒 Privacy the code actually enforces

Privacy in Bare is not a preference panel; it is a property of the architecture. Three mechanisms make it real rather than aspirational:

🖞ïļ

Structural image blocking

The WebView ships with a strict Content-Security-Policy of img-src 'self' data:. The page is forbidden at the engine level from loading a remote image, so a tracking pixel cannot fire even if one survives extraction. The ImageMode setting (Block · Placeholder · Show) puts that choice in your hands.

1ïļâƒĢ

One click, one request

The WebView never originates network traffic. Only the Rust core fetches, and it fetches exactly the document you asked for — no fonts, analytics beacons, or third-party assets load in the background to leak your visit.

🔑

TOFU for Gemini

Gemini connections are verified Trust-On-First-Use: a SHA-256 fingerprint of each server's certificate is stored in known_hosts.json, and a later mismatch is flagged as a possible machine-in-the-middle attack — the same model SSH uses.

No JavaScript, no cookies, no telemetry. The most private data is the data that is never collected.


🛠ïļ Build Process

Development Environment

# Clone repository
git clone https://github.com/FrankBurmo/bare.git
cd bare

# Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install Tauri CLI
cargo install tauri-cli

# Start development server
cargo tauri dev

Production Build

# Build for current platform
cargo tauri build

# Build for specific platform
cargo tauri build --target x86_64-pc-windows-msvc
cargo tauri build --target x86_64-unknown-linux-gnu
cargo tauri build --target universal2-apple-darwin

✅ Quality and trust

Bare is small, but it is not casual about correctness:

  • 117+ unit tests across the core logic — extraction, protocol clients, converters, settings.
  • Idiomatic Rust: Result + thiserror everywhere, ? propagation, almost no unwrap() outside tests, per-module error types.
  • A safe stack: rustls with ring (no OpenSSL), clamped numeric settings, allowlist sanitization.
  • 13 interface languages, in place unusually early for a project this size.

ðŸšŦ What Bare will deliberately never build

A roadmap is also a list of refusals. These are not missing features — they are guarantees:

  • No plugin or extension system. Non-extensibility is the central promise; a tool that cannot be extended cannot be quietly corrupted.
  • No JavaScript engine. Ever. It is the largest source of tracking and attack surface on the web.
  • No telemetry, no cloud sync, no accounts. Your reading is yours.
  • No author-controlled styling. Presentation belongs to the reader.

What is genuinely on the table stays in character — improvements to reading, never to running code: PDF export, heading anchors and a table of contents, and richer reading-typography controls.