oldj/SwitchHosts
51.3
Adequate · 27 September 2026
24.2k
lines of production code
Rust
with TypeScript
4
measurements over time
What this system is
SwitchHosts is a cross-platform desktop application for managing system hosts files, rebuilt on Tauri 2 with a React frontend. It enables users to organize, edit, and apply host configurations across Windows, macOS, and Linux, featuring silent privilege escalation on macOS and elevated writes on other platforms. The system includes robust data storage with migration support, a trashcan for deleted entries, and extensive internationalization.
How it got here
2011–2021 — SwitchHosts v5 architecture rewrite
23 changes.
The project underwent a comprehensive rewrite from a Python/wxPython desktop application to a modern Tauri 2 and React web interface. This period established the new v5 data layout, implemented a Mantine-based UI with CodeMirror, and introduced robust state management and internationalization support. The work focused on rebuilding core components, enhancing editor features, and modernizing the entire development and build tooling stack.
2023–2026 — Tauri 2 migration and v5 architecture
18 changes.
The project underwent a comprehensive rewrite to migrate from Electron to Tauri 2, introducing a Rust-based backend for native features like privileged hosts file updates and automated macOS updates. This period also established the v5 data storage layer with atomic writes and legacy migration support, while rebuilding the renderer with Mantine UI, Vite, and Jotai state management.
Features
Add system theme detection and CSS variable utilities
The renderer now includes utilities to detect and follow the operating system's color scheme preference. New code in src/renderer/utils/theme.ts provides functions to resolve the system theme (light or dark) using the prefers-color-scheme media query, listen for system theme changes, and apply the appropriate theme class to the document body. Additionally, a new css-var.ts utility allows reading CSS variable values from the document root, supporting dynamic styling based on the active theme.
src/renderer/utils · high confidence
Added German, French, Japanese, Korean, Polish, Turkish, and Traditional Chinese translations
SwitchHosts now supports seven additional languages: German (de), French (fr), Japanese (ja), Korean (ko), Polish (pl), Turkish (tr), and Traditional Chinese (zh-hant). These new language files provide full UI localization for all existing features, including the background helper, data directory management, and remote host updates, allowing users to interact with the application in their preferred language.
src/common/i18n/languages · high confidence
First-run migration from legacy Electron PotDb to v5 format
On first startup, the application now automatically detects legacy data from the previous Electron version (stored in \\~/.SwitchHosts/data\ and \config\) and migrates it to the new v5 storage structure. This process reads host entries, history, configuration, and trash items from the old JSON-based database, writes them into the new v5 file layout (including \manifest.json\ as a commit marker), and archives the original legacy directories into a timestamped folder under \v4/migration-\<timestamp\>/\ for safety. If no legacy data is found, the application proceeds as a fresh install.
src-tauri/src/migration · high confidence
Introduce Find & Replace, resizable sidebars, and tray mini-window UI
The main window now includes a Find & Replace page with a virtualized results list, support for single and bulk replacements, and resizable result columns. The layout adds resizable left and right sidebars that persist their widths, and the tray mini-window has been restyled with rounded corners on macOS and a polished appearance using Mantine components.
src/renderer/pages · high confidence
Introduce new common module with configuration, data models, and utility functions
This change adds a new \src/common\ directory containing foundational code for the application. It includes \default\_configs.ts\ which defines default settings such as write mode, theme, and proxy options; \data.d.ts\ and \types.d.ts\ which establish TypeScript interfaces for hosts data, tree structures, and UI elements; \hostsFn.ts\ and \normalize.ts\ which provide logic for managing hosts lists, including flattening, updating, and normalizing content with duplicate removal; \constants.ts\ for application URLs and ports; \events.ts\ for event names; \newlines.ts\ for line ending handling; \tree.ts\ for tree data utilities; and \update.ts\ for update-related types. It also adds \acknowledgements.ts\ listing contributors.
src/common · high confidence
Introduces a robust, filesystem-backed storage layer for v5
The application now uses a new Rust-based storage module to manage all local data, replacing previous ad-hoc file handling. This change introduces atomic file writes to prevent data corruption during crashes, enforces LF line-ending normalization for host entries to ensure consistent behavior across platforms, and implements a new system for custom data directories that allows users to store their SwitchHosts data in a user-selected folder. It also adds a recovery mechanism for when custom data directories become unavailable and establishes a structured layout for configuration, manifest, and state files.
src-tauri/src/storage · high confidence
Introduction of MainPanel component with HostsEditor and error handling
A new MainPanel component has been added to the renderer, serving as the primary container for the HostsEditor. It utilizes scoped SCSS for layout styling and integrates with the application's event system to monitor command execution results, specifically logging errors to the console when a custom command fails to execute successfully.
src/renderer/components/MainPanel · high confidence
Native application menu and find window with localized labels
The app now uses a native Rust implementation for the main application menu (File, Edit, View, Window, Help) and the Find/Replace window, replacing the previous Electron-based menu structure. Menu labels and the find window title are fully localized for supported languages (including Chinese, French, German, Japanese, Korean, Polish, and Turkish). The find window supports regex and case-insensitive search, persists the last 20 search/replace terms, and is lazily created to improve performance. Menu actions like Find, New, Preferences, and Quit are routed through Tauri events to the renderer, ensuring consistent behavior with the existing UI.
src-tauri/src · high confidence
New Left Sidebar with Hosts, Trash, Search, and History controls
A new LeftSidebar component has been introduced, providing a vertical navigation rail on the left side of the application. This sidebar allows users to toggle between the 'Hosts' list and the 'Trashcan' view, with a badge indicating the number of items in the trash. It also includes quick-access buttons for triggering the global search and viewing history, along with a settings menu. The component uses Jotai for state management to track the active view and integrates with the application's event system to toggle the panel's visibility.
src/renderer/components/LeftSidebar · high confidence
New Rust-based hosts apply pipeline with cross-platform elevation and post-apply hooks
The application now uses a new Rust module (\src-tauri/src/hosts\_apply\) to manage system hosts file updates. This change introduces platform-specific privilege escalation: macOS uses a silent privileged helper daemon (with fallback to OS prompts), Linux uses \pkexec\, and Windows uses UAC elevation. The pipeline aggregates selected hosts entries, deduplicates records, and supports an append mode that splices content under a specific marker. It also includes a history journal to track changes and a configurable \cmd\_after\_hosts\_apply\ runner that executes user scripts (with a 30-second timeout) after a successful write.
_src-tauri/src/hosts\apply · high confidence
New Tree component with multi-selection and drag-and-drop
A new Tree component has been added to the renderer, enabling users to select multiple nodes and reorder them via drag-and-drop. The component supports moving nodes before, after, or into other nodes, and allows dragging entire multi-selected groups as a single unit. It also includes visual indicators for drop positions and fixes a bug where toggling one folder's collapse state would incorrectly revert a sibling folder's state.
src/renderer/components/Tree · high confidence
New internationalization (i18n) module with multi-language support
A new i18n module has been introduced in src/common/i18n, providing a centralized system for managing application translations. The module exports a dictionary of supported languages, including English, Simplified and Traditional Chinese, French, German, Japanese, Turkish, Korean, and Polish. It exposes an I18N class that allows users to set a locale and access translated strings via a proxy-based lang object, supporting parameterized text replacement using placeholder indices (e.g., {0}, {1}). This enables the application to dynamically render content in the user's preferred language.
src/common/i18n · high confidence
New right-side panel for host details and system hosts metadata
A new right-side panel has been added to display detailed information about the currently selected hosts file. When a local or remote hosts file is selected, the panel shows the rule count, allows refreshing remote hosts, and provides options to edit, restore from trash, or permanently delete the entry. When 'System Hosts' is selected, the panel switches to a dedicated view that displays the hosts file path, type, and total rule count, along with a button to view the modification history. This component introduces a unified UI for managing hosts metadata and actions within the renderer.
src/renderer/components/RightPanel · high confidence
Resizable sidebar handles with drag interaction
A new ResizeHandle component has been added to enable users to resize left and right sidebars by dragging. The component provides a visual handle with hover and active states, enforces a minimum width, and manages pointer events to update sidebar dimensions in real-time during the drag operation.
src/renderer/components/ResizeHandle · high confidence
macOS privileged helper daemon for silent /etc/hosts writes
SwitchHosts now includes a privileged macOS helper daemon that allows the main app to silently write to /etc/hosts without requiring the user to enter their password. The helper communicates via XPC, enforcing strict code-signing requirements to ensure only the genuine SwitchHosts app can interact with it. It supports three operations: writing hosts content, checking the protocol version, and pinging the service. The implementation includes payload validation to prevent malformed or oversized data from being written and uses atomic file operations to ensure data integrity.
_src-tauri/src/helper\proto · high confidence
Behavioural changes
4 commits (0 fixes) modifying src-tauri/icons
A change to existing behaviour in src-tauri/icons — 4 commits, 9 files.
src-tauri/icons · medium confidence · unverified
About dialog rewritten with Mantine UI and modular styling
The About dialog component has been refactored to use Mantine UI components (Modal, ScrollArea, Stack) instead of the previous Chakra UI implementation. The component structure is now split into a main modal wrapper (index.tsx) and a content section (AboutContent.tsx), with styling moved to dedicated SCSS modules. This change updates the visual presentation of the About screen, including the logo, version display, links, and acknowledgements list, while maintaining the same functionality of opening via broadcast events.
src/renderer/components/About · high confidence
Alfred workflow for SwitchHosts now supports searching host lists
The Alfred workflow (version 1.3.0) has been updated to allow users to filter the list of available host configurations directly within the search query. When using the 'swh' keyword, the workflow now passes the user's input to the SwitchHosts API, displaying only the host sets that match the typed text, rather than showing the entire list unfiltered. The workflow also updates its homepage reference to the Vercel-hosted site.
alfred · high confidence
Dark and light themes now use Mantine color tokens
The dark and light theme styles in the renderer have been rewritten to derive their colors from Mantine's built-in palette (e.g., \--mantine-color-dark-\*\, \--mantine-primary-color-filled\) instead of hardcoded values. This ensures that the application's UI components, including the editor, tree view, and status bar, automatically align with the current Mantine theme configuration, providing a more consistent and maintainable visual experience.
src/renderer/styles/themes · high confidence
Hosts editor now uses CodeMirror 6 with syntax highlighting and comment toggling
The Hosts editor has been rebuilt on CodeMirror 6, replacing the previous implementation. This change introduces syntax highlighting for hosts files, visually distinguishing comments, IP addresses, and invalid lines. It also adds a gutter-click feature to toggle comments on individual lines, along with selection-based comment toggling that intelligently moves the cursor to the next line after editing. The editor respects read-only states and normalizes line endings for consistent behavior.
src/renderer/components/Editor · high confidence
Left panel now supports switching between host list and trashcan views
The LeftPanel component has been refactored to include a unified trashcan interface alongside the existing host list. Users can now toggle between the 'list' and 'trashcan' views within the left sidebar. The new Trashcan view displays deleted items in a tree structure, allowing users to restore individual items or permanently delete them via context menus, with a global 'Clear Trashcan' action available in the header. The layout uses Mantine's ScrollArea for content scrolling and integrates with Jotai state management to switch between the List and Trashcan components.
src/renderer/components/LeftPanel · high confidence
List component restructured with Mantine theming and improved context menu
The List component has been refactored to use Mantine UI components and SCSS modules, replacing the previous styling approach. This change introduces a 'Refresh' option in the context menu for remote hosts, improves the visual contrast of the edit button on selected rows, and fixes a bug where the hover highlight would get stuck after drag operations by switching from CSS :hover to JS-tracked hover states. Additionally, the component now properly synchronizes the tray list state after persistence and handles rollback of toggle states more reliably.
src/renderer/components/List · high confidence
Migrate configuration and theme models to Jotai with robust error handling
The models in src/renderer/models have been rewritten to use Jotai atoms for state management. The useConfigs hook now implements optimistic updates for configuration changes, automatically rolling back to the server snapshot and displaying a user-facing error notification if the backend update fails. Additionally, the useResolvedTheme hook now dynamically follows the operating system's theme preference when the user selects 'system', and the useI18n hook initializes the locale based on the system language at startup.
src/renderer/models · high confidence
Migrate renderer state management to Jotai
The application's state management in the renderer has been rewritten to use Jotai atoms, replacing the previous implementation. This change introduces new store modules for configuration, host data, internationalization, and UI state, ensuring that settings, host lists, locale preferences, and sidebar view toggles are now managed through a consistent atomic state model.
src/renderer/stores · high confidence
Migrate renderer to Mantine UI and Vite
The renderer has been rebuilt to use Mantine UI instead of Chakra UI and Vite instead of Umi.js. This introduces a new application entry point (index.html/index.tsx) that bootstraps the app with MantineProvider, defines a custom 'swhColor' primary palette, and applies global style overrides such as bold modal titles, right-aligned select check icons, and centered topbar titles. The change also updates the build tooling to Vite, replacing Less with Sass and removing the Umi.js dependency.
src/renderer · high confidence
Migration from wxPython desktop app to React web interface
The application has been completely rewritten from a Python/wxPython desktop program to a React-based web interface. The legacy entry point (SwitchHosts.py) and build script (setup.py) have been removed, and the new version is set to 5.0.1. This change introduces a modern UI architecture, replacing the previous native desktop experience with a web-based one.
src · high confidence
Migration to Tauri 2 with macOS privileged helper and automated updates
The desktop application has been upgraded to Tauri 2, introducing a new configuration schema and build process. This change enables silent host file updates on macOS by integrating a privileged helper service via the Security and ServiceManagement frameworks, configured through new entitlements and build scripts. Additionally, the app now supports automated updates via GitHub Releases, with the updater endpoint and public key defined in the new Tauri configuration. The version is now injected at build time from a central source, and the application bundle includes updated icons and DMG settings for macOS.
src-tauri · high confidence
New Tauri 2 frontend adapter and native context menu support
The renderer now communicates with the Rust backend via a new Tauri 2 agent, replacing the previous Electron IPC layer. This adapter standardizes command routing, wraps broadcast payloads to prevent argument ambiguity, and enables native context menus through Rust commands. Additionally, a new PopupMenu component and improved notification/error-handling utilities are included to support these backend interactions.
src/renderer/core · high confidence
New build and maintenance scripts for version sync, macOS universal builds, and language sorting
The scripts directory now includes four new files that change how the application is built and maintained. The sync-tauri-version.mjs script ensures package.json remains the single source of truth by automatically propagating version changes to src/version.json, tauri.conf.json, Cargo.toml, and Cargo.lock during npm versioning and Tauri builds. The bundle-universal-helper.mjs script fixes macOS universal-apple-darwin builds by manually lipo-ing the swh\_helper binary into the universal target directory, ensuring it is correctly bundled alongside the main app. The entitlements.mac.plist file adds necessary macOS entitlements for unsigned executable memory and JIT support. Finally, the sort-lang.mjs script provides a tool to automatically sort and organize language files in the i18n directory.
scripts · high confidence
New global styling system with disabled text selection and tray-specific transparency
The application now uses a new set of SCSS files in the renderer styles directory to manage global appearance. A key behavioral change is that text selection is globally disabled for the main window (html, body) to prevent accidental highlighting, but remains enabled for input fields, textareas, and contenteditable elements. Additionally, the styling explicitly handles the 'tray' mode by setting the background to transparent for tray pages, ensuring the mini-window corners appear correctly against the desktop. The system also introduces mixins for window drag regions and standardized scrollbar styling.
src/renderer/styles · high confidence
Preferences panel restructured with new data directory and command management features
The preferences interface has been rebuilt using Mantine components, introducing several new capabilities and behavioral changes. Users can now change the application's data storage directory via a new modal that supports copying existing data and warns against overwriting, with a recovery dialog to handle missing or invalid directories. A new Commands tab allows configuring post-apply shell scripts and viewing their execution history. The General tab now includes options for launch-at-login, hide-at-launch, and a macOS-specific privileged helper status for silent hosts writes. Proxy settings have been consolidated into a dedicated tab. Additionally, the UI now supports auto-saving drafts for the Commands and Proxy tabs, and language selection has been refined to better handle locale aliases and system language fallbacks.
src/renderer/components/Pref · high confidence
Redesigned top bar with import/export and configuration menu
The TopBar component has been rebuilt to include a new configuration menu (ConfigMenu) that provides access to application settings, update checks, feedback, and data management. Users can now export their hosts data to a file and import hosts either from a local file or directly from a URL via a new ImportFromUrl dialog. The top bar also displays the application brand logo and name on Windows and Linux, centers the current host title, and includes a read-only badge when applicable. Window control buttons are hidden when using the system window frame on Linux.
src/renderer/components/TopBar · high confidence
Renderer components migrated to Mantine and CodeMirror
The renderer components have been rebuilt using the Mantine UI library and CodeMirror, replacing the previous Chakra UI and native text views. This introduces a unified design system with Mantine components (such as Modal, Drawer, and ScrollArea) and a read-only CodeMirror editor for viewing hosts files and history snapshots. The migration also brings a new History drawer for browsing past hosts states, a dedicated UpdateDialog with scrollable release notes, and a custom SwitchButton that correctly prevents row selection when toggled.
src/renderer/components · high confidence
SwitchHosts v5: New data layout, Tauri 2 architecture, and modernized tooling
SwitchHosts v5 introduces a new data layout where configuration, hosts entries, and history are stored in the \\~/.SwitchHosts\ directory (with \manifest.json\, \entries/\, \trashcan.json\, and \internal/\ subfolders). The application is now built on Tauri 2 with a React frontend using Vite, Mantine, and Jotai. The project has also modernized its development tooling by replacing Less with Sass, adopting ESLint 10 with TypeScript ESLint, and adding Playwright for end-to-end testing.
(repo-wide) · high confidence
Updated application icon
The application icon has been replaced with a new design, featuring a red circular background with a white geometric pattern, available as a new SVG asset.
assets · high confidence
macOS privileged helper for silent hosts writes
macOS users can now update the system /etc/hosts file without encountering repeated administrator authorization prompts. A new privileged helper daemon (swh\_helper) and its LaunchDaemon configuration are installed to handle these writes silently in the background, while the main application communicates with it via a Mach service.
src-tauri/helper, src-tauri/src/bin · high confidence
Test coverage
Added end-to-end tests for core application features; Added structural integration tests for window lifecycle and data recovery; Added test coverage for hosts management and normalization logic; New e2e support infrastructure with Tauri mocking.
Dependencies
SwitchHosts 5.0.1 dependency baseline
The project dependencies have been updated to the 5.0.1 release baseline. The frontend stack now uses React 19, Mantine 9, Vite 8, and TypeScript 6, while the Rust backend (Tauri) is built on Tauri 2 with updated crates like reqwest 0.13 and axum 0.8.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 36 → 51 (+15.7)
- Rubric changed (rubric-2026.08.15 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 89 → 86 (-2.4)
- Architecture 98 (new)
- Maturity 59 → 59 (-0.2)
- Readiness 18 → 43 (+24.8)
- Security 39 → 67 (+28.2)
- Accessibility 48 (new)
Resolved (76)
- Change coupling: de.ts ↔ pl.ts (src/common/i18n/languages/de.ts)
- Change coupling: en.ts ↔ pl.ts (src/common/i18n/languages/en.ts)
- Change coupling: en.ts ↔ tr.ts (src/common/i18n/languages/en.ts)
- Change coupling: en.ts ↔ zh.ts (src/common/i18n/languages/en.ts)
- Change coupling: fr.ts ↔ pl.ts (src/common/i18n/languages/fr.ts)
- Change coupling: ja.ts ↔ pl.ts (src/common/i18n/languages/ja.ts)
- Change coupling: ko.ts ↔ pl.ts (src/common/i18n/languages/ko.ts)
- Change coupling: pl.ts ↔ zh-hant.ts (src/common/i18n/languages/pl.ts)
- Change coupling: pl.ts ↔ zh.ts (src/common/i18n/languages/pl.ts)
- Change coupling: tr.ts ↔ zh-hant.ts (src/common/i18n/languages/tr.ts)
- Dimension evaluation failed
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- …and 56 more
New (147)
- Boundary-crossing change coupling: hostsFn.ts ↔ index.tsx (src/common/hostsFn.ts)
- Change coupling: ListItem.tsx ↔ Node.tsx (src/renderer/components/List/ListItem.tsx)
- Change coupling: index.tsx ↔ Tree.tsx (src/renderer/components/List/index.tsx)
- Change-coupling hub: Trashcan.tsx → EditHostsInfo.tsx, ListItem.tsx, index.tsx (src/renderer/components/LeftPanel/Trashcan.tsx)
- ConfigMenu.ConfigMenu (cognitive 17) (src/renderer/components/TopBar/ConfigMenu.tsx)
- Coverage not measured — JavaScript/TypeScript suite
- Dependency hygiene PARTLY measured — Cargo dependencies read, dependency currency not (crates.io unreachable)
- Documentation: no project overview (README.md)
- Duplicated block (12 lines × 2) (src-tauri/src/http_api.rs)
- Duplicated block (19 lines × 2) (src-tauri/src/hosts_apply/cmd_runner.rs)
- Duplicated block (5 lines × 2) (src-tauri/src/commands.rs)
- Duplicated block (5 lines × 2) (src-tauri/src/find.rs)
- Duplicated block (5 lines × 2) (src-tauri/src/migration/archiver.rs)
- Duplicated block (5 lines × 2) (src-tauri/src/storage/data_dir_pointer.rs)
- Duplicated block (5 lines × 2) (src-tauri/src/storage/tree_format.rs)
- Duplicated block (5 lines × 4) (src-tauri/src/find.rs)
- Duplicated block (6 lines × 2) (src-tauri/src/commands.rs)
- Duplicated block (6 lines × 3) (src-tauri/src/lifecycle.rs)
- Duplicated block (7 lines × 2) (src-tauri/src/commands.rs)
- Duplicated block (7 lines × 2) (src-tauri/src/find.rs)
- …and 127 more
Changes since last survey
- 8 commits — 7 feature/other, 1 fixes
By area
- (repo) — 4 commits
- (root) — 2 commits
- src/common — 2 commits
Notable commits
- fix: fix(i18n): polish Traditional Chinese UI copy
- change: Add Chen, Ting-An to acknowledgements
- change: Merge pull request #1034 from oldj/dependabot/npm_and_yarn/undici-7.29.0
- change: Merge pull request #1036 from nrps9909/codex/polish-zhtw-ui-copy
- change: Merge pull request #1042 from oldj/dependabot/npm_and_yarn/browserslist-4.28.8
- change: Merge pull request #1047 from oldj/dependabot/npm_and_yarn/multi-d0c2d048a7
- change: chore(deps): bump @vitest/mocker and vitest
- change: chore(deps-dev): bump browserslist from 4.28.2 to 4.28.8
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
oldj/SwitchHosts was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 27 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 2d0de557f1e681a561473befd65252de55486b88 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-7c1cb6328e11.