

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# LobeHub Development Guidelines23Guidelines for using AI coding agents in this opensource LobeHub repository.45## Tech Stack67- Next.js 16 + React 19 + TypeScript8- SPA inside Next.js with `react-router-dom`9- `@lobehub/ui`, antd, and antd-style for UI implementation10- react-i18next for i18n; zustand for state management11- SWR for data fetching; TRPC for type-safe backend12- Drizzle ORM with PostgreSQL; Vitest for testing1314## Agent Skills1516`AGENTS.md` owns repository-wide architecture and workflow. Keep detailed implementation rules in skills so they have one source of truth.1718- **React and TSX**: Before editing components, component state, render boundaries, or memoization, read [`.agents/skills/react/SKILL.md`](.agents/skills/react/SKILL.md). It owns component selection, styling, state locality, and render-performance rules.1920## Project Structure2122```plaintext23lobehub/24├── apps/25│ ├── desktop/ # Electron desktop app26│ ├── cli/ # LobeHub CLI27│ └── server/ # Backend service (Hono app + server routers/services)28├── packages/ # Shared packages (@lobechat/*)29│ ├── database/ # Database schemas, models, repositories30│ ├── agent-runtime/ # Agent runtime31│ ├── locales/ # i18n source: packages/locales/src/default/32│ ├── env/ # env schemas (@/envs/* → packages/env/src/*)33│ └── ...34├── src/35│ ├── app/ # Next.js App Router (route shell + auth)36│ │ ├── (backend)/ # Backend route shells37│ │ ├── spa/ # SPA HTML template service38│ │ └── spa-auth/ # Auth HTML shell (SSR)39│ ├── routes/ # SPA page segments (thin — delegate to features/)40│ │ ├── (main)/ (mobile)/ (desktop)/ (popup)/41│ │ ├── auth/ # Auth page segments (signin, signup, …)42│ │ ├── onboarding/ share/43│ ├── spa/ # SPA entry points and router config44│ │ ├── entry.{web,mobile,desktop,popup}.tsx45│ │ └── router/ # React Router configuration46│ ├── store/ # Zustand stores47│ ├── services/ # Client services48│ ├── libs/ # Shared client/server helpers for the app shell49│ └── ...50└── e2e/ # E2E tests (Cucumber + Playwright)51```5253## SPA Routes and Features5455SPA-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.5657- **`src/spa/`** – SPA entry points (`entry.web.tsx`, `entry.mobile.tsx`, `entry.desktop.tsx`, `entry.popup.tsx`) and React Router config (`router/`, with `desktopRouter.config.*`, `mobileRouter.config.tsx`, `popupRouter.config.tsx`). Keeps router config next to entries to avoid confusion with `src/routes/`.5859- **`src/routes/` (roots)**\60 Only page-segment files: `_layout/index.tsx`, `index.tsx` (or `page.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.6162- **`src/features/`**\63 Business components by **domain** (e.g. `Pages`, `PageEditor`, `Home`). Put layout chunks (sidebar, header, body), hooks, and domain-specific UI here. Each feature exposes an `index.ts` (or `index.tsx`) with clear exports.6465When adding or changing SPA routes:66671. In `src/routes/`, add only the route segment files (layout + page) that delegate to features.682. Implement layout and page content under `src/features/<Domain>/` and export from there.693. In route files, use `import { X } from '@/features/<Domain>'` (or `import Y from '@/features/<Domain>/...'`). Do not add new `features/` folders inside `src/routes/`.704. **Register shared desktop content routes once:** add common Web/Electron paths, nesting, metadata, lazy loaders, and `preloadId` values in `src/spa/router/desktopRouter.shared.tsx`. The thin `desktopRouter.config.tsx` and `desktopRouter.config.desktop.tsx` files contain only runtime differences: Web mounts the content tree directly, while Electron keeps slim root stubs and mounts the same tree in per-tab memory routers through `src/spa/router/tabRouter.tsx`. Add code to a platform adapter only when the route is genuinely platform-specific. `desktopRouter.sync.test.tsx` guards the shared behavior and explicit differences — keep it passing.7172See the **spa-routes** skill for the full convention and file-division rules.7374## Development7576### Starting the Dev Environment7778```bash79# SPA dev mode (frontend only, proxies API to localhost:3010)80bun run dev:spa8182# Full-stack dev (Next.js + Vite SPA concurrently)83bun run dev8485# Standalone Hono backend service86pnpm --filter @lobechat/server dev87```8889### Backend Architecture9091- Backend runtime code lives under `apps/server/src` and is imported through `@/server/*`.92- `src/app/(backend)` contains Next.js route shells. Do not add backend business logic there.93- Web shell helpers belong under `src/libs/*` or the relevant `src/app` segment, not under `src/server`.9495After `dev:spa` starts, the terminal prints a **Debug Proxy** URL:9697```plaintext98Debug Proxy: https://app.lobehub.com/_dangerous_local_dev_proxy?debug-host=http%3A%2F%2Flocalhost%3A987699```100101Open 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.102103### Git Workflow104105- **Branch strategy**: `canary` is the development branch (cloud production); `main` is the release branch (periodically cherry-picks from canary)106- New branches should be created from `canary`; PRs should target `canary`107- Use rebase for `git pull`108- Commit messages: prefix with gitmoji109- Branch format: `<type>/<feature-name>`110111### Package Management112113- `pnpm` for dependency management114- `bun` to run npm scripts115- `bunx` for executable npm packages116117### Quality Check118119```bash120bun run check [changed-files...]121```122123- Every bug fix must include a corresponding regression test that fails before the fix and passes after it. **Skip** when the fix is pure style/CSS (selector, hover, mask, spacing, color) and the only practical assertion would be source-string matching on the stylesheet — that is not a regression test worth shipping.124- No selector = **lint + test in a single pass** — run it once; don't fire a separate pass per selector. `--lint` / `--test` / `--type` narrow scope and are composable within one run. Default files = all working-tree changes (staged + unstaged + untracked); explicit paths override.125- `--lint` auto-fixes the given files and prints the applied fixes as a diff, so you can review what changed.126- `--test` auto-discovers the related tests for the given source files and runs them under the nearest owning vitest config (e.g. `packages/database`) — no need to `cd` into packages.127- `--type` runs the full type-check. NEVER run `bun run test` — the full suite takes \~10 minutes.128- To run tests manually (e.g. a single file or unusual flags), `cd` into the owning package first: `cd packages/database && bunx vitest run --silent='passed-only' '[file-path]'`.129130### i18n131132- Add keys to a namespace file under `packages/locales/src/default/` (e.g. `agent.ts`, `auth.ts`)133- Ship en-US and zh-CN by hand in the same PR: author the English source in `packages/locales/src/default/*.ts`, mirror it to `locales/en-US/`, and hand-translate `locales/zh-CN/`.134- Leave all other locales to the daily CI workflow (`.github/workflows/auto-i18n.yml`), which runs `bun run i18n` and opens an automated translation PR. Missing locale keys fall back to English until that PR is merged.135- Run `bun run i18n` manually only when the translated locales are needed immediately instead of waiting for the daily workflow. It is slow and requires `OPENAI_API_KEY`; don't hand-translate the generated locales.136137### Code Style138139- When a single file grows beyond \~800 lines, consider splitting it into multiple files (extract sub-components, hooks, helpers, or types). Smaller, focused files are friendly to humans and agents.140141### Code Review142143Before reviewing a PR / diff / branch change, read the **deep-review** skill. Ordinary review requests use its light mode (inline review against the dimension quick checklists); the full multi-subagent deep mode runs only on explicit invocation.144145When designing or reviewing user-facing flows (empty/loading/error states, confirmations, async feedback, button hierarchy, lists at scale, pickers), follow LobeHub's design values in [`DESIGN.md`](./DESIGN.md) — Natural / Meaningful / Certainty / Growth (自然 / 意义感 / 确定性 / 成长).146
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| lobehub/lobehube2e/CLAUDE.md · 82k | CLAUDE.md | testtypestesting-strategygit+1 | 86/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| code-yeongyu/oh-my-openagentpackages/web/AGENTS.md · 68k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 13 days ago | |
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 14 days ago | |
| aaif-goose/gooseAGENTS.md · 53k | AGENTS.md | setupbuildtestlint-format+7 | 100/100 | 8 days ago | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| deepseek-ai/deepseek-harnessnative/landlock-run/AGENTS.md · 104k | AGENTS.md | setupteststylearch+3 | 100/100 | today | |
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | today | |
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 201k | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| elastic/elasticsearchx-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/AGENTS.md · 78k | AGENTS.md | buildtestlint-formatstyle+2 | 100/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/lobehub-lobehub-agents)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.