Project Starters
packages/astro-template holds the Astro projects the editor scaffolds new sites from. templates/ is the source of truth and is designed to live in (and be released from) its own repo, cloned into new projects at creation time. Its root holds one directory per starter:
plain/— as plain as it can be: Astro + Tailwind, the data-module behaviour system, and the dormant Sanity starter. Every navigation is a full page load.motion/— plain plus the animation core insrc/lib/: Lenis smooth scroll, Taxi seamless page transitions (wired into the module lifecycle),heyglobal state, and unified rAF/resize subscriptions. Skipped inside the editor canvas iframe, which stays a plain document.
The starter is chosen at project creation and recorded in the project’s package.json (plyy.starter).
How the editor resolves a starter
Section titled “How the editor resolves a starter”Resolution order (implemented in apps/app/src-tauri/src/bun.rs, template_dir(app, starter)):
PLYY_TEMPLATE_DIR— explicit local checkout; hot re-wiring while working on the starters themselves. Beats everything. May point at the starters root or (legacy) a single template.- This monorepo’s
templates/<starter>— live source in dev. - Cloned cache — a shallow clone of the standalone template repo (
PLYY_TEMPLATE_REPO, defaultvallafederico/plyy-template), refreshed on every project create. Built apps use this, so starter releases ship without an app update. Old single-template clones still resolve as a fallback. - Bundled snapshot — build-time copy inside the app resources (
templates/<starter>, legacytemplates/astro-basic) — offline first-run fallback.
What the starters ship
Section titled “What the starters ship”- Layouts —
BaseLayoutandPageLayout(header/footer shell) - Components —
Section(container wrapper),Card,Button,Hero,SiteHeader,SiteFooter - Pages —
/,/about,/contact - Modules — the
data-modulebehaviour runtime plus starter modules (see Modules). In motion projects, modules should return a teardown — page content is swapped in-place by Taxi; in plain projects a full page load resets everything, so teardowns are optional. - Editor bridge —
src/integrations/editor-bridge.ts, synced into projects on open. Identical across starters (enforced bybridge.test.ts). - Sanity starter —
src/sanity/(trimmed turbo-solid schema: home + page viacreatePage,pageSlices, shared blocks, header/footer/SEO singletons) plussanity.config.ts,sanity.cli.ts, andsrc/lib/sanity.ts. Dormant until the editor’s Connect CMS flow installs deps and writes.env; bridge sync restores missing files but never overwrites user edits. The embedded Studio is branded to match the site viasrc/sanity/theme.ts. - Brand tokens —
src/styles/global.css(@theme, canonical for Tailwind) mirrored insrc/lib/brand.tsfor JS consumers (the Studio theme today, component systems later). A rebrand is a two-file edit; the files cross-reference each other. - Icons —
astro-icon+@iconify-json/lucideship with both starters:<Icon name="lucide:menu" />inlines SVG at build time (zero client JS). The config guards the integration so older projects without the dep keep working. - Fonts — one convention: woff2 files in
public/fonts/(the editor converts ttf/otf on import),@font-facerules plus a--font-<name>@themetoken insrc/styles/fonts.css(imported byglobal.css). The token makes Tailwind exposefont-<name>. The editor’s Assets panel (Fonts tab) manages this file: it imports font files from the machine (or the OS font folders), and registered families appear in the Typography font dropdown. astro.config.mjs— single env-guarded config, identical across starters. WithPUBLIC_SANITY_PROJECT_IDset it lazily activates@sanity/astroand the embedded Studio at/admin. The editor re-copies this file on bridge sync, so config changes migrate existing projects.- Motion animation core (
motion/src/lib/) —scroll.ts(Lenis on the unified rAF,window.sscroll),pages.ts(Taxi transitions driving the module lifecycle; teardown scoped to the swapped[data-taxi-view]so persistent chrome survives),hey.ts(global reactive state),raf.ts/resize.ts(onRaf/onResizeshared loops),easings.ts.
Editor contract (boilerplate v2)
Section titled “Editor contract (boilerplate v2)”Pages own content, components are chrome. Per-instance text lives in page source (slots/props at the call site), so the visual editor’s source round-trip edits the page, not the shared component. Component internals are edited via their own file.
Releasing
Section titled “Releasing”bash packages/astro-template/publish.sh git@github.com:vallafederico/plyy-template.gitA git subtree push of templates/ to the standalone repo (its root then holds plain/ and motion/).