A desktop web browser for macOS and Windows, written in Rust. Pages render through Chromium, embedded with the Chromium Embedded Framework (CEF); the window chrome (tab strip, address bar, settings) is drawn with egui. There is no HTML in the chrome. Nautilus is the Chromium sibling of Paladin, which runs the same chrome and model on the Servo engine: both are built on osmena, the shared shell, and this repository holds only what is Chromium's.
- The Launch Panel. Ctrl+T (Cmd+T on macOS) and "+" open a panel over the window instead of a blank tab: a search-or-address field with the history and bookmark matches dropping down under it, and tiles beneath: the Google Drive files you opened last (after "Connect Google Drive"; only in builds made with a Google client id, see Local development), today's weather where you are (the panel asks the system for your location, which is what asks you about it; you can name a place on the tile instead), Ask Claude and Ask ChatGPT fields that open the question in a new tab, and the five sites you visit most. The gear opens the Launch Settings in the panel: the search engine (Google, DuckDuckGo, Bing, Brave, Kagi or custom), the question templates, the weather location and units, the Google account, and the tiles themselves, dragged to reorder or closed to remove. All of it is osmena's; the Google client id is this build's.
- Chromium under the hood. Pages render through Chromium (CEF 154), with its site isolation, sandboxless for now (see Known limitations). The chrome is drawn with egui; menus are the system's own popup menus.
- Crashes stay in their tab. Each page runs in one of Chromium's renderer processes. A renderer that crashes shows an error panel in that tab with the reason; every other tab keeps working.
- Multi-select tabs. Cmd/Ctrl-click and Shift-click select several tabs, then drag them together onto another window or onto the desktop for a new one, or right-click to close them all, move them to a window, or open them in another profile.
- Profiles. Each profile has its own settings, cookies, and local
storage, and a name, a colour and an avatar. The avatar at the
toolbar's end opens the Profiles menu (also in the macOS menu bar),
shaped like Chromium's: Edit… customises the current profile, the
other profiles sit under "Other Nautilus Profiles" and open in a
window of their own, Add Nautilus Profile… makes one (name it, pick
its theme colour and an avatar from the sea-creature or the assorted
palette, choose whether to share the default profile's bookmarks and
whether to copy the default profile's extensions; history is never
shared), Open Guest Profile starts a throwaway "Guest" browser whose
profile is deleted when it closes, and Manage Profiles… lists every
profile to open, edit or delete.
--profile <dir>picks one on the command line, and a tab can be handed to another profile from its context menu. - Your colour. The profile dialog and the settings window offer a row of swatches that tint the tab strip and toolbar per profile.
- Sleek by default. No system title bar: the tab strip is the title bar, with the window controls at its end. "Use the system title bar and borders" in Settings brings the frame back.
- Chrome extensions. Install from the Chrome Web Store (click "Add to Chrome" on an extension's page, pick "Install the extension on this page" from the puzzle-piece menu, or paste its URL or id into Settings) or load an unpacked directory; pin them to the toolbar, where their popups open under the button; switch them off or remove them in Settings.
- Session restore. "Continue where you left off" brings the windows and tabs back where they were (tabs load when first shown); after a crash a bar offers the last session; the update's restart restores it too.
- Downloads. Files go to the Downloads folder (or the one Settings names) under their names; a button at the toolbar's right end fills a ring as they arrive and opens a list (Ctrl+J) with pause, resume, cancel, open, show in folder, retry and clear; quitting mid-download asks first.
- Page zoom. Ctrl and + or − (or the wheel) zoom the page through Chromium's steps; every tab on the site follows and the site remembers its level; a chip beside the address bar shows it; Ctrl+0 resets.
- Find in page. Ctrl+F opens a bar at the top right of the page; Chromium highlights every match as you type and scrolls to the active one, with the count beside the field; Enter and F3 step forward, Shift+Enter back, "Aa" matches case, Escape closes.
- Bookmarks. The star beside the address bar (or Ctrl+D) bookmarks the page and opens a popover to name it, pick its group, or remove it; the bookmarks bar (Ctrl+Shift+B) shows the "Bookmarks bar" group as chips with favicons and the other groups as drop-downs; the Bookmarks menu imports and exports an HTML bookmarks file; bookmarks appear among the address bar's suggestions with a star.
- Tab folders and bookmark groups. Fold a selection of tabs behind one chip in the strip, or bookmark it as a named group to reopen from the menu.
- Chromium's right-click menu. Open a link in a new tab or window, save or copy it, copy or save an image, loop a video, copy, paste, or search selected text, print, view the source, or inspect an element in Chromium's developer tools; Ctrl-click and middle-click open links in background tabs, Shift-click in a new window.
- Search from the address bar. Text that is not a URL is searched, with Google unless Settings names another engine.
- Your default browser (macOS). The bundle declares itself a web browser, so System Settings lists it under "Default web browser"; while it is not the default a bar under the toolbar offers to make it so (Make default, Don't ask again, Not now), and Settings has the same button. Links clicked in other apps, and pages opened with Nautilus from the Finder, open as tabs.
- Keyboard first. Every control is a command with Chromium's shortcut (Cmd for Ctrl on macOS), chords work even while the address bar has focus, and Settings remaps them the way a game's controls screen does: a primary and a secondary slot per action, click and press.
- Engine-agnostic design. Only one crate imports CEF, and it implements
osmena's
Enginetrait; the model and the UI are osmena's, shared with Paladin and unit-tested without an engine.
| Layer | Choice |
|---|---|
| Language | Rust 1.97.1 (pinned in rust-toolchain.toml), edition 2024 |
| Engine | Chromium 154 through CEF (the cef crate 154.5), confined to crates/nautilus-engine |
| Shell | osmena: the model, the egui 0.34 chrome on winit 0.30, the settings window, pinned by git revision |
| Chrome GL | osmena's glutin surface (Chromium paints into memory, so the chrome owns the GL context) |
| Pages | CEF off-screen rendering: each tab paints BGRA frames that osmena draws as a texture |
| Packaging | cargo xtask bundle-mac for the macOS .app (CI zips it), cargo-packager's NSIS installer on Windows |
| CI | GitHub Actions on macOS and Windows runners |
crates/
nautilus-engine/ CEF glue: osmena's Engine and TabHost over CEF, handlers -> events, frames
nautilus/ The binary: the Brand, Chromium's process preamble, the command line, packaging metadata
xtask/ `cargo xtask icons` (osmena's icon task for logo.svg -> icns/ico/png)
assets/
logo.svg The shell logo (pure vector)
icons/ Generated from logo.svg; committed
docs/
design-plans/ Approved designs
upstream-issues.md
The Launch Panel's Drive tile needs a Google OAuth client id at build
time: set NAUTILUS_GOOGLE_CLIENT_ID in the environment to the id of a Google Cloud
"Desktop app" client (it is not a secret) and build; CI reads the
repository variable of the same name. Without it the build has no
Drive tile and nothing else changes.
The model, chrome, and winit application come from the osmena crates,
pinned by git revision in the workspace Cargo.toml. To change them
alongside Nautilus, check osmena out next to this repository and patch the
source to it in ~/.cargo/config.toml (osmena's README has the table);
then bump the revs here once the change is pushed.
Prerequisites: a Rust toolchain via rustup (the pinned version installs on
first cargo run), and the tools that build CEF's C++ wrapper library:
CMake and Ninja on PATH, plus a C++ toolchain (Xcode Command Line Tools
on macOS; Visual Studio 2022 Build Tools with the "Desktop development with
C++" workload on Windows). No Python, LLVM, or GStreamer.
The cef-dll-sys crate's build script downloads the CEF binary distribution
(about 420 MB on Windows) into its OUT_DIR unless CEF_PATH points at a
shared copy, which survives cargo clean and is reused by every checkout.
To set one up once:
cargo install export-cef-dir --version 154.5.0 --locked
export-cef-dir --force ~/.local/share/cef # downloads and unpacks
export CEF_PATH=~/.local/share/cef # add to your shell profileOn Windows the build copies the CEF runtime files (libcef.dll, the
.pak resources, locales/, and the rest) next to the binaries in
target/<profile>/, so cargo run works from the tree.
On macOS Chromium runs only from an app bundle (the framework and its
helper apps have to sit at fixed places around the executable), so
cargo run cannot start it there. Build the bundle instead and run it:
cargo xtask bundle-mac # builds the release binaries first
open target/release/Nautilus.app # or, with arguments:
target/release/Nautilus.app/Contents/MacOS/Nautilus --profile dev https://example.com- Build and run:
cargo run(Windows) or the bundle (macOS, above) opens a window at the homepage. Pass URLs to open them as tabs, or--profile <name>to use another profile. - Icons: edit
assets/logo.svg, runcargo xtask icons, and commit the regenerated files inassets/icons/. CI fails if they are stale.
The first build compiles CEF's
libcef_dll_wrapperwith CMake (a minute or two) and then Nautilus's own crates. Incremental builds take seconds.
Profiles live in ~/Library/Application Support/Nautilus/profiles/<name>/
on macOS and %APPDATA%\Nautilus\profiles\<name>\ on Windows, holding
settings.toml (homepage, new-tab URL, chrome colour) and Chromium's
chromium/ directory (cookies, local storage, cache). A profile directory
belongs to one running Nautilus at a time.
cargo test --workspace— unit tests innautilus-engine(frame composition, key mapping; nothing starts Chromium). The model, chrome, and routing tests live in osmena.cargo clippy --workspace --all-targets -- -D warningsandcargo fmt --all --check— what CI runs.
Run with cargo run after any change to the chrome, input handling, or
engine glue. Each item must pass.
- Launch. A window opens with one tab at the homepage and the page renders. There is no system title bar: the tab strip ends in the minimize, maximize, and close controls, the toolbar in the profile avatar and the ☰ menu, and the taskbar shows the shell logo with the title Nautilus. Dragging the strip's empty space moves the window, double-clicking it maximizes, and the pointer becomes a resize arrow at every edge and corner.
- Address bar. Type
example.comand press Enter: the page loads, the tab title becomes "Example Domain", and the address bar showshttps://example.com/. Typinglocalhost:8080targetshttp://. Typerust programming languageand press Enter: a Google search for it loads. Settings has Search engine and Search URL fields; change the URL tohttps://duckduckgo.com/?q={query}and the next search goes there. - History. Navigate to a second page, then use Back and Forward: the buttons enable and disable with the history and the pages change. Reload reloads the current page; while a page loads, a Stop button appears beside it and stops the load.
- Tabs. "+" or Cmd+T (Ctrl+T on Windows) opens a new tab, activates it, and puts the keyboard focus in the address bar with its text selected, so typing a URL and pressing Enter loads it in the new tab; clicking a tab title switches tabs and the address bar follows; "×" and middle-click close a tab and the neighbour to the right becomes active; closing the last tab closes the window and the process exits. Selection. With three tabs open, Cmd-click (Ctrl-click on Windows) the first: it gets a tinted fill while the third stays active; Shift-click the first from the third selects all three; a plain click leaves only the clicked tab selected. Right-click a selected tab: the menu offers "Close 3 tabs", "Close other tabs" (disabled when all are selected), "Move 3 tabs to new window" (same), "Move 3 tabs to window" (disabled with one window), and "Open 3 tabs in profile" (disabled with no other profile directory). Right-click an unselected tab: it becomes the active and only selected tab and the menu says "Close tab". Open a second window with Cmd+N, select two tabs in the first, and drag one of them onto the second window: both appear at the end of its strip (reloaded, with the previously active one active) and leave the first. Drag a tab onto the desktop: it opens in a new window. Dropping within the same window does nothing. "Open tab in profile" starts a second Nautilus for that profile with the tab's URL and closes the tab here. Both this menu and the "☰" menu are the system's own popup menus.
- Crashed tab. Open
chrome://crashin a tab: the tab's error panel says the renderer process crashed, the other tabs keep working, and the terminal showstab crashed: ...; Back, Forward, and Reload clear the panel. - Resize and HiDPI. Resize the window: the page follows within a frame and stays aligned under the toolbar. Drag the window to a display with a different scale factor: text stays sharp and clicks land where expected.
- Input. Scrolling with the wheel or trackpad over the page scrolls it;
clicking a text field on a page and typing enters text; double-click
selects a word; typing in the address bar does not reach the page.
Hovering a link shows its URL in the status overlay at the bottom left
and the pointer becomes a hand; over text it becomes an I-beam. A
<select>opens its list over the page and picks on click. Drag and drop. On a page with draggable elements and a drop zone (any HTML5 drag-and-drop demo), press on an element and drag: an image of it follows the pointer, the zone reacts as the pointer crosses it (itsdragenter/dragoverstyling), the pointer shows no-drop elsewhere, and releasing over the zone drops it there; releasing over the toolbar or outside the window, or pressing Escape mid-drag, cancels the drag and the element returns to normal, hovering as before. Selected text dragged into a text field on the same page lands there. Page menu. Right-click a link: a native menu at the pointer offers Open link in new tab, Open link in new window, Save link as…, Copy link address, and Inspect. "Open link in new tab" adds a tab right after this one without leaving this one; "Copy link address" then Ctrl+V in the address bar pastes the URL. Right-click an image: Open image in new tab, Save image as…, Copy image, Copy image address. Right-click a text field: Undo, Redo, Cut, Copy, Paste, Paste as plain text, Delete, Select all, with their shortcuts, and the spelling suggestions for a misspelled word. On macOS, Cmd+Z, Cmd+X, Cmd+C, Cmd+V, Shift+Cmd+V, and Cmd+A pressed in the field do what those entries do (Nautilus carries them out itself; there is no Edit menu). Select some text and right-click it: Copy, Search Google for "…", Print…. Right-click empty page: Back, Forward, Reload (with their shortcuts), Save as…, Print…, View page source, Inspect. "Save link as…" opens the system's Save As dialog and, once saved, the status overlay reads "Saved ". "View page source" opens aview-source:tab. "Inspect" opens Chromium's developer tools in a window of their own, on the element; closing the tab closes them. - Page-opened tabs. Middle-click or Ctrl-click a link: a new tab
opens at the URL right after the current one, which stays active
(Ctrl+Shift-click activates the new tab). Shift-click a link: it
opens in a new window. Let a page call
window.open: a new tab opens at the URL in the same window and becomes active. - Windows and menu. Cmd+N (Ctrl+N on Windows), or New window chosen with the mouse from the "☰" menu, opens a second window; each window's tabs, address bar, and page are independent, and closing one leaves the other working.
- Shortcuts. With Cmd on macOS or Ctrl on Windows: T new tab, W close tab (also Ctrl+F4 on Windows), Shift+T reopens the last closed tab, Shift+W close window, N new window, L focus the address bar with its text selected (also Alt+D on Windows), R reload (also F5 on Windows), period Stop, Shift+] and Shift+[ on macOS or Tab and Shift+Tab and PgDn/PgUp everywhere next and previous tab (wrapping), 1 to 8 the tab at that position and 9 the last tab, comma opens settings, Q quits. Back and forward are Cmd+[ and Cmd+] on macOS and Alt+Left and Alt+Right on Windows; the homepage is Cmd+Shift+H or Alt+Home; F11 (Ctrl+Cmd+F on macOS) shows the page alone and again brings the chrome back. A chord held down fires once, and none of its key strokes reach the page. Shortcuts also work while the address bar has focus.
- Settings. Settings (Cmd+, or chosen with the mouse from the menu)
opens a window with Homepage, New tab URL, a row of chrome colour
swatches, the "Use the system title bar and borders" checkbox, the
restore checkbox, and the Keyboard shortcuts table. Edits are saved when a field loses
focus or the window closes; relaunching opens the new homepage. Click a
swatch: every browser window's tab strip takes that colour at once.
Title bar. Tick "Use the system title bar and borders": every open
window gets the system frame at once on Windows (on macOS, the next
window opened); untick it and the strip is the title bar again.
Shortcuts. Click the primary slot of New tab: it reads "Press
keys…"; press Ctrl+Y (Cmd+Y): the slot shows it,
keymap.tomlin the profile directory holdsnew-tab = ["Ctrl+KeyY"](Meta on macOS), and Ctrl+Y opens a tab while Ctrl+T no longer does. Give Reload's secondary slot Ctrl+Y: New tab loses it and a note under the table says so. Right-click a slot to clear it; "Reset to defaults" puts everything back and the file lists the defaults. - Extensions. The toolbar ends in a puzzle piece. Open
https://chromewebstore.google.com/detail/ublock-origin-lite/ddkjiahejlhfcafbddmgiahcphecmpfh,
click the puzzle piece: "Install the extension on this page" is
enabled; pick it (or, when the store shows its "Add to Chrome"
button, click that: the page says the install was cancelled, and
the install still happens). Within a few seconds the puzzle menu lists uBlock
Origin Lite; Settings (Ctrl+,) lists it under Extensions with
Enabled ticked, and the profile has
chromium/extensions/ddkjiahejlhfcafbddmgiahcphecmpfh/manifest.jsonwith akeyfield. Tick "In toolbar": its icon appears beside the address bar (and the menu's "Pin to toolbar" submenu shows it checked). Click the icon: the extension's popup opens under it, sized to its content; Escape closes it, as does a click back into the window; clicking the icon again while it is open closes it. Untick Enabled: the icon goes; tick it again: it is back. "Load unpacked…" opens a folder dialog; cancelling it is not an error. Remove: the extension leaves the list, the menu, and the directory. Relaunch: installed extensions are still there, and no Chromium window appears (the management page runs in a window that is never shown). - Folders and bookmarks. Open three tabs. Right-click the second:
the menu has "Close all selected (1)" (disabled with one selected),
"Move tab to folder…", and "Bookmark all selected (1)…". Pick "Move
tab to folder…": a prompt over the page offers "Folder A"; Enter.
The strip shows a chip "▸ Folder A (1)" in the tab's place; click
it: a list drops down with the tab, and clicking the tab there
activates it. Right-click the chip: Expand, Rename…, Ungroup, Close
folder (1 tab). Expand: the tab appears after the chip, which reads
"▾ Folder A". Ctrl-click the other two tabs, right-click one, "Move
2 tabs to folder…", pick Folder A from the existing-folder choice:
the folder holds three tabs, together. "Bookmark all selected…" on a
selection asks for a group name; type Work, Enter: the profile has
bookmarks.tomlwith the pages, and ☰ → Bookmarks → Work lists them with "Open all (n)", which opens each in a new tab. Folders are gone after a relaunch; bookmarks stay. On a page, press Ctrl+D (Cmd+D on macOS): the star beside the address bar fills and a popover "Bookmark added" opens under it with the title and the group "Bookmarks bar"; Enter closes it and the page is in ☰ → Bookmarks → Bookmarks bar. Ctrl+Shift+B shows the bar under the toolbar with the page as a chip (its favicon once the site reported one); clicking the chip loads the page, right-clicking it offers Open in new tab, Open in new window, Copy link address, Edit… and Delete. Click the star again: the popover reads "Edit bookmark"; pick "New group…", type Reading, Done: the chip moves out of the bar and a "Reading ▾" chip at the bar's right end lists it with Open all, Rename group… and Delete group. Typing part of the page's title in the address bar offers it with a star before any history match. - Profiles. Click the avatar at the toolbar's right end (the
profile's initial on its colour): the menu lists the current profile
(checked) with "Edit…", the other profiles, "Add Profile…" and a
"Delete Profile" submenu. "Edit…" opens "Customize your profile"
over the page with the name selected, the colour swatches and the
avatars (the initial, then the "Sea creatures" and "Assorted"
palettes); type Alice, click the plum swatch and the whale, tick
"Share bookmarks with the Default profile" and Save: the chrome
turns plum, the toolbar shows the whale, the window title ends in
"– Alice", the menu reads "Alice", and
settings.tomlhas[profile]with the name,avatar = "whale"andshare_bookmarks = true. "Add Profile…", type Work Stuff and tick "Copy extensions from the Default profile", Add: a second window opens for the new profile (its own colour and avatar, title "– Work Stuff"), andprofiles/work-stuff/settings.tomlexists. From the first window, Delete Profile → Work Stuff asks "Delete “Work Stuff” and everything it holds?"; with the second window still open, Delete reports in the status area that the profile is open in another window; close it and delete again: the directory is gone and the menu no longer lists it. Edit… → "Delete profile…" on a non-default profile hands over to the Default profile and quits. - Find in page. On example.com press Ctrl+F: a pill opens at the
page's top right with the keyboard in its field. Type
domain: the page highlights both matches, the first in orange, and the bar reads "1 of 2". Enter: "2 of 2" and the second match is orange; Shift+Enter goes back. Typexyzafter it: "No matches" and the arrows disable. Escape closes the bar and the highlights go. Ctrl+F again reopens it with the previous text selected. - Page zoom. On example.com press Ctrl and = twice: the page grows
and a "125%" chip appears beside the address bar; Ctrl and the wheel
over the page step it; the chip's click offers −, + and Reset. Open
example.com in a second tab: it opens at 125%. Ctrl+0: both tabs
return to 100% and the chip goes;
zoom.tomlin the profile has no entry for the site. - Downloads. Load a release asset's address (a
latest.tomlfrom the Releases page): the file lands in the Downloads folder and a downloads button appears at the toolbar's right end. Ctrl+J opens the list with the file and its size; Open starts the default program, Show in folder selects it in Explorer, × forgets it. Load a large file: the ring on the button fills as it arrives, the row shows received of total and the speed, Pause and Resume work, and Cmd+Q asks before quitting; Cancel leaves a row with Retry. - Session restore. Turn on "Continue where you left off" in Settings, open a second tab, move the window, quit. Launch again: the window is where it was with both tabs, the one that was active loaded and the other faint; click the faint tab and it loads. Kill the process (Task Manager) and launch: a bar under the toolbar offers the last session; Restore brings the tabs back and the home-page window goes; Dismiss leaves the home page.
- Typing (macOS). In a page's text field (a login form's email
field), type a word with E and D in it, then press Backspace once:
every letter appears, one character goes, and neither the emoji
palette nor the dictation prompt opens. Left and Right move the
caret one place per press. Ctrl+Cmd+Space opens the palette (what it
inserts is still lost, E2 in
docs/upstream-issues.md). - Default browser (macOS). On a profile where Nautilus is not the
default, a bar under the toolbar says so; "Make default" brings the
system's question, and choosing Nautilus there makes the bar go and
Settings → Default browser read "Nautilus is your default browser."
System Settings → Desktop & Dock → Default web browser lists
Nautilus. With it the default, a link clicked in Mail or Notes opens
as a tab and brings the window forward; with Nautilus not running it
starts and shows only that link. "Open With → Nautilus" on an
.htmlfile in the Finder opens it. "Don't ask again" keeps the bar away after a restart; the Settings checkbox brings it back. - Dock icon (macOS). While running, the Dock shows the same icon as the Finder: a white rounded square on Apple's grid, as large as its neighbours, with no black outline.
- Clean exit. Closing the last window and Cmd+Q both exit with code 0,
and no
nautilusprocess is left behind (Task Manager /ps).
cargo xtask bundle-macbuilds the release binaries (nautilus and nautilus-helper), lays out
target/release/Nautilus.app the way CEF needs it (Chromium Embedded Framework.framework under Contents/Frameworks, copied from the CEF
distribution at CEF_PATH, and the five helper apps beside it, Nautilus Helper, … (GPU), … (Renderer), … (Plugin), … (Alerts), each a
copy of nautilus-helper), writes the property lists (the browser's
claims the http and https schemes and HTML pages, which is what
makes macOS offer it as a default browser), and signs the
bundle ad hoc (Apple silicon runs no unsigned code; there is no
Developer ID yet). CI builds it on every push to main for both Mac
architectures, on an Apple silicon runner and on an Intel one (CEF
ships a distribution for each, and the cef crate picks the one for
the build's target), starts each once on its runner as a smoke test
(a local page with --exit-after: the browser must exit cleanly and
must have read the page's title, which proves the helper processes
ran from the bundle; a launch that exits cleanly without the title is
tried again on the same profile, up to three times, because the first
launch of a fresh profile sometimes stalls on the Intel runner, C6 in
docs/upstream-issues.md), and uploads the workflow artifacts
nautilus-macos-15 (Apple silicon) and nautilus-macos-15-intel
(Intel), each with Nautilus-macos-<arch>.zip (arm64 or x86_64),
Nautilus-<arch>.dSYM.zip (the symbols, for crash logs) and the
smoke test's logs. The Intel bundle also runs on Apple silicon under
Rosetta, which is how to try it without an Intel Mac; the Apple
silicon bundle does not run on an Intel Mac. A bundle downloaded from
CI carries the quarantine attribute and,
being signed ad hoc, is refused as "damaged" when opened; clear the
attribute first:
xattr -dr com.apple.quarantine Nautilus.appThere is no .dmg yet, and no universal bundle: the CEF framework is
a few hundred megabytes per architecture, so the two bundles stay
separate.
GitHub retires its Intel macOS runners together with the macOS 15
image, expected in fall 2027. Revisit the Intel build in 2027: keep
it only if Intel Macs still matter then, and otherwise drop the
macos-15-intel entries from .github/workflows/ci.yml and this
section.
cargo install cargo-packager --version 0.11.8 --locked once, then:
cargo build --release -p nautilus
cargo packager --release -p nautiluscargo packager also runs cargo build --release -p nautilus itself (its
before-packaging-command), so the bundle always matches the current
source. The installer picks up libcef.dll and the other CEF runtime files
that the build copied into target/release/ (the resources globs in
crates/nautilus/Cargo.toml). Output lands in target/release/ as
nautilus_<version>_x64-setup.exe (NSIS, per-user install), unsigned. CI
builds it on every push to main and uploads it as the workflow artifact
nautilus-windows-2025, together with nautilus.pdb (the release profile
keeps line tables) so a crash in an installed build can be symbolized.
Every green push to main also becomes a GitHub release
(https://github.com/thomasmost/nautilus/releases), tagged build-<run number> and titled "Nautilus (build )", made by
the workflow's release job from the package job's artifacts: the
Windows installer, both macOS bundles as zips, the symbol files, and latest.toml, the
update manifest (ci/update-manifest.sh writes it; the format is
osmena-core's update::Manifest). GitHub's
releases/latest/download/latest.toml always points at the newest
release, and that is the URL in crates/nautilus/src/brand.rs.
The browser updates itself from it (osmena's flow, see its README): the
package job sets OSMENA_BUILD_NUMBER to the run number, which the
brand reads at compile time, so a running build knows whether a release
is newer. It checks 15 seconds after it starts and every six hours,
downloads the newer build into <config dir>/Nautilus/updates/,
verifies it, and shows a green "Restart to update" pill in the toolbar
(also "Restart to update Nautilus" in the ☰ menu and the application
menu on macOS, and in Settings, whose Updates section has the
"Check for updates and download them in the background" switch, "Check
now" and the release notes). The restart runs the installer silently
on Windows (it closes every other Nautilus window, other profiles
included, and installs over the previous location) or swaps the bundle
on macOS, and starts the same profile again. A build made outside CI
has no build number and never updates itself; "Check for updates…" is
disabled in it. A rerun of a workflow run replaces that run's release.
- Visual Studio 2022 Build Tools with the "Desktop development with C++" workload (MSVC v143 and a Windows 10/11 SDK).
- CMake and Ninja on
PATH(winget install Kitware.CMake Ninja-build.Ninja). - Rust via https://win.rustup.rs/; the pinned toolchain installs on first use.
- The Microsoft Visual C++ Redistributable, which the installer does not bundle: https://aka.ms/vs/17/release/vc_redist.x64.exe.
Upstream causes and the features they block are tracked in
docs/upstream-issues.md.
- No renderer sandbox. CEF's sandbox on Windows requires the browser to
be started through CEF's
bootstrap.exewith the browser built as a DLL, and on macOS a signed helper layout; Nautilus starts CEF withno_sandboxuntil that is built (roadmap). Site isolation and separate renderer processes still apply. - Page frames go through system memory (CEF's software off-screen path); CEF's shared-texture path would skip the copy and is a later step.
window.openopens a tab at the URL but the opener gets no handle to it (the call returns null), so pages that script the new window do not work.- No IME composition for page text fields yet: egui-winit only enables IME
for its own fields. The emoji palette (Ctrl+Cmd+Space) and dictation
open, but winit drops the text they insert (E2 in
docs/upstream-issues.md). - The default-browser offer and the links other apps hand over are macOS only; on Windows the installer does not register Nautilus as a browser yet.
- macOS 26 masks app icons made with Icon Composer (an
.iconcompiled intoAssets.carby Xcode 26'sactool, which CI's runners do not have); Nautilus ships an.icnsdrawn on Apple's grid (assets/logo-macos.svg), which macOS 15 and earlier show as is and macOS 26 may show inside its own tile. - A download in progress is cancelled when the browser exits (the list marks it interrupted, with Retry).
- Drag and drop stays within a page: no system drag starts, so nothing can be dragged out of a page (to another tab, window, or application), and files from the desktop cannot be dropped in. A drag released anywhere but over its own page is cancelled.
- Without the system title bar, Windows 11's snap-layouts flyout on the maximize control is not available (snap by dragging still is), and the frameless window has not been tried on macOS.
- macOS has had one run by hand (2026-10-20: launch, a page, the
extension manager starting and shutting down); the rest of the manual
checklist is untried there (see the handoff in
CLAUDE.md). - On GitHub's Intel macOS runner, the first launch of a fresh profile
sometimes never loads a page; a second launch does (C6 in
docs/upstream-issues.md). Not seen on Apple silicon, and no Intel Mac has been tried by hand. - Extensions: an action popup on macOS is a borderless child window of
the browser window (
popup.rs); it was built from the Windows behaviour and not yet clicked by hand. Extension popups see Chromium's own tabs, not Nautilus's:chrome.tabs.query({active: true})finds the hidden management page, so a popup that acts on "the current tab" acts on nothing. An action without a popup cannot be clicked. The Web Store may show "Switch to Chrome" instead of an install button (install through the puzzle menu or Settings then); when it shows "Add to Chrome", the button installs through Nautilus but the page reports the install as cancelled. Store extensions do not update themselves. Themes and apps are not listed. Chromium records an install, switch, or removal in its preferences up to ten seconds later, so closing the browser within that time keeps the process alive, windowless, until it has. - No H.264 video or AAC audio. The CEF binaries Nautilus builds
against are open-source Chromium builds without the patented codecs
(Chrome ships them under Google's licence). Pages that serve only
H.264 show their player's "missing codecs" message; VP8, VP9, AV1,
Opus, and Vorbis play, so YouTube and most large services work. The
fix is a CEF built from source with
proprietary_codecs=true, a full Chromium build per platform redone on every CEF bump; not planned. - The macOS menu bar (osmena's: Nautilus, File, Edit, View, History, Bookmarks, Profiles, Tab, Window) has not yet been tried on a Mac by hand; nor has the Profiles menu there, which since 2026-10-26 lists the profiles by name with Edit…, Add Profile… and Delete Profile. Its Edit entries reach the page as CEF frame commands, the way the page context menu's do.
- Restore previous windows on launch is stored in
settings.tomlbut not yet acted on. - No history UI or sync.
- Thorium (a Chromium fork with compiler and feature patches) publishes no
CEF distribution; building CEF from Thorium's tree is possible but is a
multi-hour Chromium build, so Nautilus tracks stock CEF for now. See
docs/design-plans/2026-10-19-nautilus-chromium-browser.md.
- macOS
.dmg, and a Developer ID signature in place of the ad-hoc one - Renderer sandbox (
bootstrap.exeon Windows, helper layout on macOS) - Accelerated off-screen rendering (shared textures)
- IME composition for page text fields, and text from the emoji palette and dictation (E2)
- Register as a browser on Windows (the installer's
Capabilitieskeys) and offer to become the default there - An Icon Composer icon for macOS 26
- A history page