N8n Conventions
This skill provides a quick reference guide to n8n's coding conventions, best practices, and architectural patterns.
Install
npx promptshop add n8n-conventionsDetails
What This Skill Does
This skill provides a quick reference guide to n8n's coding conventions, best practices, and architectural patterns. It covers Type
Script, error handling, frontend development with Vue 3, backend structure, testing, database usage, and common commands. It's designed for n8n developers who need a fast reminder of critical rules and patterns.
When to Use
Quickly check Type
- Script best practices.
- Review error handling conventions.
- Find frontend development guidelines.
- Understand backend architecture.
- Check testing procedures.
- Find common commands.
Key Features
Type
Script best practices (any, satisfies).Error handling with Unexpected
Error. Vue 3 Composition A
PI guidelines. C
- SS variable usage.
- Backend Controller โ Service โ Repository pattern.
- Testing with Vitest and Playwright.
Manual Installation
Manual installation
View Full Skill Content
The complete markdown content that gets installedn8n Quick Reference
๐ Full Documentation: General: /A
GENTS.md - Architecture, commands, workflows Frontend: /packages/frontend/A
GENTS.md - C
SS variables, timing
Use this skill when you need quick reminders on critical patterns.
Critical Rules (Must Follow)
Type
Script: Never any โ use unknown Prefer satisfies over as (except tests) Shared types in @n8n/api-types
Error Handling: import { Unexpected
Error } from 'n8n-workflow'; throw new Unexpected
Error('message', { extra: { context } }); // D
ON'T use deprecated Application
Error
Frontend: Vue 3 Composition A
PI (</code>)</li>
<li>CSS variables (never hardcode px) - see <code>/packages/frontend/A
GENTS.md</code></li>
<li>All text via i18n (<code>$t('key')</code>)</li> <li><code>data-testid</code> for E2E (single value, no spaces)</li> </ul> <p><strong>Backend:</strong></p> <ul><li>Controller โ Service โ Repository</li> <li>Dependency injection via <code>@n8n/di</code></li> <li>Config via <code>@n8n/config</code></li> <li>Zod schemas for validation</li> </ul> <p><strong>Testing:</strong></p> <ul><li>Vitest (unit), Playwright (E2E)</li> <li>Mock external dependencies</li> <li>Work from package directory: <code>pushd packages/cli && pnpm test</code></li> </ul> <p><strong>Database:</strong></p> <ul><li>SQLite/Postgre
SQL only (app DB)</li>
<li>Exception: DB nodes (MySQL Node, etc.) can use DB-specific features</li>
</ul> <p><strong>Commands:</strong></p> <pre><code class="language-bash">pnpm build > build.log 2>&1 # Always redirect <p>pnpm typecheck # Before commit</p> <p>pnpm lint # Before commit</code></pre></p> <h2>Key Packages</h2> <p>| Package | Purpose |</p> <p>|---------|---------|</p> <p>| <code>packages/cli</code> | Backend API |</p>
<p>| <code>packages/frontend/editor-ui</code> | Vue 3 frontend |</p> <p>| <code>packages/@n8n/api-types</code> | Shared types |</p> <p>| <code>packages/@n8n/db</code> | TypeORM entities |</p>
<p>| <code>packages/workflow</code> | Core interfaces |</p> <h2>Common Patterns</h2> <p><strong>Pinia Store:</strong></p> <pre><code class="language-typescript">import { STORES } from '@n8n/stores';
<p>export const useMyStore = define
Store(S
TORES.M
Y_STORE, () => {</p>
<p> const state = shallowRef([]);</p>
<p> return { state };</p> <p>});</code></pre></p> <p><strong>Vue Component:</strong></p> <pre><code class="language-vue"><script setup lang="ts"> <p>type Props = { title: string };</p> <p>const props = defineProps<Props>();</p>
<p></script></code></pre></p> <p><strong>Service:</strong></p> <pre><code class="language-typescript">import { Service } from '@n8n/di'; <p>import { Config } from '@n8n/config';</p> <p>@Service()</p> <p>export class MyService {</p>
<p> constructor(private readonly config: Config) {}</p> <p>}</code></pre></p> <hr> <p>๐ <strong>Need more details?</strong> Read <code>/AGENTS.md</code> and <code>/packages/frontend/A
- GENTS.md</code></p></div></div></div></details></div><div class="sr-only" aria-hidden="true"><div class="max-w-none overflow-hidden"><div class="skill-content [&_pre]:bg-muted [&_code]:bg-muted [&_hr]:border-border [&_blockquote]:border-border [&_blockquote]:text-muted-foreground [&_a]:text-primary [&_th]:border-border [&_th]:bg-muted [&_td]:border-border [&_a]:text-sm [&_a]:underline [&_blockquote]:border-l-4 [&_blockquote]:pl-4 [&_blockquote]:text-sm [&_blockquote]:italic [&_code]:break-all [&_code]:rounded [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-xs [&_h1]:mb-4 [&_h1]:text-2xl [&_h1]:font-semibold [&_h2]:mb-3 [&_h2]:mt-8 [&_h2]:text-xl [&_h2]:font-semibold [&_h3]:mb-2 [&_h3]:mt-6 [&_h3]:text-lg [&_h3]:font-medium [&_hr]:my-6 [&_li]:mb-1 [&_ol]:mb-3 [&_ol]:list-decimal [&_ol]:pl-6 [&_ol]:text-sm [&_p]:mb-3 [&_p]:text-sm [&_p]:leading-relaxed [&_pre]:mb-4 [&_pre]:max-w-full [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:p-4 [&_pre]:text-xs [&_pre_code]:break-normal [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_strong]:font-semibold [&_table]:w-full [&_table]:border-collapse [&_table]:text-sm [&_td]:border [&_td]:px-3 [&_td]:py-2 [&_th]:border [&_th]:px-3 [&_th]:py-2 [&_th]:text-left [&_ul]:mb-3 [&_ul]:list-disc [&_ul]:pl-6 [&_ul]:text-sm"><h1>n8n Quick Reference</h1>.
GENTS.md</code> - Architecture, commands, workflows</li>
<li><strong>Frontend:</strong> <code>/packages/frontend/AGENTS.md</code> - C
SS variables, timing</li>
</ul> <p>Use this skill when you need quick reminders on critical patterns.</p> <h2>Critical Rules (Must Follow)</h2> <p><strong>TypeScript:</strong></p>
<ul><li>Never <code>any</code> โ use <code>unknown</code></li> <li>Prefer <code>satisfies</code> over <code>as</code> (except tests)</li> <li>Shared types in <code>@n8n/api-types</code></li> </ul> <p><strong>Error Handling:</strong></p> <pre><code class="language-typescript">import { UnexpectedError } from 'n8n-workflow';
<p>throw new UnexpectedError('message', { extra: { context } });</p>
<p>// DON'T use deprecated Application
Error</code></pre></p>
<p><strong>Frontend:</strong></p> <ul><li>Vue 3 Composition API (<code><script setup lang="ts"></code>)</li>
<li>CSS variables (never hardcode px) - see <code>/packages/frontend/A
GENTS.md</code></li>
<li>All text via i18n (<code>$t('key')</code>)</li> <li><code>data-testid</code> for E2E (single value, no spaces)</li> </ul> <p><strong>Backend:</strong></p> <ul><li>Controller โ Service โ Repository</li> <li>Dependency injection via <code>@n8n/di</code></li> <li>Config via <code>@n8n/config</code></li> <li>Zod schemas for validation</li> </ul> <p><strong>Testing:</strong></p> <ul><li>Vitest (unit), Playwright (E2E)</li> <li>Mock external dependencies</li> <li>Work from package directory: <code>pushd packages/cli && pnpm test</code></li> </ul> <p><strong>Database:</strong></p> <ul><li>SQLite/Postgre
SQL only (app DB)</li>
<li>Exception: DB nodes (MySQL Node, etc.) can use DB-specific features</li>
</ul> <p><strong>Commands:</strong></p> <pre><code class="language-bash">pnpm build > build.log 2>&1 # Always redirect <p>pnpm typecheck # Before commit</p> <p>pnpm lint # Before commit</code></pre></p> <h2>Key Packages</h2> <p>| Package | Purpose |</p> <p>|---------|---------|</p> <p>| <code>packages/cli</code> | Backend API |</p>
<p>| <code>packages/frontend/editor-ui</code> | Vue 3 frontend |</p> <p>| <code>packages/@n8n/api-types</code> | Shared types |</p> <p>| <code>packages/@n8n/db</code> | TypeORM entities |</p>
<p>| <code>packages/workflow</code> | Core interfaces |</p> <h2>Common Patterns</h2> <p><strong>Pinia Store:</strong></p> <pre><code class="language-typescript">import { STORES } from '@n8n/stores';
<p>export const useMyStore =