| name | bubble-components-pubsub |
| description | Comprehensive Bubble skill for component/page authoring, props-emits wiring, router usage, and pub-sub topic lifecycle patterns. Always apply for files ending in .bub.js or .bubble.js. Use for frontend Bubble tasks; skip for backend-only changes. |
| license | MIT |
| metadata | {"author":"card-room","tags":"bubble, components, props, emits, pubsub, router, sfc"} |
Bubble Components + PubSub
Canonical Bubble patterns for this repository, with GitHub-first references and local integration rules.
Overview
This skill is optimized for two recurring task families:
- Building or refactoring Bubble SFC-style components/pages.
- Wiring app events via Bubble pub-sub (
bubble.events.topic(...)) with stable lifecycle handling.
Use this skill to avoid regressions around props behavior and topic listener leaks.
Skill Format
This skill uses progressive disclosure:
SKILL.md = routing and decision layer.
references/*.md = deep implementation guides.
scripts/*.sh = optional audits you can run quickly.
When To Apply
Apply when the request involves any of:
- New Bubble component/page creation.
- Child component registration with props/emits.
- Fixing old
this.props.foo.value usage.
- Adding or refactoring game/session event listeners.
- Bubble router setup or route updates.
Automatic trigger rules:
- Always activate this skill when the task touches files ending with
.bub.js.
- Always activate this skill when the task touches files ending with
.bubble.js.
Do not apply when:
- Task is server-only (Express/TS/socket backend without Bubble UI integration).
- Task is unrelated to Bubble runtime behavior.
Sources (GitHub first)
Primary source of truth:
- Repo root:
https://github.com/antocorr/bubble/
- Framework source:
https://github.com/antocorr/bubble/tree/main/src
- Examples:
https://github.com/antocorr/bubble/tree/main/examples
- Prompt baseline:
https://github.com/antocorr/bubble/blob/main/ai-component-creation-prompt.md
Priority Map
| Priority | Area | Risk | Reference |
|---|
| 1 | Props model correctness | High | references/props-emits.md |
| 2 | Pub-sub listener lifecycle | High | references/pubsub-lifecycle.md |
| 3 | Component authoring conventions | Medium | references/components-core.md |
| 4 | Router wiring and route data | Medium | references/router-patterns.md |
| 5 | Legacy migration checks | Medium | references/migration-checks.md |
Default Rules
- Component shape
- Export plain object with
name, template(), data(), methods.
template() returns one root element.
- Add
/* html */ above template literals.
- Caveat: do not use
x-if on the root element of custom Bubble components.
- Caveat 2: WORK IN PROGRESS but as of today you can either use class="" or :class=""
Use
x-show on root, or apply x-if in the parent around the component tag.
- Reactive state
- Read/write component state with
this._data.key.value.
- Arrays/objects in signal values can be mutated through
.value proxy.
- Props behavior (critical)
- In component JS:
this.props.foo is raw value.
- Never use
this.props.foo.value.
- In templates: props are available by key (
{{ foo }}), not {{ props.foo }}.
- Emits contract
- Child declares
emits: ["eventName"].
- Child emits with
this.emit("eventName", payload).
- Parent listens with
@eventName="handler".
- Pub-sub contract
- Use
bubble.events.topic("name"), not bubble.topic("name").
- Keep stable handler refs on
this and .off previous before .on in init().
- Attribute bindings (critical)
attr="{{signal}}" does NOT work for reactive attribute binding. Mustache interpolation is for text content only.
- Always use
:attr="expression" to bind a reactive value to an HTML attribute.
- Correct:
:src="imageUrl", :disabled="isLoading", :class="activeClass".
- Wrong:
src="{{imageUrl}}", disabled="{{isLoading}}".
{{ }} interpolation remains valid inside text nodes (e.g. <p>{{ count }}</p>).
Rapid Workflow
- Classify task: component | props/emits | pubsub | router | migration.
- Open relevant reference file(s) below.
- Apply minimal scoped changes aligned with existing style.
- Run script audit (optional):
bash .agents/skills/bubble-components-pubsub/scripts/audit-bubble-patterns.sh.
- If touching docs/prompts/examples, keep props guidance aligned with runtime.
References
- Core authoring:
references/components-core.md
- Props and emits:
references/props-emits.md
- Pub-sub lifecycle:
references/pubsub-lifecycle.md
- Router patterns:
references/router-patterns.md
- Migration checks:
references/migration-checks.md
- Source map (GitHub/local):
references/source-map.md
Problem -> Reference Mapping
| Problem | Start with |
|---|
| Child prop does not update / wrong value shape | references/props-emits.md |
| Event handlers duplicate after re-init | references/pubsub-lifecycle.md |
| New page/component scaffold needed | references/components-core.md |
| Route data/props not reaching component | references/router-patterns.md |
| Legacy code still using old patterns | references/migration-checks.md |
Quality Gate
Before finalizing Bubble-related edits:
- No
this.props.*.value remains.
- No
attr="{{signal}}" patterns in HTML attributes; use :attr="expression" instead.
- No mixed topic APIs (
bubble.topic vs bubble.events.topic) in touched files.
- Event listeners are attached with stable handler refs and detached before re-attach.
- Templates keep one root and use directives idiomatically.