Skip to content

About

Pure Rust GTK4 office suite: Tables (spreadsheet), Decks (presentations), Letters (word processor)

Topics

Resources

Code of conduct

Contributing

Security policy

Accessibility

Stars

17 stars

Watchers

1 watching

Forks

Latest commit

 

History

1,565 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

GTK Office Suite

Warning

Pre-alpha. Not usable for real work yet. Do not use Letters, Tables or Decks as a replacement for LibreOffice, OnlyOffice, Google Docs or Microsoft Office. Documents you open may look wrong on screen, and formatting that is preserved in the saved file is often not drawn in the editor. Keep using your existing office suite, and only open copies of files you care about. See Project status.

CI

Three GNOME-native office applications written in Rust with GTK4 and libadwaita, an email client and a Matrix chat client built alongside them, shipped as Flatpaks:

App What it is Reads Writes
Letters Word processor DOCX, ODT, Markdown, TXT DOCX, ODT, Markdown, HTML, PDF, TXT
Tables Spreadsheet XLSX, XLS, ODS, CSV, TSV XLSX, PDF
Decks Presentations PPTX, ODP PPTX, ODP, PDF
Lifafa Email client, built on Hylki; lives in tuna-os/lifafa Mail over IMAP, POP3, JMAP, Microsoft 365, Tuta and Proton Mail over SMTP and the same services
Mandelbrot Matrix chat client with native voice and video calls, a Fractal fork; source in mandelbrot/ Matrix rooms, threads, polls, voice messages The same, end-to-end encrypted

CSV and TSV are import-only in Tables, on purpose: saving a spreadsheet over an imported .csv would write XLSX bytes to a file everything else reads as text, so Save As offers .xlsx instead.

Lifafa (a word for envelope) is not built from this repository. It is Hylki by hyprlab with native Tuta and Proton Mail accounts added, developed in the fork tuna-os/lifafa, and it belongs to the suite by name, icon and packaging. It is published from that repository as a signed Flatpak repository on its GitHub Pages, and as bundles on its releases page (see Install). Report problems with it in tuna-os/lifafa's issues. Mandelbrot is built from mandelbrot/ (its own Cargo workspace and Flatpak manifest); see docs/SUITE-INTEGRATION.md for how the whole suite fits together.

The three apps can send the open document by email from the main menu (see docs/LIFAFA-INTEGRATION.md). Everything below this section is about Letters, Tables and Decks.

They are not a LibreOffice port. Each app has its own document model in a GTK-free *-core crate, and compatibility with other office software is measured against real LibreOffice output rather than asserted — see Project status.


Contribute compute — no code needed

Donate time with your AI CLI.

Your machine runs one task at a time using your signed-in AI coding CLI. The relay alternates between eligible School (OS) and Reef (apps) hives after each task. If one hive has no work, the other can continue.

The guide covers prerequisites, verified just setup, credentials, provider costs, and how to stop with Ctrl+C. Your subscription quota or API charges apply. Never post account credentials or API keys in issues or pull requests.

Screenshots

Captured automatically from the real applications by the Screenshots workflow, which drives each app under Xvfb. Nothing here is a mockup, but the demo documents were written to show features that work. Real-world files look worse (see Project status).

Letters Tables
Letters — styled document Tables — live range statistics and a formula
Command palette (Ctrl+K) Decks
Letters — command palette Decks — object inspector and presenter pill

Every feature, with a screenshot of each: the feature overviews for Letters, Tables and Decks, captured the same way.


Install

The applications are published as Flatpaks from the TunaOS repository:

flatpak remote-add --if-not-exists tuna-os \
    https://tunaos.org/flatpak/tuna-os.flatpakrepo
flatpak install tuna-os org.tunaos.letters org.tunaos.tables org.tunaos.decks

Then launch them from your application menu, or:

flatpak run org.tunaos.letters

Lifafa is not in the TunaOS repository; it has a signed Flatpak repository of its own (coming with its first release published there, v1.47.1-tuna6), which flatpak update follows:

flatpak install --user https://tuna-os.github.io/lifafa/org.tunaos.lifafa.flatpakref

Until then, or to install a file, download the bundle from the latest release of tuna-os/lifafa and install it with flatpak install --user org.tunaos.lifafa-<version>.flatpak. The signing key, the bundles and moving an older bundle install over to the repository are in Lifafa's install instructions.

Something not working? See docs/USER-TROUBLESHOOTING.md.

Flathub submission is prepared but not yet submitted — the remaining steps need a human and are written down in flathub/README.md.


Project status

Current release: the latest on GitHub — its version number is not a maturity claim.

Honest status: pre-alpha, not a daily driver. The file-format engines (reading and writing DOCX/ODT/XLSX/ODS/PPTX/ODP) are the most mature part and are tested against LibreOffice. The editors, meaning what you see on screen while you work, are catching up, and are now measured:

  • On-screen rendering is compared with LibreOffice's, feature by feature. The render lab draws one fixture per feature in our apps (headless, and in a browser via GTK Broadway) and in LibreOffice, and compares the two. The current results and accepted metric artifacts are in the generated table below.
  • Real-world documents and the installed Flatpak are measured too. The real-document corpus (#1200) and Tier C on a GNOME VM (#1199) expose gaps single-feature fixtures cannot. Until both are green for an app, it is not "usable for everyday documents", whatever its single features score.
  • The README screenshots come from demo documents chosen to show what works. They do not represent arbitrary real-world files.
App Single-feature fixtures, Tiers A and B Real documents Shipped Flatpak (Tier C) Status
Letters 42 / 48 green + letters/table (accepted amber); not green: letters/bullet-symbol-font-line-height, letters/floating-image-gap, letters/odt-page-break-spacing, letters/table-cell-numbered-list-indent, letters/table-row-min-height-page-break 19 / 30 green 37 / 78 green Not yet usable for everyday documents
Tables 22 / 43 green; not green: tables/filtered, tables/fit-to-width, tables/horizontal-pagination, tables/hyperlink-theme-colors, tables/oversized-unheaded-instructions, tables/paginated-columns, tables/print-scale, tables/tall-unheaded-postcodes, tables/tall-unprinted-sheet, tables/unheaded-bordered-musts, tables/wide-borderless-hyperlinks, tables/wide-column-no-headings, tables/wide-column-right-align, tables/wide-unheaded-complaint-log, tables/wide-unheaded-consumption-estimates, tables/wide-unheaded-contact-list, tables/wide-unheaded-deep-sea-stock, tables/wide-unheaded-transactions, tables/worksheet-image, tables/wrap-merged, tables/wrap-wide-default-font 2 / 30 green 16 / 73 green Not yet usable for everyday documents
Decks 17 / 18 green; not green: decks/pay-centre-reduced-line-breaks 1 / 30 green 15 / 48 green Not yet usable for everyday documents

This table is generated by tools/render-lab/readme_status.py from the render-lab scorecard (single-feature baseline and real-document baseline); CI fails when the table disagrees. Non-green real documents are tracked by render-real issues. A release also needs a green Tier C run on the release candidate and a documented gap list; see the Phase 4 exit.

Measured file compatibility (file content, not on-screen rendering). Four corpora are ratcheted in CI. The pass count may climb but never fall:

Corpus Score What it checks
CommonMark 0.31.2 652 / 652 Every spec example round-trips idempotently through Letters' model
LibreOffice ↔ Letters 109 / 109 Documents survive a real LibreOffice Writer pass
LibreOffice ↔ Decks 9 / 9 Decks survive a real LibreOffice Impress pass
OpenFormula 107 / 107 Formula evaluation against the ODF spec's own cases

These use LibreOffice itself as an oracle, not a hand-written expectation of what it would do. A missing oracle is a failure in the required lanes, never "observed compatibility". Feature-by-feature detail is in docs/PARITY.md.

Current focus: crashes and flakiness, not features. The work in docs/readiness-2026-09/ is a September readiness push. The honest summary is that it keeps finding real defects — seeded command-sequence campaigns run nightly against all three document models, recorded GUI journeys run on every pull request, and every package reader is bounded against hostile input. Each of those landed because the instrument found something, and each readiness document marks what is not done rather than rounding up.

Where this is going next: ROADMAP.md.


Build from source

You need Rust and the GTK4 + libadwaita development libraries (gtk4-rs 0.11, libadwaita 0.9, targeting the GNOME 50 runtime).

cargo check --workspace      # fast — no linking
cargo run -p letters         # or -p tables, -p decks
cargo test --workspace

A justfile wraps the common loops:

just setup        # create the toolbox container with the build dependencies
just preflight    # check + lint + test, the same gates CI runs
just test-gui-all # the AT-SPI GUI journeys, inside the toolbox

Nix

A flake gets you running without installing GTK development libraries yourself:

nix run .            # Letters
nix run . -- tables  # letters | tables | decks
nix develop          # dev shell with Rust + GTK4/libadwaita
nix build            # all three apps plus desktop/schema/icon files

nix develop points GSETTINGS_SCHEMA_DIR at flatpak/, so cargo run -p letters works immediately.

Two crates (IronCalc, rdocx) are pinned to git revisions and fetched with allowBuiltinFetchGit, so no dependency hashes need maintaining. flake.lock is not committed — run nix flake lock on a Nix machine to pin nixpkgs and commit the result.

Flatpak

flatpak run org.flatpak.Builder --state-dir=.flatpak-builder \
    build-dir flatpak/org.tunaos.letters.json

How the code is organised

Every app is split in two: a *-core crate with no GTK dependency holding the document model and file formats, and a thin GTK binary on top. That split is what makes the document models testable without a display, and it is where most of the test suite lives.

Crate GTK? What lives there
letters-core, tables-core, decks-core no Document models, file readers and writers, undo commands
letters, tables, decks yes Windows, widgets, Cairo rendering, actions
suite-common-core no Shared primitives: undo, number formats, styles, search, atomic saves, autosave
suite-common yes Shared widgets: command palette, file dialogs, toasts
suite-export no PDF export
suite-collab no The wire protocol between an app and the collabd sidecar (serde only, no network stack); off by default, see collab/ and RFC-0005

Other directories: tests/ (GUI journeys and Python harness tests), interop/ (the reviewable interoperability corpus), fuzz/ (cargo-fuzz targets), flatpak/ and flathub/ (packaging), collab/ (the collabd collaboration sidecar, its own cargo workspace and lockfile so no network crate reaches the apps), docs/, po/ (translations).

For module layout, data flow, the LibreOffice patterns this borrows from, and the dependency inventory, see docs/ARCHITECTURE.md.


Testing

Tests are layered, and the layers answer different questions:

Layer Command Question it answers
Unit and model cargo test --workspace Does the document model do the right thing?
Property and round-trip part of the above Does write → read return what went in?
LibreOffice oracle REQUIRE_SOFFICE=1 cargo test Does other software agree?
Stateful campaigns cargo test -- --ignored seed_campaign Does a long random command sequence break an invariant?
GUI journeys just test-gui-all Does the application actually do it, on a real display?

The GUI journeys drive the real applications through AT-SPI under Xvfb in a container, and can record what they did: add the verify-video label to a pull request and the recorded clips are written into its description. See docs/GUI-TESTING-SPEC.md and docs/CI-VIDEO-EVIDENCE.md.

The oracle suites need LibreOffice Writer and Impress installed; without them they fail rather than silently skip, so a green run means the oracle really ran.


Contributing

Start with docs/CONTRIBUTING.md — it covers the Rust/GTK patterns this codebase uses, commit style, module size limits and the pre-commit gates. AGENTS.md is the instruction set for automated contributors.

Good first things to look at:

  • Open issues labelled for the current readiness push in docs/readiness-2026-09/ — each document lists what is still open, with reproductions.
  • docs/PARITY.md rows that are not yet green.

File bug reports and feature requests in this repository. If you are coming from the deprecated Python applications, see the deprecation and migration roadmap.


Documentation

Document What it covers
docs/ARCHITECTURE.md Workspace layout, module structure, data flow, dependencies
docs/CONTRIBUTING.md Conventions, workflow, pitfalls
docs/DEVELOPMENT.md Environment setup
docs/GNOME-GUIDELINES.md HIG compliance rules and widget patterns
docs/OVERVIEW-VIDEOS.md The GNOME-styled overview videos: how they are recorded and kept current
docs/USER-TROUBLESHOOTING.md Common setup, build, test and runtime problems
docs/ACCESSIBILITY.md Keyboard shortcuts, keyboard-only use, and screen-reader support
docs/PARITY.md Feature-by-feature compatibility truth table
docs/TESTING.md Test strategy (docs/TEST-PLAN.md is the v1.0 plan, kept as history)
docs/GUI-TESTING-SPEC.md The AT-SPI journey harness
docs/CI-QUALITY-GATES.md What CI enforces and why
docs/readiness-2026-09/ Current readiness work, item by item
docs/RELEASE.md Release process
docs/adr/ Architecture decision records
CHANGELOG.md What changed when

License

GPL-3.0-or-later, with one directory under another licence:

  • lifafa/ (the email client, from Hylki) is AGPL-3.0-or-later; its own lifafa/LICENSE applies there.
  • mandelbrot/ (the Matrix client, from Fractal) is GPL-3.0-or-later, the same as the rest.

AGPLv3 and GPLv3 each allow the two to be combined in one work (section 13 of each), so a distribution of the whole suite is covered by both: the AGPL's network-use clause applies to the AGPL part. Details and origins are in THIRD-PARTY-NOTICES.md. All source files carry SPDX headers. The GTK-free core crates published on crates.io (suite-common-core, suite-export, tables-core) are under the same license as the rest of the office apps.

About

Pure Rust GTK4 office suite: Tables (spreadsheet), Decks (presentations), Letters (word processor)

Topics

Resources

Code of conduct

Contributing

Security policy

Accessibility

Stars

17 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages