lobehub/apps/desktop
Innei 687b36c81c
♻️ refactor: migrate frontend from Next.js App Router to Vite SPA (#12404)
* init plan

* 📝 docs: update SPA plan for dev mode Worker cross-origin handling

- Clarified the handling of Worker cross-origin issues in dev mode, emphasizing the need for `workerPatch` to wrap cross-origin URLs as blob URLs.
- Enhanced the explanation of the dev mode's resource URL rewriting process for better understanding.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: Phase 1 - 环境变量整治

- Fix Pyodide env var mismatch (NEXT_PUBLIC_PYPI_INDEX_URL → pythonEnv.NEXT_PUBLIC_PYODIDE_PIP_INDEX_URL)
- Consolidate python.ts to use pythonEnv instead of direct process.env
- Remove NEXT_PUBLIC_ prefix from server-side MARKET_BASE_URL (5 files)

* 🏗️ chore: Phase 2 - Vite 工程搭建

- Add vite.config.ts with dual build (desktop/mobile via MOBILE env)
- Add index.html SPA template with __SERVER_CONFIG__ placeholder
- Add entry.desktop.tsx and entry.mobile.tsx SPA entry points
- Add dev:spa, dev:spa:mobile, build:spa, build:spa:copy scripts
- Install @vitejs/plugin-react and linkedom

* ♻️ refactor: Phase 3 - 第一方包 Next.js 解耦

- Replace next/link with <a> in builtin-tool-web-browsing (4 files, external links)
- Replace next/image with <img> in builtin-tool-agent-builder/InstallPlugin.tsx
- Add Vite import.meta.env compat for isDesktop in const/version.ts, builtin-tool-gtd, builtin-tool-group-management

* ♻️ refactor: Phase 4a - Auth 页面改用直接 next/navigation 和 next/link

- 9 auth files: @/libs/next/navigation → next/navigation
- 5 auth files: @/libs/next/Link → next/link
- Auth pages remain in Next.js App Router, need direct Next.js imports

* ♻️ refactor: Phase 4b - Next.js 抽象层替换为 react-router-dom/vanilla React

- navigation.ts: useRouter/usePathname/useSearchParams/useParams → react-router-dom
- navigation.ts: redirect/notFound → custom error throws
- navigation.ts: useServerInsertedHTML → no-op for SPA
- Link.tsx: next/link → react-router-dom Link adapter (href→to, external→<a>)
- Image.tsx: next/image → <img> wrapper with fill/style support
- dynamic.tsx: next/dynamic → React.lazy + Suspense wrapper

*  feat: Phase 5 - 新建 SPAGlobalProvider

- Create SPAServerConfig type (analyticsConfig, clientEnv, theme, featureFlags, locale)
- Add window.__SERVER_CONFIG__ and __MOBILE__ to global.d.ts
- Create SPAGlobalProvider (client-only Provider tree mirroring GlobalProvider)
- Includes AuthProvider for user session support
- Update entry.desktop.tsx and entry.mobile.tsx to wrap with SPAGlobalProvider

* ♻️ refactor: add SPA catch-all route handler with Vite dev proxy

- Create (spa)/[[...path]]/route.ts for serving SPA HTML
- Dev mode: proxy Vite dev server, rewrite asset URLs, inject Worker patch
- Prod mode: read pre-built HTML templates
- Build SPAServerConfig with analytics, theme, clientEnv, featureFlags
- Update middleware to pass SPA routes through to catch-all

* ♻️ refactor: skip auth checks for SPA routes in middleware

SPA pages are all public (no sensitive data in HTML).
Auth is handled client-side by SPAGlobalProvider's AuthProvider.
Only Next.js auth routes and API endpoints go through session checks.

* ♻️ refactor: replace Next.js-specific analytics with vanilla JS

- Google.tsx: replace @next/third-parties/google with direct gtag script
- ReactScan.tsx: replace react-scan/monitoring/next with generic script
- Desktop.tsx: replace next/script with native script injection

* ♻️ refactor: migrate @t3-oss/env-nextjs to @t3-oss/env-core

Replace framework-specific env validation with framework-agnostic version.
Add clientPrefix where client schemas exist.

* ♻️ refactor: replace next-mdx-remote/rsc with react-markdown

Use client-side react-markdown for MDX rendering instead of
Next.js RSC-dependent next-mdx-remote.

* 🔧 chore: update build scripts and Dockerfile for SPA integration

- build:docker now includes SPA build + copy steps
- dev defaults to Vite SPA, dev:next for Next.js backend
- Dockerfile copies public/spa/ assets for production
- Add public/spa/ to .gitignore (build artifact)

* 🗑️ chore: remove old Next.js route segment files and serwist PWA

- Delete [variants] page.tsx, error.tsx, not-found.tsx, loading.tsx
- Delete root loading.tsx and empty [[...path]] directory
- Delete unused loaders directory
- Remove @serwist/next PWA wrapper from Next.js config

* plan2

*  feat: add locale detection script to index.html for SPA dev mode

* ♻️ refactor: remove locale and theme from SPAServerConfig

*  feat: add [locale] segment with force-static and SEO meta generation

* ♻️ refactor: remove theme/locale reads from SPAGlobalProvider

*  feat: set vite base to /spa/ for production builds

*  feat: auto-generate spaHtmlTemplates from vite build output

* 🔧 chore: register dev:next task in turbo.json for parallel dev startup

* ♻️ refactor: rename (spa) route group to spa segment, rewrite SPA routes via middleware

*  feat: add Vite-compatible i18n/locale modules with import.meta.glob and resolve aliases

* 🔧 fix: use custom Vite plugin for module redirects instead of resolve.alias

* very important

* build

* 🔧 chore: update build scripts and clean up Vite configuration by removing unused plugin and code

Signed-off-by: Innei <tukon479@gmail.com>

* 🗑️ refactor: remove all electron modifier scripts

Modifiers are no longer needed with Vite SPA renderer build.

*  feat: add Vite renderer entry to electron-vite config

Add renderer build configuration to electron-vite, replacing the old
Next.js shadow workspace build flow. Delete buildNextApp.mts and
moveNextExports.ts, update package.json scripts accordingly.

*  feat: add .desktop suffix files for eager i18n loading

Create 4 .desktop files that use import.meta.glob({ eager: true })
for synchronous locale access in Electron desktop builds, replacing
the async lazy-loading used in web SPA builds.

* 🔧 refactor: adapt Electron main process for Vite renderer

Replace nextExportDir with rendererDir, update protocol from
app://next to app://renderer, simplify file resolution to SPA
fallback pattern, update _next/ asset paths to /assets/.

* 🔧 chore: update electron-builder files config for Vite renderer

Replace dist/next references with dist/renderer, remove Next.js
specific exclusion rules no longer applicable to Vite output.

* 🗑️ chore: remove @ast-grep/napi dependency

No longer needed after removing electron modifier scripts.

* 🔧 refactor: unify isDesktop to __ELECTRON__ compile-time constant

Remove NEXT_PUBLIC_IS_DESKTOP_APP and VITE_IS_DESKTOP_APP env vars.
Unify isDesktop in @lobechat/const using __ELECTRON__ defined by Vite.
Re-export from builtin-tool packages. Scripts use DESKTOP_BUILD.

* update

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: use electron-vite ELECTRON_RENDERER_URL instead of hardcoded port 3015

Replace hardcoded http://localhost:3015 with process.env.ELECTRON_RENDERER_URL
injected by electron-vite dev server. Clean up stale Next.js references.

* 🐛 fix: use local renderer-entry shim to resolve Vite root path issue

HTML entry ../../src/entry.desktop.tsx resolves to /src/entry.desktop.tsx
in URL space, which Vite cannot find within apps/desktop/ root. Add a
local shim that imports across root via module resolver instead.

* 🔧 refactor: extract shared renderer Vite config into sharedRendererConfig

Deduplicate plugins (nodeModuleStub, platformResolve, tsconfigPaths) and
define (__MOBILE__, __ELECTRON__, process.env) between root vite.config.ts
and electron.vite.config.ts renderer section.

* 🔧 refactor: move all renderer plugins and optimizeDeps into shared config

sharedRendererPlugins now includes react, codeInspectorPlugin alongside
nodeModuleStub, platformResolve, tsconfigPaths. Add sharedOptimizeDeps
for pre-bundling list. Both root and electron configs consume shared only.

* 🐛 fix: set electron renderer root to monorepo root for correct glob resolution

import.meta.glob with absolute paths (e.g. /node_modules/antd/...) resolved
within apps/desktop/ instead of monorepo root. Change renderer root to ROOT_DIR,
add electronDesktopHtmlPlugin middleware to rewrite / to /apps/desktop/index.html,
and remove the now-unnecessary renderer-entry.ts shim.

* desktop vite !!

Signed-off-by: Innei <tukon479@gmail.com>

* sync import !!

Signed-off-by: Innei <tukon479@gmail.com>

* clean ci!!

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: update SPA path structure and clean up dependencies

- Changed the path in .gitignore and related files from [locale] to [variants] for SPA templates.
- Updated index.html to set body height to 100%.
- Cleaned up package.json by removing unused dependencies and reorganizing devDependencies.
- Refactored RendererUrlManager to use a constant for SPA entry HTML path.
- Removed obsolete route.ts file from the SPA structure.
- Adjusted proxy configuration to reflect the new SPA path structure.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: update build script to include mobile SPA build

- Modified the build script in package.json to add the mobile SPA build step.
- Ensured the build process accommodates both desktop and mobile SPA versions.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: update build scripts and improve file encoding consistency

- Modified the build script in package.json to ensure the SPA copy step runs after the build.
- Updated file encoding in generateSpaTemplates.mts from 'utf-8' to 'utf8' for consistency.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 fix: correct Blob import syntax and update global server config type

- Fixed the Blob import syntax in route.ts to ensure proper module loading.
- Updated the global server configuration type in global.d.ts for improved type safety.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 test: update RendererUrlManager test to reflect new file path

- Modified the mock implementation in RendererUrlManager.test.ts to check for the updated file path '/mock/export/out/apps/desktop/index.html'.
- Adjusted the expected resolved path in the test to match the new structure.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: remove catch-all example file and update imports

- Deleted the catch-all example file `catch-all.eg.ts` to streamline the codebase.
- Updated import paths in `ClientResponsiveLayout.tsx` and `ClientResponsiveContent/index.tsx` to use the new dynamic import location.
- Added type declarations for HTML templates in `spaHtmlTemplates.d.ts`.
- Adjusted `tsconfig.json` to include the updated file structure.
- Enhanced type definitions in `global.d.ts` and fixed locale loading in `locale.vite.ts`.

Signed-off-by: Innei <tukon479@gmail.com>

* e2e

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: remove unused build script for Vercel deployment

- Deleted the `build:vercel` script from package.json to streamline the build process.
- Ensured the remaining build scripts are organized and relevant.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 config: update Vite build input for mobile support

- Changed the build input path in vite.config.ts to conditionally use 'index.mobile.html' for mobile builds, enhancing support for mobile SPA versions.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 feat: add compatibility checks for import maps and cascade layers

- Implemented functions to check for browser support of import maps and CSS cascade layers.
- Redirected users to a compatibility page if their browser does not support the required features.
- Updated the build script in package.json to use the experimental analyze command for better performance.

Signed-off-by: Innei <tukon479@gmail.com>

* chore: rename

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 feat: refactor authentication layout and introduce global providers

- Created a new `RootLayout` component to streamline the layout structure.
- Removed the old layout file for variants and integrated necessary features into the new layout.
- Added `AuthGlobalProvider` to manage authentication context and server configurations.
- Introduced language and theme selection components for enhanced user experience.
- Updated various components to utilize the new context and improve modularity.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 config: exclude build artifacts from serverless functions

- Updated the `next.config.ts` to exclude SPA, desktop, and mobile build artifacts from serverless functions.
- Added paths for `public/spa/**`, `dist/**`, `apps/desktop/build/**`, and `packages/database/migrations/**` to the exclusion list.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 config: refine exclusion of build artifacts from serverless functions

- Updated `next.config.ts` to specify exclusion paths for desktop and mobile build artifacts.
- Changed exclusions from `dist/**` and `apps/desktop/build/**` to `dist/desktop/**`, `dist/mobile/**`, and `apps/desktop/**` for better clarity and organization.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 fix: update BrowserRouter basename for local development

- Modified the `ClientRouter` component to conditionally set the `basename` of `BrowserRouter` based on the `__DEBUG_PROXY__` variable, improving local development experience.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 feat: implement mobile SPA workflow and S3 asset management

- Added a new workflow for building and uploading mobile SPA assets to S3, including environment variable configurations in `.env.example`.
- Updated `package.json` to include a new script for the mobile SPA workflow.
- Enhanced the Vite configuration to support dynamic CDN base paths.
- Refactored the template generation script to handle mobile HTML templates more effectively.
- Introduced new modules for uploading assets to S3 and generating mobile HTML templates.

Signed-off-by: Innei <tukon479@gmail.com>

* 🐛 fix: extract origin from MOBILE_S3_PUBLIC_DOMAIN to prevent double key prefix

* 🔧 fix: update mobile HTML template to use the latest asset versions

- Modified the mobile HTML template to reference the updated JavaScript asset version for improved functionality.
- Ensured consistency in the template structure while maintaining existing styles and scripts.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: update dependencies and refine service worker integration

- Removed outdated dependencies related to Serwist from package.json and tsconfig.json.
- Added vite-plugin-pwa to enhance PWA capabilities in the Vite configuration.
- Updated service worker registration logic in the PWA installation component.
- Introduced a new local development proxy route for debugging purposes.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: refactor development scripts and remove Turbo configuration

- Updated the `dev` script in `package.json` to use a new startup sequence script for improved development workflow.
- Removed the outdated `turbo.json` configuration file as it is no longer needed.
- Introduced `devStartupSequence.mts` to manage the startup of Next.js and Vite processes concurrently.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 feat: update entry points and introduce debug proxy for local development

- Changed the main entry point in `index.html` from `entry.desktop.tsx` to `entry.web.tsx` for improved web compatibility.
- Added an `initialize.ts` file to enable `immer`'s `enableMapSet` functionality.
- Introduced a new `__DEBUG_PROXY__` variable in global types to support local development proxy features.
- Implemented a debug proxy route to facilitate local development with dynamic HTML injection and script handling.
- Removed outdated mobile routing components to streamline the codebase.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: replace BrowserRouter with RouterProvider for improved routing

- Updated entry points for desktop, mobile, and web to utilize RouterProvider and createAppRouter for better routing management.
- Removed the deprecated renderRoutes function in favor of a more streamlined router configuration.
- Enhanced router setup to support error boundaries and dynamic routing.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: remove direct access handling for SPA routes in proxy configuration

- Eliminated the handling of direct access to pre-rendered SPA pages in the proxy configuration.
- Simplified the request processing logic by removing checks for SPA routes, streamlining the middleware response flow.

Signed-off-by: Innei <tukon479@gmail.com>

* update

* 🔧 refactor: enhance Worker instantiation logic in mobile HTML template

* 🐛 fix: remove duplicate waitForPageWorkspaceReady calls in page CRUD e2e steps

* 🔧 refactor: simplify createTracePayload function by using btoa for base64 encoding

* 🔧 refactor: specify locales in import.meta.glob for dayjs and antd

* 🔧 refactor: replace Node.js Buffer with web-compatible btoa for base64 encoding in file upload

* 🐛 fix: disable consistent-type-imports rule for mdx files to prevent eslint crash

* 🔧 refactor: add height style to root div for consistent layout

* 🔧 refactor: replace btoa with Buffer for base64 encoding in trace and file upload handling

* 🔧 refactor: extract nextjsOnlyRoutes to a separate file for better organization

* 🔧 refactor: enable Immer MapSet plugin in tests for better state management

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: integrate sharedRollupOutput configuration and increase cache size for better performance

Signed-off-by: Innei <tukon479@gmail.com>

* 🗑️ chore: remove obsolete desktop.routes.test.ts file as it is no longer needed

Signed-off-by: Innei <tukon479@gmail.com>

* 🐛 fix: use cross-env for env vars in npm scripts (Windows CI)

Co-authored-by: Cursor <cursoragent@cursor.com>

* 🔧 chore: update Dockerfile for web-only build and adjust npm scripts to use pnpm

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: enhance Dockerfile prebuild process with environment checks and add new dependencies

- Updated Dockerfile to include environment checks before removing desktop-only code.
- Added new dependencies in package.json: @aws-sdk/client-bedrock-runtime, @opentelemetry/auto-instrumentations-node, @opentelemetry/resources, @opentelemetry/sdk-metrics, and ajv.
- Configured Rollup to exclude @aws-sdk/client-bedrock-runtime from the SPA bundle.
- Introduced dockerPrebuild.mts script for environment variable validation and information logging.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: enhance Vite and Electron configurations with environment loading and trace encoding improvements

- Updated Vite and Electron configurations to load environment variables using loadEnv.
- Modified trace encoding in utils to use TextEncoder for better compatibility.
- Adjusted sharedRendererConfig to expose only necessary public environment variables.

Signed-off-by: Innei <tukon479@gmail.com>

* 🗑️ chore: remove plans directory (migrated to discussion)

* ♻️ refactor: inject NEXT_PUBLIC_* env per key in Vite define

Co-authored-by: Cursor <cursoragent@cursor.com>

*  feat: add loading screen with animation to enhance user experience

- Introduced a loading screen with a brand logo and animations for better visual feedback during loading times.
- Implemented CSS styles for the loading screen and animations in index.html.
- Removed the loading screen from the DOM once the layout is ready using useLayoutEffect in SPAGlobalProvider.

Signed-off-by: Innei <tukon479@gmail.com>

* 🗑️ chore: remove unnecessary external dependency from Vite configuration

- Eliminated the external dependency '@aws-sdk/client-bedrock-runtime' from the Vite configuration to streamline the build process for the SPA bundle.

Signed-off-by: Innei <tukon479@gmail.com>

*  feat: add web app manifest link in index.html and enable PWA support in Vite configuration

- Added a link to the web app manifest in index.html to enhance PWA capabilities.
- Enabled manifest support in Vite configuration for improved service worker functionality.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: update link rel attributes for improved SEO and consistency

- Modified link rel attributes in multiple components to remove 'noreferrer' and standardize to 'nofollow'.
- Adjusted imports in PageContent components for better organization.

Signed-off-by: Innei <tukon479@gmail.com>

* update provider

*  feat: enhance loading experience and update package dependencies

- Added a loading screen with animations and a brand logo in index.html for improved user feedback during loading times.
- Introduced CSS styles for the loading screen and animations.
- Updated package.json files across multiple packages to include "@lobechat/const" as a dependency.

Signed-off-by: Innei <tukon479@gmail.com>

* fix: update proxy

Signed-off-by: Innei <tukon479@gmail.com>

* 🗑️ chore: remove GlobalLayout and Locale components

- Deleted GlobalLayout and Locale components from the GlobalProvider directory to streamline the codebase.
- This removal is part of a refactor to simplify the layout structure and improve maintainability.

Signed-off-by: Innei <tukon479@gmail.com>

* chore: clean up console logs and improve component structure

- Removed unnecessary console log statements from AgentForkTag components in both agent and community directories to enhance code cleanliness.
- Refactored UserAgentList component for better readability by restructuring the useUserDetailContext hook and adjusting the layout of Flexbox components.

Signed-off-by: Innei <tukon479@gmail.com>

* chore: remove console log from MemoryAnalysis component

* chore: update mobile HTML template with new asset links

- Replaced the previous asset links in the mobile HTML template with updated versions to ensure the latest resources are utilized.
- Adjusted the link rel attributes for module preloading to enhance performance and loading efficiency.

Signed-off-by: Innei <tukon479@gmail.com>

* fix: correct variable assignment in createClientTaskThread integration test

- Updated the assignment of the second parent message in the createClientTaskThread integration test to improve clarity and ensure proper data handling.
- Changed the variable name from 'secondParentMsg' to 'inserted' for better context before extracting the first message from the inserted results.

Signed-off-by: Innei <tukon479@gmail.com>

* refactor: simplify authentication check in define-config

- Removed the dependency on the isDesktop variable in the authentication check to streamline the logic.
- Enhanced the clarity of the redirection process for protected routes by focusing solely on the isLoggedIn status.

Signed-off-by: Innei <tukon479@gmail.com>

*  feat(dev): enhance local development setup with debug proxy instructions

- Added detailed instructions for starting the development environment in CLAUDE.md, including commands for SPA and full-stack modes.
- Updated README.md and README.zh-CN.md to reflect new commands and the debug proxy URL for local development.
- Introduced a Vite plugin to print the debug proxy URL upon server start, facilitating easier local development against the production backend.
- Corrected the debug proxy route in entry.web.tsx and define-config.ts for consistency.

This improves the developer experience by providing clear guidance and tools for local development.

Signed-off-by: Innei <tukon479@gmail.com>

* optimize perf

* optimize perf

* optimize perf

* remove speedy plugin

* add dayjs vendor

* Revert "remove speedy plugin"

This reverts commit bf986afeb1.

---------

Signed-off-by: Innei <tukon479@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-28 00:01:01 +08:00
..
build feat: rebrand stable app icon 2026-02-11 12:58:44 +08:00
resources feat(desktop): configure DMG background image (#12284) 2026-02-13 01:06:43 +08:00
scripts 🔧 chore: update eslint v2 configuration and suppressions (#12133) 2026-02-11 13:04:48 +08:00
src ♻️ refactor: migrate frontend from Next.js App Router to Vite SPA (#12404) 2026-02-28 00:01:01 +08:00
.gitignore feat: support desktop release framework and workflow (#6474) 2025-04-27 11:57:06 +08:00
.i18nrc.js 🐛 fix(desktop): add auth required modal and improve error handling (#11574) 2026-01-18 18:55:18 +08:00
.npmrc feat: remove Clerk authentication code (#11711) 2026-01-23 14:41:22 +08:00
.prettierignore feat: refactor desktop implement with brand new 2.0 2025-12-24 12:54:35 +08:00
.remarkrc.mjs 🔧 chore: update eslint v2 configuration and suppressions (#12133) 2026-02-11 13:04:48 +08:00
.stylelintignore feat: refactor desktop implement with brand new 2.0 2025-12-24 12:54:35 +08:00
dev-app-update.yml feat(desktop): add local update testing scripts and stable channel API version check (#11474) 2026-01-15 17:26:19 +08:00
Development.md 🔧 chore: update eslint v2 configuration and suppressions (#12133) 2026-02-11 13:04:48 +08:00
electron-builder.mjs ♻️ refactor: migrate frontend from Next.js App Router to Vite SPA (#12404) 2026-02-28 00:01:01 +08:00
electron.vite.config.ts ♻️ refactor: migrate frontend from Next.js App Router to Vite SPA (#12404) 2026-02-28 00:01:01 +08:00
index.html ♻️ refactor: migrate frontend from Next.js App Router to Vite SPA (#12404) 2026-02-28 00:01:01 +08:00
native-deps.config.mjs feat(desktop): integrate electron-liquid-glass for macOS Tahoe (#12277) 2026-02-14 00:31:16 +08:00
package.json ♻️ refactor: migrate frontend from Next.js App Router to Vite SPA (#12404) 2026-02-28 00:01:01 +08:00
pnpm-workspace.yaml feat: refactor desktop implement with brand new 2.0 2025-12-24 12:54:35 +08:00
prettier.config.mjs 🔧 chore: update eslint v2 configuration and suppressions (#12133) 2026-02-11 13:04:48 +08:00
README.md ♻️ refactor: restructure electron build workflow with i18n codemod 2026-02-11 12:58:42 +08:00
README.zh-CN.md ♻️ refactor: restructure electron build workflow with i18n codemod 2026-02-11 12:58:42 +08:00
stylelint.config.mjs 🔧 chore: update eslint v2 configuration and suppressions (#12133) 2026-02-11 13:04:48 +08:00
tsconfig.json feat(electron): enhance native module handling and improve desktop features (#11867) 2026-01-27 01:30:08 +08:00
vitest.config.mts 🔧 chore(desktop): exclude node_modules from electron-builder packaging (#11397) 2026-01-10 23:15:42 +08:00

🤯 LobeHub Desktop Application

LobeHub Desktop is a cross-platform desktop application for LobeChat, built with Electron, providing a more native desktop experience and functionality.

Features

  • 🌍 Cross-platform Support: Supports macOS (Intel/Apple Silicon), Windows, and Linux systems
  • 🔄 Auto Updates: Built-in update mechanism ensures you always have the latest version
  • 🌐 Multi-language Support: Complete i18n support for 18+ languages with lazy loading
  • 🎨 Native Integration: Deep OS integration with native menus, shortcuts, and notifications
  • 🔒 Secure & Reliable: macOS notarized, encrypted token storage, secure OAuth flow
  • 📦 Multiple Release Channels: Stable, beta, and nightly build versions
  • Advanced Window Management: Multi-window architecture with theme synchronization
  • 🔗 Remote Server Sync: Secure data synchronization with remote LobeChat instances
  • 🎯 Developer Tools: Built-in development panel and comprehensive debugging tools

🚀 Development Setup

Prerequisites

  • Node.js 22+
  • pnpm 10+
  • Electron compatible development environment

Quick Start

# Install dependencies
pnpm install-isolated

# Start development server
pnpm dev

# Type checking
pnpm type-check

# Run tests
pnpm test

Environment Configuration

Copy .env.desktop to .env and configure as needed:

cp .env.desktop .env

[!WARNING] Backup your .env file before making changes to avoid losing configurations.

Build Commands

Command Description
pnpm build:main Build main/preload (dist output only)
pnpm package:mac Package for macOS (Intel + Apple Silicon)
pnpm package:win Package for Windows
pnpm package:linux Package for Linux
pnpm package:local Local packaging build (no ASAR)
pnpm package:local:reuse Local packaging build reusing existing dist

Development Workflow

# 1. Development
pnpm dev # Start with hot reload

# 2. Code Quality
pnpm lint       # ESLint checking
pnpm format     # Prettier formatting
pnpm type-check # TypeScript validation

# 3. Testing
pnpm test # Run Vitest tests

# 4. Build & Package
pnpm build:main    # Production build (dist only)
pnpm package:local # Local testing package

🎯 Release Channels

Channel Description Stability Auto-Updates
Stable Thoroughly tested releases 🟢 High Yes
Beta Pre-release with new features 🟡 Medium Yes
Nightly Daily builds with latest changes 🟠 Low Yes

🛠 Technology Stack

Core Framework

  • Electron 37.1.0 - Cross-platform desktop framework
  • Node.js 22+ - Backend runtime
  • TypeScript 5.7+ - Type-safe development
  • Vite 6.2+ - Build tooling

Architecture & Patterns

  • Dependency Injection - IoC container with decorator-based registration
  • Event-Driven Architecture - IPC communication between processes
  • Module Federation - Dynamic controller and service loading
  • Observer Pattern - State management and UI synchronization

Development Tools

  • Vitest - Unit testing framework
  • ESLint - Code linting
  • Prettier - Code formatting
  • electron-builder - Application packaging
  • electron-updater - Auto-update mechanism

Security & Storage

  • Electron Safe Storage - Encrypted token storage
  • OAuth 2.0 + PKCE - Secure authentication flow
  • electron-store - Persistent configuration
  • Custom Protocol Handler - Secure callback handling

🏗 Architecture

The desktop application uses a sophisticated dependency injection and event-driven architecture:

📁 Core Structure

src/main/core/
├── App.ts                    # 🎯 Main application orchestrator
├── IoCContainer.ts           # 🔌 Dependency injection container
├── window/                   # 🪟 Window management modules
│   ├── WindowThemeManager.ts     # 🎨 Theme synchronization
│   ├── WindowPositionManager.ts  # 📐 Position persistence
│   ├── WindowErrorHandler.ts     # ⚠️  Error boundaries
│   └── WindowConfigBuilder.ts    # ⚙️  Configuration builder
├── browser/                  # 🌐 Browser management modules
│   ├── Browser.ts               # 🪟 Individual window instances
│   └── BrowserManager.ts        # 👥 Multi-window coordinator
├── ui/                       # 🎨 UI system modules
│   ├── Tray.ts                  # 📍 System tray integration
│   ├── TrayManager.ts           # 🔧 Tray management
│   ├── MenuManager.ts           # 📋 Native menu system
│   └── ShortcutManager.ts       # ⌨️  Global shortcuts
└── infrastructure/           # 🔧 Infrastructure services
    ├── StoreManager.ts          # 💾 Configuration storage
    ├── I18nManager.ts           # 🌍 Internationalization
    ├── UpdaterManager.ts        # 📦 Auto-update system
    └── StaticFileServerManager.ts # 🗂️ Local file serving

🔄 Application Lifecycle

The App.ts class orchestrates the entire application lifecycle through key phases:

1. 🚀 Initialization Phase

  • System Information Logging - Captures OS, CPU, RAM, and locale details
  • Store Manager Setup - Initializes persistent configuration storage
  • Dynamic Module Loading - Auto-discovers controllers and services via glob imports
  • IPC Event Registration - Sets up inter-process communication channels

2. 🏃 Bootstrap Phase

  • Single Instance Check - Ensures only one application instance runs
  • IPC Server Launch - Starts the communication server
  • Core Manager Initialization - Sequential initialization of all managers:
    • 🌍 I18n for internationalization
    • 📋 Menu system for native menus
    • 🗂️ Static file server for local assets
    • ⌨️ Global shortcuts registration
    • 🪟 Browser window management
    • 📍 System tray (Windows only)
    • 📦 Auto-updater system

🔧 Core Components Deep Dive

🌐 Browser Management System

  • Multi-Window Architecture - Supports chat, settings, and devtools windows
  • Window State Management - Handles positioning, theming, and lifecycle
  • WebContents Mapping - Bidirectional mapping between WebContents and identifiers
  • Event Broadcasting - Centralized event distribution to all or specific windows

🔌 Dependency Injection & Event System

  • IoC Container - WeakMap-based container for decorated controller methods
  • Typed IPC Decorators - @IpcMethod wires controller methods into type-safe channels
  • Automatic Event Mapping - Events registered during controller loading
  • Service Locator - Type-safe service and controller retrieval
🧠 Type-Safe IPC Flow
  • Async Context Propagation - src/main/utils/ipc/base.ts captures the IpcContext with AsyncLocalStorage, so controller logic can call getIpcContext() anywhere inside an IPC handler without explicitly threading arguments.
  • Service Constructors Registry - src/main/controllers/registry.ts exports controllerIpcConstructors and DesktopIpcServices, enabling automatic typing of renderer IPC proxies.
  • Renderer Proxy Helper - src/utils/electron/ipc.ts exposes ensureElectronIpc() which lazily builds a proxy on top of window.electronAPI.invoke, giving React/Next.js code a type-safe API surface without exposing raw proxies in preload.
  • Shared Typings Package - apps/desktop/src/main/exports.d.ts augments @lobechat/electron-client-ipc so every package can consume DesktopIpcServices without importing desktop business code directly.

🪟 Window Management

  • Theme-Aware Windows - Automatic adaptation to system dark/light mode
  • Platform-Specific Styling - Windows title bar and overlay customization
  • Position Persistence - Save and restore window positions across sessions
  • Error Boundaries - Centralized error handling for window operations

🔧 Infrastructure Services

🌍 I18n Manager
  • 18+ Language Support with lazy loading and namespace organization
  • System Integration with Electron's locale detection
  • Dynamic UI Refresh on language changes
  • Resource Management with efficient loading strategies
📦 Update Manager
  • Multi-Channel Support (stable, beta, nightly) with configurable intervals
  • Background Downloads with progress tracking and user notifications
  • Rollback Protection with error handling and recovery mechanisms
  • Channel Management with automatic channel switching
💾 Store Manager
  • Type-Safe Storage using electron-store with TypeScript interfaces
  • Encrypted Secrets via Electron's Safe Storage API
  • Configuration Validation with default value management
  • File System Integration with automatic directory creation
🗂️ Static File Server
  • Local HTTP Server for serving application assets and user files
  • Security Controls with request filtering and access validation
  • File Management with upload, download, and deletion capabilities
  • Path Resolution with intelligent routing between storage locations

🎨 UI System Integration

  • Global Shortcuts - Platform-aware keyboard shortcut registration with conflict detection
  • System Tray - Native integration with context menus and notifications
  • Native Menus - Platform-specific application and context menus with i18n
  • Theme Synchronization - Automatic theme updates across all UI components

🏛 Controller & Service Architecture

🎮 Controller Pattern

  • Typed IPC Decorators - Controllers extend ControllerModule and expose renderer methods via @IpcMethod
  • IPC Event Handling - Processes events from renderer with decorator-based registration
  • Lifecycle Hooks - beforeAppReady and afterAppReady for initialization phases
  • Type-Safe Communication - Strong typing for all IPC events and responses
  • Error Boundaries - Comprehensive error handling with proper propagation

🔧 Service Pattern

  • Business Logic Encapsulation - Clean separation of concerns
  • Dependency Management - Managed through IoC container
  • Cross-Controller Sharing - Services accessible via service locator pattern
  • Resource Management - Proper initialization and cleanup

🔗 Inter-Process Communication

📡 IPC System Features

  • Bidirectional Communication - Main↔Renderer and Main↔Next.js server
  • Type-Safe Events - TypeScript interfaces for all event parameters
  • Context Awareness - Events include sender context for window-specific operations
  • Error Propagation - Centralized error handling with proper status codes
🧩 Renderer IPC Helper

Renderer code uses a lightweight proxy generated at runtime to keep IPC calls type-safe without exposing raw Electron objects through contextBridge. Use the helper exported from src/utils/electron/ipc.ts to access the main-process services:

import { ensureElectronIpc } from '@/utils/electron/ipc';

const ipc = ensureElectronIpc();
await ipc.windows.openSettingsWindow({ tab: 'provider' });

The helper internally builds a proxy on top of window.electronAPI.invoke, so no proxy objects need to be cloned across the preload boundary.

🛡️ Security Features

  • OAuth 2.0 + PKCE - Secure authentication with state parameter validation
  • Encrypted Token Storage - Using Electron's Safe Storage API when available
  • Custom Protocol Handler - Secure callback handling for OAuth flows
  • Request Filtering - Security controls for web requests and external links

🧪 Testing

Test Structure

apps/desktop/src/main/controllers/__tests__/ # Controller unit tests
tests/                                       # Integration tests

Running Tests

pnpm test       # Run all tests
pnpm test:watch # Watch mode
pnpm type-check # Type validation

Test Coverage

  • Controller Tests - IPC event handling validation
  • Service Tests - Business logic verification
  • Integration Tests - End-to-end workflow testing
  • Type Tests - TypeScript interface validation

🔒 Security Features

Authentication & Authorization

  • OAuth 2.0 Flow with PKCE for secure token exchange
  • State Parameter Validation to prevent CSRF attacks
  • Encrypted Token Storage using platform-native secure storage
  • Automatic Token Refresh with fallback to re-authentication

Application Security

  • Code Signing - macOS notarization for enhanced security
  • Sandboxing - Controlled access to system resources
  • CSP Controls - Content Security Policy management
  • Request Filtering - Security controls for external requests

Data Protection

  • Encrypted Configuration - Sensitive data encrypted at rest
  • Secure IPC - Type-safe communication channels
  • Path Validation - Secure file system access controls
  • Network Security - HTTPS enforcement and proxy support

🤝 Contribution

Desktop application development involves complex cross-platform considerations and native integrations. We welcome community contributions to improve functionality, performance, and user experience. You can participate in improvements through:

How to Contribute

  1. Platform Support: Enhance cross-platform compatibility and native integrations
  2. Performance Optimization: Improve application startup time, memory usage, and responsiveness
  3. Feature Development: Add new desktop-specific features and capabilities
  4. Bug Fixes: Fix platform-specific issues and edge cases
  5. Security Improvements: Enhance security measures and authentication flows
  6. UI/UX Enhancements: Improve desktop user interface and experience

Contribution Process

  1. Fork the LobeChat repository
  2. Set up the desktop development environment following our setup guide
  3. Make your changes to the desktop application
  4. Submit a Pull Request describing:
  • Platform compatibility testing results
  • Performance impact analysis
  • Security considerations
  • User experience improvements
  • Breaking changes (if any)

Development Areas

  • Core Architecture: Dependency injection, event system, and lifecycle management
  • Window Management: Multi-window support, theme synchronization, and state persistence
  • IPC Communication: Type-safe inter-process communication between main and renderer
  • Platform Integration: Native menus, shortcuts, notifications, and system tray
  • Security Features: OAuth flows, token encryption, and secure storage
  • Auto-Update System: Multi-channel updates and rollback mechanisms

📚 Additional Resources