Feeds, saved pages, and notes. One library that lives on your device.
InfoMatrix is a local-first reader built with a shared Rust core, SwiftUI on Apple platforms, and Flutter on Windows, Linux, and Android. Subscribe to RSS/Atom/JSON Feed, save a page for later, or write a note without an account or a server.
Screenshots are captured from the running apps with local demo content. They are not design mockups.
- Follow feeds: direct subscription, website discovery with candidate selection, groups, and OPML import/export.
- Read and organize: unread, starred, later, archive, and feed scopes; SQLite FTS5 search with a Chinese/Japanese/Korean substring fallback.
- Keep useful material: saved webpages, explicit full-text capture, and editable notes. Captured full text survives later feed refreshes.
- Carry your library: versioned local JSON backups include subscriptions, notes, captured text, reading states, settings and sync records. Restore atomically into an empty library.
- Stay responsive: Swift calls run off the main actor; Flutter uses separate persistent workers for database and network requests.
- Inspect failures: bounded HTTP bodies, conditional refresh, persisted failure/backoff state, and notification audit records.
- Keep local ownership: SQLite storage, transactional state changes, and a replayable sync journal. Apple CloudKit is optional and still needs live account/provisioning validation.
No AI service, hosted database, or telemetry is required. Background refresh runs while the app is running; this is not a claim of unrestricted background execution on mobile operating systems. Apple notification delivery is implemented; Flutter does not yet deliver native notifications.
The source on main prepares 0.3.0; no 0.3.0 release has been published. Existing downloads remain on GitHub Releases. Existing Homebrew/npm versions may therefore differ from this source tree.
| Target | App shell / package | Validation coverage |
|---|---|---|
| macOS 14+ | SwiftUI, universal ZIP + DMG | Built, ad-hoc signature verified, launched and exercised |
| iOS 17+ | SwiftUI, simulator ZIP; optional signed IPA | Built and exercised in iOS 26.3 simulator |
| Android API 24+ | Flutter, APK + AAB | Built, launched; native persistence test passed on API 36 |
| Windows x64 | Flutter, portable ZIP; optional MSIX | Build, real FFI tests and packaging run in GitHub Actions |
| Linux x64 | Flutter, Ubuntu 24.04 DEB + tar.gz | Build, real FFI tests and packaging run in GitHub Actions |
Preview packages are explicitly marked as unsigned, ad-hoc, or development-signed in their manifests. A simulator ZIP is not an iPhone installer. Store distribution and macOS notarization require the owner's signing setup.
Use Rust 1.97.0 (pinned in rust-toolchain.toml), Flutter 3.44.8, Python 3.10+, and Node 22+ for npm tooling. Apple builds additionally need full Xcode 26.3, its iOS SDK, and XcodeGen. Select Xcode per command with DEVELOPER_DIR if your global developer path points to Command Line Tools.
brew install rustup xcodegen
export PATH="/opt/homebrew/opt/rustup/bin:$PATH" # Homebrew on Apple Silicon
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
tooling/scripts/run_macos_app.shThe script builds the Rust XCFramework, packages dist/InfoMatrix.app, and runs it. No development HTTP server is needed. A local ad-hoc package does not have a notarization ticket or CloudKit entitlement.
cd core
cargo test --locked --workspace
cargo build --locked -p ffi_bridge
cd ../apps/flutter
flutter pub get --enforce-lockfile
flutter analyze
flutter testThe FFI tests load the library from core/target/debug, or INFOMATRIX_FFI_LIB_PATH when explicitly set. A missing library fails the tests. For an Android package:
# Requires Android SDK 36, build-tools 35 + 36, NDK 28.2.13676358, Java 17.
INFOMATRIX_ANDROID_ALLOW_DEBUG_SIGNING=1 tooling/scripts/package_flutter_android_release.shSee development for platform setup, release for all packaging commands, and validation for tests actually run.
python3 tooling/scripts/smoke_core.py --serve --demo-db /tmp/infomatrix-demo.sqlite
# In another terminal, after packaging:
INFOMATRIX_DB_PATH=/tmp/infomatrix-demo.sqlite dist/InfoMatrix.app/Contents/MacOS/InfoMatrix -infomatrix.cloudkit.enabled NOThis serves deterministic feeds and pages on loopback and creates a separate library. Keep the server running to exercise discovery, refresh and full-text capture. Normal app data uses the platform application data directory; see storage.
Choose 资料库备份与恢复… from the reader's more menu. Native file dialogs let you save a JSON backup or select one to restore. OPML remains available for subscription-only interchange; a library backup also preserves saved content and reading state.
Restoration requires a new, empty local library, including settings and sync history. Existing data is never overwritten or merged. Validation, inserts and search-index rebuilding form one transaction. Corrupt, mismatched-version or invalid archives fail without partial restoration. The portable format is limited to 64 MiB / 200,000 table rows and excludes device caches, pending notifications and fetch logs. Backups are unencrypted local files. See backup format and guarantees.
SwiftUI ── detached native calls ──┐
├── C ABI / JSON ── Rust core ── SQLite + FTS5
Flutter ── DB + network workers ──┘ │
bounded HTTP / feed parsing
Optional local HTTP API ─────────────────────────────────┘
| Directory | Responsibility |
|---|---|
core/crates |
Fetching, parsing, discovery, storage, sync replay, refresh and notification policy |
apps/apple |
Native Apple reader and optional CloudKit/local-notification adapters |
apps/flutter |
Windows, Linux and Android reader, worker-isolate FFI bridge |
tooling/scripts |
Version checks, builds, packaging and release verification |
packages/npm |
Checksummed desktop downloader and launcher |
docs |
Contracts, design decisions, real screenshots and validation evidence |
The optional HTTP server is a debugging/integration surface. Desktop and mobile apps call the Rust library directly. Architecture details · API · Sync semantics
CONTRIBUTING.md describes checks and boundaries. Report vulnerabilities using SECURITY.md. Known limitations and the modernization audit are in docs/modernization.md.




