As this project's AI coding tool, you must follow the additional conventions below, in addition to the built-in functions.
Ripple is a TypeScript-first UI framework and monorepo maintained by Dominic
Gannaway. This repository owns the Ripple runtime, Ripple-specific compiler
target, adapters, scaffolding, and framework integrations. The shared .tsrx
language, compiler core, non-Ripple targets, language tooling, editor plugins, and
syntax grammars are maintained in
tsrx-org/tsrx.
Use the nearest live source rather than historical summaries:
website/public/llms.txtfor Ripple runtime APIs, target behavior, and Ripple-specific authoring guidance- tsrx.dev for target-neutral TSRX syntax, tooling, and the language specification
README.mdfor the Ripple overview, positioning, and quick-start examplespackages/*/README.mdfor package-specific usage and public APIsvitest.config.jsfor the current Ripple test projects and file globspackage.jsonfor workspace-wide scripts such asrules:generate,test,format,format:check, andtypecheck
If a guide conflicts with nearby code or package READMEs, trust the nearby code and current package docs.
This repository contains only Ripple-owned source:
packages/ripple/: runtime, DOM behavior, hydration, SSR, reactivity, types, and server helperspackages/tsrx-ripple/: the Ripple-specific@tsrx/ripplecompiler targetpackages/vite-plugin/andpackages/rollup-plugin/: Ripple bundler integrationspackages/adapter/,packages/adapter-node/,packages/adapter-bun/, andpackages/adapter-vercel/: deployment and platform adapterspackages/cli/,packages/create-ripple/, andtemplates/: Ripple scaffoldingplayground/ripple/,benchmarks/,website/, andwebsite-new/: Ripple examples, performance work, and documentation
Shared @tsrx/* packages are registry dependencies. Do not recreate moved
compiler, formatter, linter, language-server, grammar, editor-plugin, or
non-Ripple target source here. Route changes in those areas to tsrx-org/tsrx;
update Ripple only when its target integration must adapt.
The intended dependency direction is Ripple -> published TSRX packages. Do not add
a workspace link, Git dependency, or copied source that reverses that boundary.
@tsrx/ripple is the deliberate exception in package naming: its source and
publishing authority remain in this repository because it implements Ripple
runtime semantics.
This repository uses RuleSync as the single source of truth for shared AI agent
instructions. Edit .rulesync/rules/ and regenerate derived files instead of
patching generated outputs directly.
Generated targets include:
AGENTS.md.github/copilot-instructions.mdCLAUDE.mdGEMINI.md.cursor/rules/project.mdc
After changing RuleSync content, run:
pnpm rules:generate- Default component files are
.tsrx. Do not describe the project as primarily using.ripplefiles unless the local historical context requires it. - Prefer the current TSRX component shape:
function Component(props) @{ ... }when setup and output share a scope, orfunction Component(props) { return <div />; }for simple single-root output. - TSRX templates use JSX-shaped elements, fragments, text, expression containers, and directive control flow. Do not introduce removed experimental template-boundary or legacy component syntaxes in new examples.
- When a template scope mixes TypeScript setup with rendered output, setup statements come first and the scope finishes with one output node: a JSX element, JSX fragment, or JSX control-flow expression. Wrap text, expression containers, or multiple siblings in a fragment when they are the output after setup.
- Use
@if,@for,@switch, and@tryfor template control flow. Plain JavaScript control flow remains ordinary setup code. - A
<style>block is scoped to its siblings: it styles the elements beside it and everything below them, never the element that contains it. Put the block and its markup side by side in a fragment or element, inside a@{ ... }body or a control-flow branch. Blocks among the same children share one hash; nested children lists with blocks are nested scopes. Assign a block to a variable for a theme (theme.$class,<style apply={theme} />) or class map; raw CSS in a<style>inside a plainreturn <div />function is an error. - Share context across files by exporting one
Contextinstance from a shared module and importing it in providers and consumers, or passing the same instance as a prop. Call.set()and.get()during component initialization; event handlers can mutate tracked values stored in the context. For shared updates, provide a store object once in a common ancestor and update its reactive properties. A child's.set()overrides the provided value for its subtree; it does not update the value held by ancestors or sibling branches. Seewebsite/docs/guide/state-management.mdfor examples. - Use
pnpmfor all package management and workspace scripts. - Follow the conventions of the package you are changing. This repo mixes plain JavaScript, JSDoc-typed JavaScript, and TypeScript depending on package.
- Match nearby naming, file layout, and test style instead of applying a single convention repo-wide.
- Ripple compiler lowering, analysis, or target semantics:
packages/tsrx-ripple/ - Ripple runtime behavior, hydration, reactivity, DOM updates, or server output:
packages/ripple/ - Ripple Vite, Rollup, or adapter behavior: the relevant retained package under
packages/ - Ripple project generation:
packages/cli/,packages/create-ripple/, andtemplates/ - Target-neutral TSRX parsing, diagnostics, formatting, linting, language-server
behavior, editor integration, or non-Ripple targets:
tsrx-org/tsrx
Prefer the smallest validation that covers the touched surface.
Common workspace commands:
pnpm rules:generate
pnpm format:check
pnpm test
pnpm test --project ripple-client
pnpm test --project ripple-server
pnpm test --project ripple-hydration
pnpm test --project tsrx-ripple
pnpm typecheck
pnpm changeset:checkRipple runtime suites use .test.tsrx files for many client, server, and
hydration tests. Tooling packages often use .test.js files.
Add a changeset for user-facing package changes. Skip changesets for docs-only, test-only, and internal tooling updates.
Use patch changesets for ordinary changes. Reserve minor for a breaking change
such as removed syntax or a removed public API, and never use major until a
release plan explicitly changes that policy. Peer-dependency bumps only patch
their dependents (@changesets/cli 3), so a minor on ripple never cascades
into a major.
pnpm changeset
pnpm changeset:checkChangesets discovers publishable packages from the pnpm workspace. Keep
non-publishable projects marked private: true, and use .changeset/config.json
for release grouping and temporary ignores. @tsrx/ripple remains the sole
@tsrx-scoped package published from this repository.
- Prefer Ripple docs in
website/public/llms.txtand target-neutral guidance attsrx.devover stale architectural summaries. - Treat
@tsrx/coreand generic tooling as external published dependencies, including in tests and examples. - Avoid copying removed compiler APIs, old package layouts, or legacy
.rippleexamples into new guidance. - If exact behavior is unclear, read the owning retained package and its tests.
- Keep documentation updates short and durable. High-level guidance ages better than detailed internal call lists.