AppRun
Use this skill to make AppRun-specific architecture decisions. Keep the work anchored in the existing codebase before inventing a pattern.
First Pass
- Inspect the local source, tests, and package scripts before changing behavior.
- Identify whether the task is about an application using AppRun or the AppRun library itself.
- Preserve existing project tooling unless the user explicitly asks to change it.
- Prefer the smallest change that fixes the AppRun behavior and can be verified with focused tests.
- Do not add Tailwind, Vite, routing libraries, state libraries, or starter scaffolds unless the user specifically asks for them.
Core Architecture
- Treat AppRun code as MVU: model/state, view, update/event handlers.
- Keep update logic pure when possible; move side effects to explicit handlers.
- Return a new state when the UI must re-render.
- Return nothing only for side effects that should not re-render.
- Use async generators for multi-step flows that need intermediate renders, such as validation -> loading -> success/error.
- Keep view functions deterministic from state. Avoid hidden DOM reads unless integrating with browser APIs.
- Keep component state shapes specific to the component. Do not force generic
loading,error, orsuccessMessagefields into components that do not need them.
For detailed component patterns, read references/component-architecture.md.
Lifecycle Rules
- Use
mounted(props, children, state)for components embedded in JSX that need props-derived initial state. The hook also receives current children and state; return new state or nothing. - Use async
stateonly for top-level routed components that must load route-level data before rendering. - Do not mix
mounted()and asyncstatein the same component unless the existing code proves a deliberate local contract. - Preserve cleanup in the
unload(state)hook for timers, subscriptions, pending promises, animation frames, custom elements, and global listeners. - For async state, guard against stale promise completion when a newer state load has started.
Events And State
- Prefer AppRun directives for AppRun updates:
$bind,$onclick,$oninput, and sibling$on...directives. - Use
$bindfor simple form binding, including textarea value binding. - Use
$oninputor explicit handlers when validation, parsing, debouncing, or normalization is needed. - Do not wrap
$onclickaround an arrow function whose only job isapp.run(...); use AppRun event binding directly. - Use standard DOM events only for DOM-only effects, such as stopping propagation or integrating with browser APIs.
- Use global events deliberately. They are a coupling point, not a default.
- Keep event names domain-specific and behavior-specific.
For handler shapes and async examples, read references/events-and-state.md.
Routing And Navigation
- Use AppRun's existing routing behavior before adding any router abstraction.
- Preserve native browser behavior for links: modifier keys, new tabs, downloads, external URLs, and non-left clicks should not be hijacked.
- Register routed components in one clear place when the app structure allows it.
- Route params should be decoded and validated close to the route handler.
- Programmatic navigation is a side effect; make that explicit in update handlers.
For routing contracts and guard details, read references/routing-navigation.md.
AppRun Library Work
When modifying this repository rather than an app:
- Inspect
src/and the nearby tests before patching. - Preserve public API shape in
apprun.d.ts,esm/,dist/, and runtime exports unless the request is explicitly breaking. - Add focused regression tests for behavior fixes.
- Use existing Jest patterns in this repo.
- Run the smallest relevant test first, then the broader suite or build when behavior or public API changed.
For repo-specific verification expectations, read references/testing.md.
Reference Routing
- Read
references/component-architecture.mdfor component class/function choices, lifecycle, custom elements, and cleanup. - Read
references/events-and-state.mdfor update handler patterns, directives, async generators, and state transitions. - Read
references/routing-navigation.mdfor route registration, anchors, params, navigation side effects, and click guards. - Read
references/testing.mdfor AppRun test strategy, async generator tests, routing tests, and this repo's commands.
Non-Goals
- Do not teach generic TypeScript, Vite, webpack, Tailwind, CSS Modules, or fetch-client setup in this skill.
- Do not prescribe a directory layout unless the existing repository already has one or the user asks for a new app scaffold.
- Do not replace AppRun idioms with React, Redux, external routers, or framework conventions just because they are familiar.
- Do not turn examples from one app domain into reusable AppRun doctrine.