Project Structure
Tour the frontend, the Rust core, shared config, and the Supabase backend layout.
The template splits by boundary first — the sandboxed frontend (src/), the
privileged Rust core (src-tauri/), and the cross-cutting brand/config both
sides read (shared/) — then by feature inside each.
Top-level layout
App.tsx
main.tsx
tauri.conf.json
Cargo.toml
vite.config.ts
Frontend: src/
src/ is the sandboxed React SPA. It uses HashRouter, lazy routes, TanStack
Query, zustand stores, i18next, and shadcn/ui primitives.
| Path | Role |
|---|---|
src/main.tsx | Browser entry: validates the Supabase env, then mounts either App or the standalone config-error screen. |
src/App.tsx | Route tree, providers, app-intent navigation, analytics route tracking, onboarding gate. |
src/routes/ | Home, Settings, Account, Billing, About, Logs, Help, Update, NotFound/Error, the auth/ pages, and the showcase/ routes. |
src/components/ | Shell + sidebar (layout/), window/ titlebar, command-palette/, onboarding/, billing/, and ui/ primitives. |
src/services/ | Pure Supabase / Edge-Function calls: todos, profile, avatar, subscription, billing, license/, analytics, error-reporting. |
src/stores/ | auth-store and subscription-store (zustand). |
src/showcase/ | [template-demo] capability catalog and its types. |
src/locales/ | en/ and zh/ JSON catalogs (common, auth, settings, showcase). |
src/lib/ — the frontend engine room
| Module | Responsibility |
|---|---|
lib/tauri/ | Typed per-domain wrappers (app, window, secure, logs, file, diagnostics, update) over the generated bindings, plus events.ts and external-url.ts. |
lib/bindings.ts | Generated and committed tauri-specta types — never hand-edit (see below). |
lib/settings/ | Zod schema, versioned store, and backup import/export. |
lib/intents/ | parse → dispatcher deep-link/argv intents, validated against routes.ts. |
lib/menu/ + lib/tray/ | The native menu and tray, built in TypeScript (Tauri v2 JS APIs). |
lib/updates/ | The update scheduler (background-check timing). |
lib/supabase/ | Client, env validation, typed database.types.ts, keychain-backed session storage. |
lib/auth/, lib/i18n/, lib/query/, lib/logging/, lib/notifications.ts, lib/shortcuts.ts | Auth schemas, i18next bootstrap, the query client, redacted logging, notifications, and the shortcut registry. |
lib/conveyor/ | A port-compat shim carried over from the Electron template (see the note on IPC). |
Rust core: src-tauri/
src-tauri/src/ owns everything privileged; the webview never touches the OS
directly.
| Path | Role |
|---|---|
src/main.rs | Thin binary entry that calls run(). |
src/lib.rs | Registers plugins (single-instance first), the setup hook, and the tauri-specta command builder. |
src/commands/ | Command modules by domain: app, secure, logs, window, diagnostics, update, plus redaction.rs. |
src/error_reporting.rs | Optional Rust-side Sentry init with payload redaction. |
capabilities/default.json | The capabilities ACL scoped to the main window. |
tauri.conf.json | Window, CSP, bundle, updater, and deep-link config. |
Cargo.toml | Rust dependencies and crate features. |
icons/ | Generated app icons (pnpm tauri icon). |
Shared and backend
| Path | Role |
|---|---|
shared/constants.ts | The single brand-identity source (app id, name, slug, scheme, support/repo URLs, EULA). |
shared/config.ts | The central env-read hub: features, billingConfig, showcaseConfig, analytics/Sentry config. Nothing else reads import.meta.env. |
shared/feature-flags.ts / shared/price-config.ts | Native-flag payload shape and the Creem product → tier map. |
supabase/migrations/ + supabase/functions/ | Committed SQL and Edge Functions (billing schema shared with Electron; see Supabase Setup). |
resources/ | Source tray/icon art. |
scripts/ | rebrand.mjs and deploy-edge-functions.sh. |
test/e2e/ | An isolated WebdriverIO + tauri-driver harness with its own package.json. |
docs/ | CUSTOMIZE, CAPABILITIES, APP_ICONS, RELEASE. |
Path aliases and build config
@/→src/and@/shared/→shared/(the more specific@/sharedalias is ordered to win invite.config.ts).- TypeScript uses project references:
tsconfig.web.json(frontend +shared+test) andtsconfig.node.json, composed by the roottsconfig.json. - Vite serves a fixed dev port
1420(strictPort) and ignoressrc-tauri/from its watcher so Rust changes don't churn the frontend.
src/lib/bindings.ts is generated from the Rust commands and committed. It
regenerates on every pnpm dev and by the export_bindings cargo test, and
CI fails on any drift. Change commands in Rust and let the file rewrite — never
hand-edit it.
Tests and the demo marker
- Tests are colocated as
*.test.ts(x)next to the code they cover.pnpm test(test:core) runs the fast logic suite under jsdom;pnpm test:allruns everything. Rust tests live in the crate and run withcargo test. - Demo code is marked with
[template-demo]. Preview the app withVITE_SHOWCASE_ENABLED=false, then follow Showcase to deletesrc/showcase/andsrc/routes/showcase/and clean the enumerated touchpoints.
