FynApp Guide: Create or Modify an App
A step by step guide to create a new FynApp or change an existing one. It is written for developers and for coding agents that follow the FynApp contract.
This package supports two distinct workflows. Pick the right one.
| You want to… | Do this |
|---|---|
| Create a new FynApp | Run the static create-fynapp CLI (§1). Mechanical, no code understanding needed. |
| Modify an existing FynApp | You're a coding agent — follow CONTRACT.md, copy from the FynMesh examples, then cfa check (§2). |
| Update FynApps to a changed kernel API | Follow MIGRATION.md. |
Claude Code skills (opt-in). This package bundles two skills under
../skills/—fynapp-modifyandfynapp-migrate-kernel. They are not installed automatically. To make them available in a project, runcfa install-skills— it copies them into<project>/.claude/skills/(--forceto overwrite)..claude/is typically gitignored, so each user decides whether to install them.
1. Create a new FynApp (CLI — static scaffold)
From the monorepo root:
create-fynapp --name my-fynapp --framework react
# options: --name/-n, --framework/-f (any framework name; templates:
# react | react18 | preact | vue | solid | svelte | marko | vanilla),
# --dir/-d (defaults to the name), --skip-install
--framework accepts any name. Eight frameworks ship a hand-authored
template and scaffold a complete working app. Any other name — qwik, lit,
alpine, whatever you can work with — scaffolds the framework-generic skeleton
instead, plus an AGENT-TODO.md in the new app. That scaffold is not a stub:
it installs, builds and passes cfa check before you touch it, so you convert
it one step at a time from a green baseline. Converting it is a modify task
(§2) and AGENT-TODO.md is its checklist.
Run from the monorepo root this scaffolds demo/my-fynapp/; run anywhere else
it scaffolds my-fynapp/ in the current directory. Either way from static
templates: package.json, tsconfig.json, rollup.config.ts (the
createFynAppRollupConfig factory form), and a starter src/. It does not
reason about your code — it just stamps out a known-good skeleton that already
conforms to CONTRACT.md.
Register the new app in the demo server
The scaffold creates the app but the demo server must be told about it:
demo/demo-server/templates/components/fynapp-loader.html— add your app to thefeaturesmap:"my-fynapp": true(true= eager,"lazy"= button-triggered, omit = off).demo/demo-server/src/dev-proxy.ts— add a path mapping so the dev server can find its files:[ { path: "/my-fynapp" }, { protocol: "file", path: Path.join(__dirname, "../../my-fynapp") } ],
Then from the repo root: fyn bootstrap (build all) and fyn start
(→ http://localhost:3000/demo.html).
Editing
fynapp-loader.html/dev-proxy.tsis a trivial config edit — do it mechanically. Anything beyond stamping the skeleton (real components, middleware, rendering logic) is a modify task → §2.
2. Modify an existing FynApp (coding agent)
Modifying requires understanding the code, so it is your job, not a code-mod's. The loop:
- Read the contract.
CONTRACT.mdis authoritative for theFynUnitlifecycle,rollup.config.ts, middleware consume/provide, render results, and package/tsconfig shape. - Copy a pattern. Find the closest match in the FynMesh examples:
react-minimal— standalone React app.middleware-consumer— consume another app's middleware.middleware-provider— author a middleware.vanilla— framework-agnostic. The working demo appsdemo/fynapp-6-reactanddemo/fynapp-design-tokensare the fuller, real-world versions.
- Make the surgical edit to
src/(and, if adding an exposed module or a dependency, the trivial config edits torollup.config.ts/package.json). - Check — the change is not done until this passes:
cd demo/<fynapp> && cfa checkcfa checkbuilds via rollup and checks the federation output (dist/fynapp-entry.js+ a validdist/fynapp.manifest.jsonexposing./main). Use--no-buildto check an existingdist/. - If the app renders UI, also load it in the demo (
fyn start) to confirm runtime behavior — types and manifest passing does not prove it renders.
Common modifications (all → CONTRACT.md sections)
- Add/adjust rendering →
FynUnit.execute+ render results (CONTRACT §2, §5). - Consume a middleware →
useMiddleware+middlewareContext.get(CONTRACT §4). - Provide a middleware →
__middleware__export +setup/apply(CONTRACT §6); add the./middleware/*expose torollup.config.ts(CONTRACT §3). - Add a dependency →
package.json(trivial); React apps use publicreact/react-dom.
3. Build helpers exported by create-fynapp
rollup.config.ts files import these from create-fynapp:
| API | Purpose |
|---|---|
createFynAppRollupConfig(opts) |
Preferred whole-config factory |
setupFynAppOutputConfig() |
Standard dist/ SystemJS output |
setupDummyEntryPlugins() |
Virtual entry federation requires |
setupReactFederationPlugins(cfg) / setupFederationPlugins(cfg) |
Federation + manifest |
setupReactAliasPlugins() |
Local-demo alias: react → esm-react |
setupMinifyPlugins() |
Terser (production only) |
fynappDummyEntryName, fynappEntryFilename, env |
Constants for the low-level form |
checkFynApp, runCheck |
Programmatic output check (what cfa check calls) |
Debug the build with DEBUG=create-fynapp.