| name | create-bubble |
| description | Create a new Bubble integration for Bubble Lab following all established patterns and best practices from CREATE_BUBBLE_README.md |
| argument-hint | <service-name> [multi-operation] |
| disable-model-invocation | true |
Create Bubble Skill
Create a new Bubble integration for: $ARGUMENTS
Follow the CREATE_BUBBLE_README.md guide at packages/bubble-core/CREATE_BUBBLE_README.md exactly.
Step 1: Gather Requirements
Before writing any code, ask the user:
- Service name: What external service is this integrating with?
- Operations: What operations should this bubble support? (single or multiple)
- Authentication: What auth type? (
none, apikey, oauth, basic)
- Credentials: What credential types are needed? (API key, access token, etc.)
Step 2: Create Folder Structure
All bubbles use this folder structure in packages/bubble-core/src/bubbles/service-bubble/{service-name}/:
{service-name}/
├── {service-name}.schema.ts # All Zod schemas
├── {service-name}.utils.ts # Utility functions (optional)
├── {service-name}.ts # Main bubble class
├── index.ts # Exports
├── {service-name}.test.ts # Unit tests
└── {service-name}.integration.flow.ts # Integration flow test
Step 3: Create Schema File ({service-name}.schema.ts)
Include:
- Parameter schema with
.describe() on ALL fields
- Result schema with
success and error fields
- Both INPUT and OUTPUT type exports
- Use
z.discriminatedUnion() for multi-operation bubbles
- Use
z.transform() over z.preprocess() for type preservation
- Always include
credentials field
Step 4: Create Main Bubble Class ({service-name}.ts)
Required static properties:
service, authType, bubbleName, type, schema, resultSchema
shortDescription, longDescription, alias
Use INPUT type for generic constraint:
export class {ServiceName}Bubble<
T extends {ServiceName}ParamsInput = {ServiceName}ParamsInput,
> extends ServiceBubble<T, Extract<{ServiceName}Result, { operation: T['operation'] }>>
Implement:
constructor with default values
chooseCredential() method
performAction() method with operation switch
Step 5: Create Index File (index.ts)
Export the bubble class and types.
Step 6: Create Integration Flow Test ({service-name}.integration.flow.ts)
Integration flow tests are complete BubbleFlow workflows that exercise all bubble operations end-to-end.
Requirements:
- Exercise all or most operations of your bubble
- Include edge cases (special characters, spaces in names, unicode)
- Test null/undefined handling in data
- Return structured results tracking each operation's success/failure
- Use realistic data and scenarios
Template structure:
import { BubbleFlow, {ServiceName}Bubble, type WebhookEvent } from '@bubblelab/bubble-core';
export interface Output {
resourceId: string;
testResults: {
operation: string;
success: boolean;
details?: string;
}[];
}
export interface TestPayload extends WebhookEvent {
testName?: string;
}
export class {ServiceName}IntegrationTest extends BubbleFlow<'webhook/http'> {
async handle(payload: TestPayload): Promise<Output> {
const results: Output['testResults'] = [];
const result1 = await new {ServiceName}Bubble({
operation: 'operation_name',
}).action();
results.push({
operation: 'operation_name',
success: result1.success,
details: result1.success ? `Success details` : result1.error,
});
return {
resourceId: result1.data?.id || '',
testResults: results,
};
}
}
Reference: See packages/bubble-core/src/bubbles/service-bubble/google-sheets/google-sheets.integration.flow.ts for a complete implementation.
Step 7: Complete Registration Checklist
You MUST update these 12 locations:
-
Credential Types - packages/bubble-shared-schemas/src/types.ts
- Add new
CredentialType enum values
-
Credential Configuration Map - packages/bubble-shared-schemas/src/bubble-definition-schema.ts
- Add to
CREDENTIAL_CONFIGURATION_MAP
-
Credential Environment Mapping - packages/bubble-shared-schemas/src/credential-schema.ts
- Add to
CREDENTIAL_ENV_MAP
-
Frontend Credential Configuration - apps/bubble-studio/src/pages/CredentialsPage.tsx
- Add to
CREDENTIAL_TYPE_CONFIG
- Add to
typeToServiceMap
-
Bubble-to-Credential Mapping - packages/bubble-shared-schemas/src/credential-schema.ts
- Add to
BUBBLE_CREDENTIAL_OPTIONS
-
Bubble Name Type Definition - packages/bubble-shared-schemas/src/types.ts
-
Backend Credential Test Parameters - apps/bubblelab-api/src/services/credential-validator.ts
- Add to
createTestParameters method with ALL required parameters
-
System Credential Auto-Injection (optional) - apps/bubblelab-api/src/services/bubble-flow-parser.ts
- Add to
SYSTEM_CREDENTIALS if needed
-
Bubble Factory Registration - packages/bubble-core/src/bubble-factory.ts
- Import and register the bubble
- Add to boilerplate imports
-
Code Generator List - packages/bubble-core/src/bubble-factory.ts
- Add to
listBubblesForCodeGenerator()
-
Main Package Export - packages/bubble-core/src/index.ts
- Export bubble class and types
-
Logo Integration (optional) - apps/bubble-studio/src/lib/integrations.ts
- Add to
SERVICE_LOGOS, INTEGRATIONS, NAME_ALIASES, and matchers
Step 8: Verification
Run these commands to verify:
pnpm run typecheck
pnpm run build
Quality Checklist
Before completing, ensure:
Key Patterns to Follow
Type Safety:
- Use INPUT type (
z.input<>) for generic constraints and constructor
- Use OUTPUT type (
z.output<>) for internal methods after validation
- Cast
this.params as {ServiceName}Params inside performAction()
Schema Best Practices:
- Use
z.transform() to preserve input types in discriminated unions
- Use
z.preprocess() only when accepting unknown/null/undefined inputs
- All fields MUST have
.describe() calls
- Provide sensible defaults with
.optional().default(value)
Error Handling:
- Return
{ success: false, error: message } format
- Catch and wrap errors appropriately
Reference Implementations
Study these existing bubbles for patterns:
- Multi-operation:
packages/bubble-core/src/bubbles/service-bubble/google-sheets/
- Single operation:
packages/bubble-core/src/bubbles/service-bubble/ai-agent/
- Tool bubble:
packages/bubble-core/src/bubbles/tool-bubble/