Builds Activepieces pieces (integrations) with actions and triggers. Use when the user asks to create a new piece, add actions to a piece, add triggers to a piece, or build an integration for a third-party app. Also use when the user mentions Activepieces pieces, connectors, or integration development.
Build pieces (integrations) for the Activepieces automation platform. Each piece provides actions (operations users can perform) and triggers (events that start flows).
Follow these 5 steps every time:
packages/pieces/custom/ (no need to ask)packages/pieces/community/npm run cli pieces create
# Enter: piece name, package name (@activepieces/piece-<name>), type (community)
npm run cli actions create
# Enter: piece folder name, action display name, description
npm run cli triggers create
# Enter: piece folder name, trigger display name, description, technique (polling/webhook)
Create this structure under packages/pieces/community/<name>/:
src/
index.ts
lib/
actions/ # One file per action
triggers/ # One file per trigger
common/ # Shared helpers (optional)
package.json
project.json
.eslintrc.json
tsconfig.json
tsconfig.lib.json
Copy config files from an existing simple piece (e.g. packages/pieces/core/qrcode/) and replace <name> throughout. Templates:
package.json
{
"name": "@activepieces/piece-<name>",
"version": "0.0.1",
"dependencies": {}
}
.eslintrc.json
{
"extends": ["../../../../.eslintrc.base.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], "rules": {} },
{ "files": ["*.ts", "*.tsx"], "rules": {} },
{ "files": ["*.js", "*.jsx"], "rules": {} }
]
}
tsconfig.json
{
"extends": "../../../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [{ "path": "./tsconfig.lib.json" }]
}
tsconfig.lib.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"rootDir": ".",
"baseUrl": ".",
"paths": {},
"outDir": "./dist",
"declaration": true,
"types": ["node"]
},
"include": ["src/**/*.ts"],
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
}
Read these files before writing any code:
| What you're implementing | Read this file |
|---|---|
| Auth setup | auth-patterns.md |
| Action structure | action-patterns.md |
| Trigger structure (polling or webhook) | trigger-patterns.md |
| Any props -- actions or triggers | props-patterns.md |
| HTTP client, shared helpers, pagination | common-patterns.md |
| Every prop and dropdown (mandatory for all) | ux-guidelines.md |
| Every return value (mandatory for all) | output-quality.md |
ux-guidelines.md and output-quality.md apply to every action and trigger -- read them before starting, not only when unsure.
src/index.ts and add to actions: [...]src/index.ts and add to triggers: [...]src/index.ts so actions/triggers can import it via import { myAppAuth } from '../../'createCustomApiCallAction to actions: [...] for power userstsconfig.base.json at the repo root (insert alphabetically):
"@activepieces/piece-<name>": ["packages/pieces/community/<name>/src/index.ts"]
Build fails without this step.bun install
npx turbo run build --filter=@activepieces/piece-<name>
bun install is required for new pieces so the workspace symlinks are created before TypeScript can resolve imports. Skip it on subsequent rebuilds.
Fix TypeScript errors and rebuild. Common causes: missing import in src/index.ts, missing tsconfig.base.json entry, wrong type cast on context.auth (use context.auth as unknown as string for SecretText), missing sampleData on a trigger.
Add to packages/server/api/.env:
AP_DEV_PIECES=<name>
Start the dev server (npm start), open localhost:4200, sign in with [email protected] / 12345678, and find your piece in the flow builder.
| Location | Purpose |
|---|---|
packages/pieces/community/ | Third-party integrations (Slack, Stripe, etc.) -- use this for almost all work |
packages/pieces/core/ | Built-in platform utilities (HTTP, Store, Math, etc.) -- do NOT recreate these |
packages/pieces/custom/ | Private customer-specific pieces |
Full reference: piece-types.md -- includes all PieceCategory values and the list of existing core pieces.
packages/pieces/community/<piece-name>/
src/
index.ts # Piece definition (auth + imports + createPiece)
lib/
actions/ # One file per action
triggers/ # One file per trigger
common/ # Shared API helpers and dropdown definitions
package.json
project.json
.eslintrc.json
tsconfig.json
tsconfig.lib.json
| API Auth Method | Activepieces Type | Access Pattern |
|---|---|---|
| API key / Bearer token | PieceAuth.SecretText() | context.auth (string) |
| OAuth2 | PieceAuth.OAuth2() | context.auth.access_token |
| Username + password | PieceAuth.BasicAuth() | context.auth.username, .password |
| Multiple fields | PieceAuth.CustomAuth() | context.auth.<field_name> |
| No auth needed | PieceAuth.None() | No context.auth available |
Full code examples: read auth-patterns.md
import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
import { createCustomApiCallAction } from '@activepieces/pieces-common';
import { PieceCategory } from '@activepieces/shared';
import { myAction } from './lib/actions/my-action';
import { myTrigger } from './lib/triggers/my-trigger';
export const myAppAuth = PieceAuth.SecretText({
displayName: 'API Key',
description: 'Go to Settings > API Keys in your dashboard to generate a key.',
required: true,
});
export const myApp = createPiece({
displayName: 'My App',
description: 'What the app does in one sentence.',
minimumSupportedRelease: '0.36.1',
// Logo: add a PNG to packages/pieces/community/<name>/ and reference it here.
logoUrl: 'https://cdn.activepieces.com/pieces/my-app.png',
categories: [PieceCategory.PRODUCTIVITY],
auth: myAppAuth,
authors: ['your-github-username'], // GitHub usernames of contributors
actions: [
myAction,
createCustomApiCallAction({
baseUrl: () => 'https://api.example.com/v1',
auth: myAppAuth,
authMapping: async (auth) => ({
Authorization: `Bearer ${auth}`,
}),
}),
],
triggers: [myTrigger],
// If the piece needs third-party npm packages, declare them here:
// npmDependencies: { 'some-sdk': '^1.0.0' },
});
Pieces are used by people who have never seen an API. Every prop, dropdown, and description must be clear enough to use without reading external docs.
Rules:
"Jane Doe ([email protected])" not "cus_abc123").Property.MarkDown() with numbered steps when a prop requires configuration in the third-party app."Create Contact" not "POST /contacts". Triggers: "New Order" not "order.created webhook"."Please select a project first" not just empty.Full patterns and examples: read ux-guidelines.md
Every action output must be directly mappable to Google Sheets, Excel, and Activepieces Tables. Users pipe piece outputs into spreadsheets constantly -- if your output is nested or inconsistent, it breaks their flows.
Rules:
{ user: { name: "Jo", email: "[email protected]" } } into { user_name: "Jo", user_email: "[email protected]" }.company_name not cName. These become column headers.Full patterns and examples: read output-quality.md
compilerOptions.paths. Build fails without this.name field in createAction/createTrigger must never change after publishing.import { myAppAuth } from '../../'.{}.Always pause and ask if: