A private research browser using local AI for capturing the web, running entirely on your own hardware.
Build Knowledge Hubs, generate new research hooks, and ask grounded questions to the web pages you explore.
🔒 No cloud • 💸 No subscription • 🚫 No account • 📊 No telemetry
ÆTHER is a Tauri-native desktop browser built for local knowledge work. It turns ordinary browsing into a private research loop: save useful pages, organize them into knowledge hubs, embed them on-device, and ask AiON for citation-backed answers grounded in what you actually captured.
It is not a cloud wrapper and it is not an external chatbot sidebar. The local wisdom path runs in the app process through GGUF models and a bundled llama.cpp runtime.
| Surface | What it does |
|---|---|
| Dashboard | A calm home for saved portals, knowledge hubs, and saved iCE atlases. |
| Browser | Normal browsing with tabs, search/address entry, quick capture, and current-page AI actions. |
| AiON | A local knowledge sidepanel that answers from captured hubs, the current page, or both. |
| iCE | The Information Complexity Explorer: iceberg-style conceptual maps generated locally. |
- Automatic Setup: fresh installs can download the recommended local model pack from official sources.
- Private Local Capture Pipeline: readable page text is extracted, chunked, embedded, and stored locally.
- Grounded Local Answers: AiON renders markdown answers with copy support, compact metrics, and clickable citations.
- Knowledge Hubs: create, reorder, edit, and organize captured pages into persistent local collections.
- iCE Maps: generate layered concept atlases for research topics. Create a Cartography of Topics for new research hooks.
- Native Shell: Tauri, Rust commands, Vite renderer, and no required local server sidecar.
| Grounded local answers | Complexity maps |
|---|---|
ÆTHER's capture, retrieval, and captured wisdom workflow is designed to stay on your machine.
Local by design:
- Extracted page text and capture metadata
- Knowledge hub metadata
- Embeddings and vector chunk storage
- Retrieval queries and RAG prompts
- AiON answers generated by in-process local models
- iCE topic maps
Normal browsing is still normal browsing. Websites can make their own network requests, track sessions, run JavaScript, and communicate with their servers. The privacy boundary applies to ÆTHER's indexing and intelligence pipeline, not to third-party websites loaded in the browser.
Fresh installs use AiON Launch, the in-app setup flow for downloading local models into the app-data model directory. The same setup flow is available later from Settings for repair or manual installation.
| Model | Role | Official source | Size |
|---|---|---|---|
| AiON MiST | Required embedding model for search, capture, and retrieval | Qwen/Qwen3-Embedding-0.6B-GGUF |
~0.64 GB |
| AiON LiTE | Smaller, faster chat model for everyday answers and summaries | google/gemma-4-E2B-it-qat-q4_0-gguf |
~3.35 GB |
| AiON WiSE | Larger chat model for richer synthesis and iCE maps | google/gemma-4-E4B-it-qat-q4_0-gguf |
~5.15 GB |
Install choices:
- MiST + LiTE: best default for laptops, mobile-class hardware, and quick grounded answers.
- MiST + WiSE: better for deeper synthesis, longer answers, and iCE generation.
- MiST + LiTE + WiSE: lets the user switch between speed and depth.
Manual development installs can also place models here:
./aether-models/
embeddings/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf
chat/gemma-4-E2B-it-qat-q4_0-gguf/gemma-4-E2B_q4_0-it.gguf
chat/gemma-4-E4B-it-qat-q4_0-gguf/gemma-4-E4B_q4_0-it.gguf
Environment overrides:
export AETHER_CHAT_MODEL=/absolute/path/to/chat.gguf
export AETHER_EMBEDDING_MODEL=/absolute/path/to/embedding.gguf
export AETHER_MODEL_DIR=/absolute/path/to/a/model/folderThese requirements are based on the current three-model setup. RAM depends mostly on the active chat model: installing both LiTE and WiSE uses more disk, but the app only needs to run the selected chat model alongside MiST.
| Platform | AiON LiTE minimum | AiON WiSE minimum | Recommended |
|---|---|---|---|
| macOS Apple Silicon | M1, 8 GB RAM | M1/M2, 12 GB RAM | 16 GB RAM, SSD |
| macOS Intel | 4-core Intel, 16 GB RAM | Not ideal | Apple Silicon preferred |
| Windows x64 | 4-core CPU, 8 GB RAM | 6-core CPU, 12-16 GB RAM | 16 GB RAM, AVX2 CPU, SSD |
| Linux x64 | 4-core CPU, 8 GB RAM | 6-core CPU, 12-16 GB RAM | 16 GB RAM, AVX2 CPU, SSD |
| Linux ARM64 / Raspberry Pi | 8 GB RAM | 16 GB RAM | Raspberry Pi 5 16 GB with active cooling |
| Android ARM64 | 8 GB RAM | 12-16 GB RAM | Recent high-end SoC, 12 GB+ RAM |
Storage guidance:
| Install choice | Raw models | Minimum free storage | Comfortable |
|---|---|---|---|
| MiST only | ~0.64 GB | 2 GB | 4 GB |
| MiST + LiTE | ~3.99 GB | 7 GB | 10 GB |
| MiST + WiSE | ~5.79 GB | 10 GB | 14 GB |
| MiST + LiTE + WiSE | ~9.14 GB | 14 GB | 20 GB+ |
Current runtime note: macOS builds use llama.cpp Metal acceleration. Windows and Linux builds are CPU-only in the current Cargo configuration.
The left rail is the main app switcher:
- ÆTHER opens the dashboard.
- iCE opens the Information Complexity Explorer.
- Web View switches back to browser content.
- Settings opens the global settings modal.
- AiON can be opened from the right-side panel control.
Settings controls app-level preferences:
- Default search engine.
- Developer Mode, which exposes more advanced/experimental funtionality.
- Keyboard shortcut reference.
The browser chrome includes:
- Back and forward controls.
- Address/search field.
- Tabs with favicon fallback and dynamic theme tinting.
- New tab creation.
- AI quick actions for current-page prompts.
- Capture controls in browser mode.
- Selected knowledge hub dropdown.
Address behavior:
- Full URLs navigate directly.
- Search-like text is sent to the selected default search engine.
- Default search engines currently include Google, Bing, Yahoo, Ecosia, and DuckDuckGo.
The dashboard is the internal home surface. It shows:
- Compact saved portals for fast page reopening.
- Compact saved iCE atlases for reopening generated complexity maps.
- Knowledge hub accordions.
- Capture source cards with hub indicators.
Portal behavior:
- Save the current page as a portal from the browser controls.
- Reorder portals by dragging.
- Open portals into browser tabs.
- Delete portals from the dashboard.
Knowledge hub behavior:
- Create hubs with a name, description, and searchable icon.
- Reorder hubs by dragging.
- Expand a hub to show its captured sources.
- Captured sources are shown as compact scrollable lists inside expanded hubs.
- Drag captured source cards between hub accordions.
- Click captured source links to open them in a new browser tab.
- Edit/delete hub controls live in the accordion header.
Saved iCE behavior:
- Saved atlases appear on the dashboard as compact cards.
- Opening an atlas restores its topic, model metadata, and generated depth map in iCE.
- Saved atlases can be deleted from the dashboard.
AiON is the local wisdom sidepanel.
Ask mode:
- Pressing Enter submits a non-empty prompt.
Cmd+A/Ctrl+Aselects all text in the prompt field.- Empty hubs with
0 capturesor0 chunksare hidden because they cannot contribute context. - Browser quick actions open AiON and ask against current-page-only context.
- If no populated hubs exist, AiON defaults to current-page-only context.
- If populated hubs exist, rows show icon, hub name, and capture count.
- Current page context can be toggled with a larger button-style control.
- Answers are markdown-rendered, selectable, copyable, and citation-backed.
- Completed answers include a small metrics subtitle with token rate, chunk count, and elapsed time.
- Duplicate citation URLs are deduplicated before display.
- Citation clicks open the source in a browser tab.
- The embedded Flow panel auto-updates a semantic trail from the active page or an optional Focus topic.
- Developer Mode exposes expanded local chat and embedding model controls.
The iCE view maps a topic into an iceberg-style complexity atlas.
It generates five depth layers:
- Surface: common language
- Formation: adjacent concepts
- Cold Current: methods and mechanisms
- Black Ice: specialist patterns
- Abyssal Lattice: hidden edge knowledge
The iCE canvas includes:
- Topic search input.
- In-process local model generation.
- Depth scoring that encourages all five layers to be represented when the topic has enough usable material.
- Manual saving and reopening of generated atlases.
- Zoom in/out/reset controls.
- Smooth view reset and zoom transitions.
- Layer zone tinting and labels.
- Layer filter buttons with counts.
- Disabled filter controls before results exist.
- Ordered topic list with selected fragment details and click-to-focus canvas zoom.
- Loading state with glassmorphic canvas blur and icy particle effects.
- Staggered reveal after results arrive.
ÆTHER stores app data under Tauri's app data directory.
Current storage paths:
<appData>/aether-library/library.json
<appData>/aether-realms/chunks.json
<appData>/aether-settings/settings.json
<appData>/aether-icebergs/icebergs.json
./aether-models/
library.json stores:
- Knowledge hub summaries.
- Saved portal shortcuts.
- Capture summaries.
- Capture counts.
- Chunk counts.
- Legacy migration flags.
chunks.json stores embedded chunk rows:
idvectortextcollectionIdcaptureIdtitleurlappIdcapturedAtchunkIndex
settings.json stores app preferences such as the default search engine, Developer Mode, and selected local model paths.
icebergs.json stores manually saved iCE generations:
- Saved iceberg metadata.
- Original keyword, model, and generation timestamp.
- Full iceberg item lists for reopening in iCE.
When the current browser page is captured:
- Renderer calls
window.aether.capture.currentPage({ collectionId }). - The Tauri command validates the selected knowledge hub.
- The Rust backend reads the active desktop child webview snapshot when available, then falls back to fetching the active URL over HTTP.
- It collects page URL, title, description, body text, and metadata.
- Rust parsing normalizes readable text and rejects pages below the minimum readable text threshold.
- The backend creates overlapping chunks.
- Chunks are embedded through the in-process llama.cpp runtime.
- Chunk rows are stored on disk.
- Capture metadata is persisted to
library.json. - Renderer refreshes collection and capture summaries.
Moving a capture between hubs updates both:
- The capture's
collectionIdinlibrary.json. - Matching chunk rows so future search and Ask retrieval follow the moved source.
Deleting a capture removes both:
- The manifest capture summary.
- Matching chunk rows.
Search flow:
- User enters a query.
- Query is embedded with the configured embedding model.
- The local chunk store returns nearest chunks scoped to the selected hub.
- Renderer receives typed
SearchResultobjects.
Ask flow:
- User chooses current page, a populated hub, or both.
- If a hub is selected, top chunks are retrieved from the local vector chunk store.
- If current page is included, the active page is extracted and added as context.
- Duplicate source citations are merged.
- The local chat model receives a grounded prompt.
- AiON renders the markdown answer, compact metrics subtitle, and citation badges.
The intended answer behavior is grounded: when hub context is used, the model should answer from supplied context rather than inventing unsupported facts.
Renderer React UI
|
| window.aether typed API
v
src/renderer/src/tauri-aether.ts
|
| Tauri invoke() commands and event listeners
v
Rust Tauri Backend
|
|-- Native browser view manager
| desktop child webview tabs, dashboard visibility, resize, popups, history
|
|-- Library storage
| knowledge hubs, captures, saved portals, migration metadata
|
|-- Settings storage
| default search engine and app settings
|
|-- Capture pipeline
| active page snapshot or fetch -> readable text -> chunks
|
|-- Local model runtime
| llama.cpp GGUF loading, Metal offload, embeddings, chat, and iCE generation
|
|-- Local chunk store
| vector search and chunk metadata
|
|-- iCE generator
| local chat prompt -> parsed iceberg JSON -> typed renderer result
Rust backend responsibilities:
- Owns browser views and tabs.
- Owns file-system writes.
- Owns local chunk storage and vector search.
- Owns in-process local model loading and inference.
- Owns capture extraction from the active page.
- Exposes typed Tauri command results to the renderer.
Renderer responsibilities:
- App shell and UI state.
- Dashboard, browser chrome, AiON, iCE, modals, and interactions.
- Drag/drop interactions for portals, hubs, and captured source cards.
- Calls typed
window.aetherAPIs instead of direct Tauri, database, or file-system access.
Required:
- Bun for dependency management and scripts.
- Rust and the Tauri platform prerequisites for your target OS.
- CMake, required for building the bundled llama.cpp Rust binding.
- macOS, Windows, or Linux for desktop development.
- Android Studio, Android SDK/NDK, and Rust Android targets for Android builds.
Install dependencies:
bun installRun the app in development:
bun run devRun checks:
bun run typecheck
bun run lint
bun run build:viteBuild compiled app bundles:
bun run buildÆTHER now has Tauri Android scripts, but the local Android SDK/NDK must be installed before Tauri can initialize or build the Android project.
Install Android Studio, then install these SDK pieces through Android Studio's SDK Manager:
- Android SDK Platform
- Android SDK Build-Tools
- Android SDK Platform-Tools
- Android NDK
- Android Emulator, if you want emulator testing
Set the Android environment variables in your shell profile:
export ANDROID_HOME="$HOME/Library/Android/sdk"
export ANDROID_SDK_ROOT="$ANDROID_HOME"
export NDK_HOME="$ANDROID_HOME/ndk/$(ls "$ANDROID_HOME/ndk" | sort -V | tail -n 1)"
export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator:$ANDROID_HOME/cmdline-tools/latest/bin:$PATH"Install Rust Android targets:
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-androidAccept the Android SDK licenses after installing or updating SDK packages:
yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --licensesInitialize the Android project once:
bun run android:initRun on a connected device or emulator:
bun run android:devIf this reports No available Android Emulator detected, start an emulator from Android Studio's Device Manager or connect a physical device with USB debugging enabled, then confirm it is visible:
adb devicesBuild Android release artifacts:
bun run android:buildBuild an APK:
bun run android:build:apkBuild an AAB for Play Store distribution:
bun run android:build:aabAndroid outputs are generated under:
src-tauri/gen/android/app/build/outputs/
Current mobile limitation: the React shell can be packaged for Android, but ÆTHER's current live browser tab surface uses Tauri desktop child webviews. That desktop-only browser surface must be replaced with an Android-compatible browser path before the Android app behaves like the macOS Tauri app.
Use the Docker-based Linux build script (scripts/build-linux.sh) to build a Linux package from macOS or another non-Linux host. Arch is parametrized, defaulting to arm64:
bun run linux:arm64:build # aarch64 .deb
bun run linux:x64:build # x86_64 .debThis runs an ubuntu:24.04 container, installs the Linux Tauri + llama.cpp build dependencies (including cmake/clang), installs Bun and Rust inside Docker volumes, and builds a .deb.
The default export is a Debian package for Ubuntu:
bun run linux:arm64:deb
bun run linux:x64:debArtifacts are generated under (slug is arm64 or x64):
src-tauri/target-linux-<slug>/<target-triple>/release/bundle/
The script keeps Linux-specific dependencies out of the host project by mounting per-arch Docker volumes for /work/node_modules, /root/.cargo, /root/.rustup, and /root/.bun.
Note: building x86_64 on an arm64 Mac (or vice-versa) runs under QEMU emulation, which is very slow for the llama.cpp C++ compile. For the non-native arch, prefer CI (see below).
Optional overrides:
LINUX_IMAGE=ubuntu:24.04 bun run linux:arm64:build
LINUX_BUNDLES=deb,appimage bun run linux:arm64:build
LINUX_DOCKER_PLATFORM=linux/amd64 LINUX_TARGET=x86_64-unknown-linux-gnu LINUX_ARCH_SLUG=x64 bun run linux:arm64:buildBecause Tauri cannot cross-compile desktop targets, and llama.cpp builds natively per-OS, the cross-platform installers are produced by .github/workflows/build.yml:
macos-latest→ styled.dmginstaller.windows-latest→ NSIS.exe/ MSI installer.ubuntu-latest→ x86_64.deband AppImage.ubuntu-24.04-arm→ ARM64.debfor devices such as Raspberry Pi / Compute Module boards.- Android job → manual workflow artifact only for now; it is not published on tagged desktop releases until the mobile build is signed and product-ready.
Trigger it from the GitHub Actions tab (workflow_dispatch) or by pushing a v* tag. Off macOS, llama.cpp runs CPU-only (the metal feature is gated to macOS in src-tauri/Cargo.toml).
On a v* tag push, a final release job publishes a clean set of stable installer asset names to the GitHub Release:
AETHER_macOS.dmgAETHER_x64-setup.exeAETHER_amd64.debAETHER_arm64.debAETHER_amd64.AppImage
GitHub also adds source archives automatically. On a manual workflow_dispatch run, installers are uploaded as workflow artifacts instead of a release.
Keep release versions synced from package.json:
bun run version:bump 1.0.1
bun run version:check
git add package.json src-tauri/Cargo.toml src-tauri/Cargo.lock src-tauri/tauri.conf.json
git commit -m "chore: release v1.0.1"
git tag v1.0.1
git push origin main
git push origin v1.0.1Build the current desktop app with Tauri:
bun run build| Script | Purpose |
|---|---|
bun run dev |
Start the Tauri desktop app in development. |
bun run start |
Alias for the Tauri desktop development app. |
bun run dev:vite |
Start only the Vite renderer dev server on 127.0.0.1:1420. |
bun run format |
Format the project with Prettier. |
bun run typecheck:web |
Run renderer TypeScript checks. |
bun run typecheck:tauri |
Run Rust cargo check for the Tauri backend. |
bun run typecheck |
Run renderer TypeScript checks and Rust cargo check for the Tauri backend. |
bun run version:bump 1.2.3 |
Sync package.json, src-tauri/Cargo.toml, and src-tauri/tauri.conf.json to one app version. |
bun run version:check |
Verify the app version manifests match package.json. |
bun run lint |
Run ESLint. |
bun run build:vite |
Build only the Vite renderer assets into dist/. |
bun run build |
Typecheck and build the Tauri desktop app. |
bun run build:desktop-local |
Build local desktop packages for the current Tauri target plus Docker Linux arm64/x64 packages. |
bun run android:dev |
Run the Tauri Android app on a connected device or emulator. |
bun run android:build:apk |
Build an Android APK. |
bun run android:build:aab |
Build an Android App Bundle. |
bun run linux:arm64:build |
Build an Ubuntu arm64 Tauri package in Docker. |
bun run linux:x64:build |
Build an Ubuntu x86_64 Tauri package in Docker. |
bun run linux:arm64:deb |
Build an Ubuntu arm64 .deb package in Docker. |
bun run linux:x64:deb |
Build an Ubuntu x86_64 .deb package in Docker. |
Important output/resource directories:
| Path | Owner | Purpose |
|---|---|---|
dist/ |
Vite/Tauri frontend | Compiled renderer assets consumed by Tauri. This is not a distributable app by itself. |
src-tauri/target/ |
Tauri/Cargo | Desktop app binaries and bundles generated by tauri build. |
src-tauri/target-linux-<slug>/ |
Tauri/Cargo in Docker | Ubuntu Linux build cache and bundle output (arm64 or x64). |
src-tauri/gen/android/app/build/outputs/ |
Tauri Android/Gradle | Android APK/AAB outputs. |
build/ |
project resources | Packaging resources such as icons. This is input to packaging, not output. |
Common Tauri outputs:
src-tauri/target/release/bundle/
src-tauri/target-linux-arm64/aarch64-unknown-linux-gnu/release/bundle/deb/ÆTHER_1.0.0_arm64.deb
src-tauri/target-linux-x64/x86_64-unknown-linux-gnu/release/bundle/deb/ÆTHER_1.0.0_amd64.deb
src-tauri/gen/android/app/build/outputs/
For quick local desktop testing, prefer:
bun run devUse bun run build when you need packaged Tauri desktop artifacts.
Desktop packaging is now driven by Tauri config:
src-tauri/tauri.conf.jsonis the main desktop/mobile Tauri configuration.src-tauri/tauri.linux.conf.jsonlimits the Docker Linux arm64 export to.debby default.src-tauri/capabilities/default.jsoncontrols the default Tauri permissions surface.
Local desktop builds are suitable for development on your own machine. For external macOS distribution, configure Apple Developer ID signing and notarization in the Tauri packaging flow before shipping.
If a packaged app behaves differently from development, rebuild from a clean package state:
bun run buildAdd local models to the project-local model directory shown in the AiON model settings, or point the app at explicit files:
export AETHER_CHAT_MODEL=/absolute/path/to/chat.gguf
export AETHER_EMBEDDING_MODEL=/absolute/path/to/embedding.ggufAdd Qwen3-Embedding-0.6B-Q8_0.gguf to ./aether-models/embeddings/Qwen3-Embedding-0.6B-GGUF/, or add another embedding GGUF to ./aether-models/embeddings/.
Add a chat GGUF, preferably Gemma-family for the current prompt template, to ./aether-models/chat/ or select it from the AiON model menu.
Some pages are login screens, app shells, canvases, PDFs, or script-heavy views with little static readable text. Navigate to a text-heavy page first, then capture again.
The desktop app allows browser popups through Tauri child webview handling and routes external flows where appropriate. If a specific provider still fails, check whether the site requires browser APIs the system webview does not expose by default, third-party cookies, or platform authenticator behavior that needs additional native integration.
Move the missing runtime package into dependencies, reinstall, and rebuild:
bun install
bun run buildUse Vite-compatible asset imports or renderer-public assets. Avoid assuming /some-file.svg will resolve the same way in development and inside packaged Tauri assets.
Recheck and rebuild the Tauri backend:
bun run typecheck:tauri
bun run buildStale package output can preserve old assets or bundle metadata. Rebuild from a fresh package state:
bun run buildIf needed, delete stale dist/ and src-tauri/target/release/bundle/ output manually before rebuilding.
Settings uses the public GitHub Releases API to check whether a newer ÆTHER release exists. If the check fails, verify general network access to GitHub and that the repository has a published, non-prerelease release that is publicly readable without being logged in. Private repositories or private/draft releases return 404 to the unauthenticated in-app checker even if you can see the release in your browser.
iCE depends on the local chat model returning parseable JSON. Try:
- Use a stronger chat model.
- Regenerate with a simpler topic.
- Check the model menu for the active chat model.
- macOS packages are local unsigned/ad-hoc builds until Developer ID signing and notarization are configured.
- Capture quality depends on page structure, active webview snapshots, and fallback HTTP extraction quality.
- App-like authenticated services can still have browser API or popup edge cases.
- iCE generation depends on local model quality and JSON compliance.
- Update checks notify about newer app releases, but they do not download or install updates yet.
- Search and Ask currently use one selected hub plus optional current page, not arbitrary multi-hub selection.
Likely next improvements:
- Production signing and notarization flow.
- Import/export for knowledge hubs.
- Full capture library view with filtering and bulk actions.
- Per-hub retrieval/model settings.
- Better authenticated-app compatibility coverage.
- Capture selected text or a selected DOM region.
- More precise token-aware chunking.
- Richer iCE export/share behavior.
- More complete settings surface.
ÆTHER's own code and releases are source-available under the
PolyForm Strict License 1.0.0 (see LICENSE). You may download
and use ÆTHER for permitted noncommercial purposes under that license.
Redistribution, resale, paid redistribution, commercial hosted/service use, modified builds, or derivative works require separate written permission from CanPixel. This is not an OSI open-source license because it restricts commercial use, redistribution, and modification.
Modified builds are not official ÆTHER releases and must not imply endorsement
by CanPixel. See TRADEMARKS.md for the project branding
policy. External contributions require a signed Contributor License Agreement
(CLA) or another written contributor agreement.
Bundled and downloaded third-party software and AI model weights (Gemma 4 E2B /
E4B and Qwen3-Embedding-0.6B, all Apache-2.0, plus libraries such as llama.cpp,
Tauri, and candle) are governed by their own licenses, reproduced in
THIRD_PARTY_LICENSES.md, not by the ÆTHER license.