Overlay Architecture¶
Crabyard generates projects using a base + overlay composition model. The base scaffold provides the app skeleton, and overlays add specific features (auth provider, UI framework) by merging files on top.
How It Works¶
base/ ← Core app (always copied first)
+ auth/{module}/ ← Auth overlay (adds/replaces files)
+ ui/{module}/ ← UI overlay (adds/replaces files)
= your project ← Fully assembled app
Generation order¶
- Copy base template — the minimal Tauri v2 + React scaffold
- Apply auth overlay — copies auth module files on top (overwrites matching paths)
- Apply UI overlay — copies UI module files on top
- Process markers — replaces
// CRABYARD:MARKER_NAMEcomments with module-injected code - Replace tokens — substitutes
{{APP_NAME}},{{APP_SLUG}}, etc. - Merge dependencies — combines
npm_dev_dependenciesfrommodule.jsonintopackage.json
Base Template¶
The base scaffold at base/ in crabyard-templates contains:
- React 19 entry point (
main.tsx,App.tsx) - Zustand store with marker comments for auth injection
- Rust backend with
lib.rs,error.rs,state.rs - Tauri commands for settings (load, save, folder picker)
- Vite config, TypeScript config,
package.json - Custom
TitleBar(from UI overlay) UpdateBannerfor auto-updates
The base is not standalone — it requires an auth overlay (even none) and a UI overlay.
Module Configuration¶
Each overlay has a module.json that declares:
{
"markers": {
"CRABYARD:MOD_AUTH": "pub mod auth;",
"CRABYARD:COMMANDS": "commands::auth::login,\ncommands::auth::logout,"
},
"npm_dev_dependencies": {
"lucide-react": "^0.577.0"
}
}
Markers¶
Markers are placeholder comments in base template files:
// CRABYARD:MOD_AUTH
During generation, the entire comment line is replaced with the content from module.json's markers map. This injects auth commands into lib.rs, error variants into error.rs, state fields into state.rs, etc.
Markers are matched in both // (Rust/TypeScript) and # (TOML/shell) comment styles.
Dependencies¶
The npm_dev_dependencies map is merged into the generated package.json's devDependencies. Later overlays override earlier ones if the same package appears.
Available Modules¶
Auth¶
| Module | Overlay | Strategy |
|---|---|---|
github |
auth/github/ |
GitHub Device Flow OAuth |
google |
auth/google/ |
Google Loopback PKCE |
none |
auth/none/ |
No authentication |
UI¶
| Module | Overlay | Components |
|---|---|---|
shadcn |
ui/shadcn/ |
Radix UI primitives + shadcn styling |
daisyui |
ui/daisyui/ |
Tailwind class-based components |
minimal |
ui/minimal/ |
Tailwind utilities without an external component library |
Token System¶
These tokens are replaced in all non-binary files during generation:
| Token | Example Value |
|---|---|
{{APP_NAME}} |
My Desktop App |
{{APP_SLUG}} |
my-desktop-app |
{{APP_SLUG_SNAKE}} |
my_desktop_app |
{{APP_BUNDLE_ID}} |
com.example.mydesktopapp |
{{APP_VERSION}} |
0.1.0 |
{{APP_DESCRIPTION}} |
A desktop application |
{{APP_AUTHOR}} |
Your Name |
{{PACKAGE_MANAGER}} |
bun |
{{PM_RUN}} |
bun run |
{{PM_TAURI_DEV}} |
bun run tauri dev |
{{CRABYARD_VERSION}} |
1.8.0 |
{{GENERATED_AT}} |
1741500000 |
In .tsx/.jsx templates, keep replacement tokens inside quoted strings rather than bare JSX expressions. The generator escapes token values for supported source-file formats; a bare {{TOKEN}} JSX expression has a different meaning to the JSX parser.
Manifest¶
Each generated project includes manifest.toml, which records:
- Template version
- Selected modules (auth, UI, package manager)
- Project metadata (name, slug, bundle ID)
The crabyard update-ui command reads this manifest to determine the current UI framework and apply updates.