LobeHub Development Guidelines
Guidelines for using AI coding agents in this LobeHub repository.
Tech Stack
- Next.js 16 + React 19 + TypeScript
- SPA inside Next.js with
react-router-dom @lobehub/ui, antd for components; antd-style for CSS-in-JS โ prefercreateStaticStyleswithcssVar.*(zero-runtime); only fall back tocreateStyles+tokenwhen styles genuinely need runtime computation. See.cursor/docs/createStaticStyles_migration_guide.md.- react-i18next for i18n; zustand for state management
- SWR for data fetching; TRPC for type-safe backend
- Drizzle ORM with PostgreSQL; Vitest for testing
Project Structure
lobehub/
โโโ apps/
โ โโโ desktop/ # Electron desktop app
โ โโโ cli/ # LobeHub CLI
โ โโโ device-gateway/ # Device gateway service
โโโ packages/ # Shared packages (@lobechat/*)
โ โโโ database/ # Database schemas, models, repositories
โ โโโ agent-runtime/ # Agent runtime
โ โโโ ...
โโโ src/
โ โโโ app/ # Next.js App Router (backend API + auth)
โ โ โโโ (backend)/ # API routes (trpc, webapi, etc.)
โ โ โโโ spa/ # SPA HTML template service
โ โ โโโ [variants]/(auth)/ # Auth pages (SSR required)
โ โโโ routes/ # SPA page components (Vite)
โ โ โโโ (main)/ # Desktop pages
โ โ โโโ (mobile)/ # Mobile pages
โ โ โโโ (desktop)/ # Desktop-specific pages
โ โ โโโ (popup)/ # Popup window pages
โ โ โโโ onboarding/ # Onboarding pages
โ โ โโโ share/ # Share pages
โ โโโ spa/ # SPA entry points and router config
โ โ โโโ entry.web.tsx # Web entry
โ โ โโโ entry.mobile.tsx
โ โ โโโ entry.desktop.tsx
โ โ โโโ entry.popup.tsx
โ โ โโโ router/ # React Router configuration
โ โโโ store/ # Zustand stores
โ โโโ services/ # Client services
โ โโโ server/ # Server services and routers
โ โโโ ...
โโโ e2e/ # E2E tests (Cucumber + Playwright)
SPA Routes and Features
SPA-related code is grouped under src/spa/ (entries + router) and src/routes/ (page segments). We use a roots vs features split: route trees only hold page segments; business logic and UI live in features.
-
src/spa/โ SPA entry points (entry.web.tsx,entry.mobile.tsx,entry.desktop.tsx,entry.popup.tsx) and React Router config (router/, withdesktopRouter.config.*,mobileRouter.config.tsx,popupRouter.config.tsx). Keeps router config next to entries to avoid confusion withsrc/routes/. -
src/routes/(roots)
Only page-segment files:_layout/index.tsx,index.tsx(orpage.tsx), and dynamic segments like[id]/index.tsx. Keep these thin: they should only import from@/features/*and compose layout/page, with no business logic or heavy UI. -
src/features/
Business components by domain (e.g.Pages,PageEditor,Home). Put layout chunks (sidebar, header, body), hooks, and domain-specific UI here. Each feature exposes anindex.ts(orindex.tsx) with clear exports.
When adding or changing SPA routes:
- In
src/routes/, add only the route segment files (layout + page) that delegate to features. - Implement layout and page content under
src/features/<Domain>/and export from there. - In route files, use
import { X } from '@/features/<Domain>'(orimport Y from '@/features/<Domain>/...'). Do not add newfeatures/folders insidesrc/routes/. - Register the desktop route tree in both configs:
src/spa/router/desktopRouter.config.tsxandsrc/spa/router/desktopRouter.config.desktop.tsxmust stay in sync (same paths and nesting). Updating only one can cause blank screens if the other build path expects the route.desktopRouter.sync.test.tsxguards this invariant โ keep it passing.
See the spa-routes skill (.agents/skills/spa-routes/SKILL.md) for the full convention and file-division rules.
Development
Starting the Dev Environment
# SPA dev mode (frontend only, proxies API to localhost:3010)
bun run dev:spa
# Full-stack dev (Next.js + Vite SPA concurrently)
bun run dev
After dev:spa starts, the terminal prints a Debug Proxy URL:
Debug Proxy: https://app.lobehub.com/_dangerous_local_dev_proxy?debug-host=http%3A%2F%2Flocalhost%3A9876
Open this URL to develop locally against the production backend (app.lobehub.com). The proxy page loads your local Vite dev server's SPA into the online environment, enabling HMR with real server config.
Git Workflow
- Branch strategy:
canaryis the development branch (cloud production);mainis the release branch (periodically cherry-picks from canary) - New branches should be created from
canary; PRs should targetcanary - Use rebase for
git pull - Commit messages: prefix with gitmoji
- Branch format:
<type>/<feature-name>
Package Management
pnpmfor dependency managementbunto run npm scriptsbunxfor executable npm packages
Testing
# Run specific test (NEVER run `bun run test` - takes ~10 minutes)
bunx vitest run --silent='passed-only' '[file-path]'
# Database package
cd packages/database && bunx vitest run --silent='passed-only' '[file]'
- Prefer
vi.spyOnovervi.mock - Tests must pass type check:
bun run type-check - After 2 failed fix attempts, stop and ask for help
i18n
- Add keys to a namespace file under
src/locales/default/(e.g.agent.ts,auth.ts) - For dev preview: translate
locales/zh-CN/andlocales/en-US/ pnpm i18nis slow; run it manually when locale keys need updating (e.g. before opening a PR).
Code Review
Before reviewing a PR / diff / branch change, read the review-checklist skill (.agents/skills/review-checklist/SKILL.md) โ it lists the recurring mistakes specific to this codebase.