Skip to content
← Public packages

@kentcdodds/package-app-kit

Design tokens, PWA install/update, About/version, cache helpers, and optional realtime notes sync for Kody package apps.

FollowFork

starter-tanstack/STARTER.md

64 lines · 3.8 KB · Markdown

TanStack Router starter template

Canonical scaffolder template for @kentcdodds/package-app-kit create-package-app-tanstack (embeds via src/starter-tanstack-templates.ts / scripts/embed-starter.mjs).

Requires the framework-agnostic package-app host (kody#2312+). TanStack Router + React is a recipe with remount / jsx / hydrate boilerplate — do not set kody.app.runtime. Do not use TanStack Start's Vite toolchain — Kody publishes Workers without Vite.

The Remix recipe lives at starter-remix/ (create-package-app). The archived fetch template lives at starter-fetch/.

Layout (TanStack + React recipe)

tsconfig.json              # jsx react-jsx, jsxImportSource react
app/router.ts              # kody.app.entry — remount + export default { fetch }
app/routeTree.tsx          # @tanstack/react-router route tree + createAppRouter
app/ssr.tsx                # react-dom/server.edge renderToReadableStream (Workers-safe)
app/routes.ts              # createRoutes(appBasePath) href helpers
app/pages/*.tsx            # home, about, notes page components
app/controllers/*          # manifest, icons, version, notes POST action
app/data/notes.ts          # packageStorage() notes + migrations
app/ui/*.tsx               # Document, layout, About/Notes/Install React components
app/assets/entry.ts        # kody.app.client — hydrateRoot + RouterProvider
public/                    # kody.app.assets — styles.css + sw.js

package.json#kody.app (no runtime field — entry is a fetch handler):

{
  "entry": "./app/router.ts",
  "client": "./app/assets/entry.ts",
  "assets": "./public"
}

Hard rules

  • Prefer @tanstack/react-router + react / react-dom (declare in dependencies so the host inlines them).
  • No TanStack Start / Vite / Pitlane inside the Worker publish.
  • Mount-aware URLs via basepath + remount in app/router.ts (same remount shape as Remix).
  • Server-only modules (app/data/*, controllers using kody:) must not be imported from the browser graph; loaders fall back to Accept: application/json fetches.
  • Root tsconfig.json sets "jsx": "react-jsx" + "jsxImportSource": "react" (standard React JSX — not remix/component pragmas).
  • SW in public/sw.js reads /_assets/__version.json — no hash in source.

Placeholders

__PACKAGE_NAME__, __PACKAGE_ID__, __APP_TITLE__, __CACHE_NAME__, __KODY_DESCRIPTION__

List / identity mark

Default mark included: the square TanStack koala (tight head/shoulders crop of the Hawaiian-shirt bust). Ships as:

  • .kody/icon.png (git lane) and .kody/icon.svg (base64-wrapped PNG for text-only packageSave)
  • icons/icon-192.png + icons/icon-512.png (git lane binaries)
  • src/icon-png-bytes.ts — embedded PNG bytes so /icons/icon-192.png + /icons/icon-512.png routes work without binary packageSave

Favicon, PWA, and .kody/icon default to this TanStack mark (not the placeholder “T” SVG, not the Remix race-driver). Replace only when product-branding. Never scaffold root community-icon.*. Keep list identity in .kody/; keep PWA binaries under icons/ (or serve via the bytes module).

After scaffold

Default tokens/theme-color are Remix-dark charcoal + cyan (match or replace when branding). The TanStack koala mark is already the default favicon / .kody/icon / PWA mark — replace it only when the product needs its own brand. Follow the After scaffolding checklist in AGENTS.template.md. Then smoke with packageAppFetch on /, /notes, /about, /manifest.webmanifest, icons, and /health.

Layout stability / press feedback / errors

Same product rules as the Remix starter: zero CLS update toast, spin-delay busy labels (app/ui/busy.ts), ErrorBanner for reserved failures.