Complete assistance for Vendure development, generated from the official documentation (docs.vendure.io).
When to use this Skill
Trigger this skill for:
- Building headless e-commerce applications with Node.js/TypeScript
- Working with GraphQL APIs for products, orders or customer management
- Implementing payment integrations (Stripe, custom handlers)
- Creating custom plugins or extending Vendure functionality
- Configuring order workflows and state machines
- Developing Dashboard extensions with React
- Configuring multi-currency stores or multi-channel stores
- Debugging Vendure code or resolving e-commerce issues
- Learning Vendure best practices for TypeScript development
Key Concepts
Fundamental concepts of Vendure architecture:
- Order State Machine - Customizable workflow (AddingItems → Delivered) via OrderProcess with interceptors
- Custom Fields - Add properties to entities via VendureConfig, automatic extension of the GraphQL schema, support for relations and 10+ field types
- Plugins - Extensibility via the @VendurePlugin decorator, lifecycle hooks, InjectableStrategy pattern for pluggable behavior
Navigation Guide
This skill is organized into 3 main sections for optimal navigation:
📚 references/Guides/ - Practical Guides (~16,000 lines)
| File | Lines | Content | When to consult |
|---|---|---|---|
getting-started.md |
619 | Installation, project creation, first steps | Starting a project |
developer-guide.md |
5,247 | Architecture, API Layer, Middleware, NestJS | Understanding the architecture |
core-concepts.md |
1,502 | Collections, Money, Assets, Taxes, Payment | Fundamental concepts |
extending-the-dashboard.md |
2,362 | React extensions, routes, custom pages | Customizing the admin |
how-to.md |
2,880 | Custom fields, payments, shipping calculators | Specific tutorials |
storefront.md |
1,618 | Next.js, Remix, API connection, starters | Creating a storefront |
deployment.md |
1,145 | Docker, production, security, HardenPlugin | Deploying to production |
user-guide.md |
473 | Using Dashboard for administrators | Training users |
migrating-from-v1.md |
302 | Breaking changes, v1→v2 migration guide | Version migration |
Useful grep commands:
grep -n "OrderProcess" references/Guides/developer-guide.md
grep -n "Custom Fields" references/Guides/how-to.md
grep -n "Collections" references/Guides/core-concepts.md
📖 references/reference/ - API Documentation (~39,000 lines)
| File | Lines | Content | When to consult |
|---|---|---|---|
typescript-api.md |
21,561 | ALL : Classes, interfaces, strategies, services | TypeScript API Reference |
admin-ui-api.md |
5,712 | Angular API (deprecated), legacy components | Maintain Angular code |
core-plugins.md |
4,527 | EmailPlugin, AssetServerPlugin, HardenPlugin, etc. | Configure official plugins |
dashboard.md |
3,585 | React hooks, Dashboard components, extensions | Develop React extensions |
graphql-api.md |
4,078 | Shop API, Admin API, queries, mutations | GraphQL queries |
reference.md |
35 | Section index/overview | Overview |
Key file: typescript-api.md - Contains ALL Vendure interfaces and classes.
Useful grep commands:
grep -n "^# " references/reference/typescript-api.md | head -50 # Liste des sections
grep -n "PaymentMethodHandler" references/reference/typescript-api.md
grep -n "OrderService" references/reference/typescript-api.md
grep -n "useDetailPage" references/reference/dashboard.md
🎨 references/UI/ - React Dashboard Components (~4,500 lines)
NEW SECTION - UI components for Dashboard extensions
| File | Lines | Components | When to consult |
|---|---|---|---|
ui.md |
1,315 | 42 components: Button, Dialog, Card, Badge, Popover, Tabs... | Basic UI elements |
form-inputs.md |
1,082 | 11 components: TextInput, SelectInput, CheckboxInput, DatePicker... | Forms |
layout.md |
862 | DetailPage, ListPage, PageLayout, TabsLayout | Page structure |
framework.md |
516 | DataTable, AssetGallery, PaginationControls | Data display |
VENDURE_UI_COMPONENTS_BASE.md |
724 | Basic component documentation | Quick reference |
Standard import:
import { Button, Card, Dialog, Badge } from "@vendure/dashboard";
import { TextInput, SelectInput } from "@vendure/dashboard";
import { DetailPage, ListPage } from "@vendure/dashboard";
Useful grep commands:
grep -A 20 "^## Button" references/UI/ui.md
grep -A 30 "TextInput" references/UI/form-inputs.md
grep -n "DetailPage" references/UI/layout.md
Workflows by Level
🟢 Beginner - First project
- Get started →
references/Guides/getting-started.md - Understand →
references/Guides/core-concepts.md(Money, Collections) - Build →
references/Guides/how-to.md - Explore → GraphQL Playground at
/shop-api
🟡 Intermediate - Custom features
- Search API →
references/reference/typescript-api.md - Create plugins →
references/Guides/developer-guide.md - Payments →
references/reference/core-plugins.md(StripePlugin) - Emails →
references/reference/core-plugins.md(EmailPlugin)
🔴 Advanced - Architecture & Production
- Architecture →
references/Guides/developer-guide.md(API Layer, Middleware) - Custom dashboard →
references/UI/+references/Guides/extending-the-dashboard.md - Security →
references/Guides/deployment.md(HardenPlugin, OWASP) - Performance → State machines, caching, optimizations
Quick Links by Task
| Task | Reference file |
|---|---|
| Start a project | Guides/getting-started.md |
| Display prices | Guides/core-concepts.md |
| Accept payments | reference/core-plugins.md |
| Send emails | reference/core-plugins.md |
| Create a plugin | Guides/developer-guide.md |
| File upload | Guides/developer-guide.md |
| Validate orders | reference/typescript-api.md |
| GraphQL queries | reference/graphql-api.md |
| Store prices | Guides/core-concepts.md |
| Install Dashboard | Guides/getting-started.md |
| Create Dashboard page | UI/layout.md + Guides/extending-the-dashboard.md |
| Form components | UI/form-inputs.md |
| DataTable | UI/framework.md |
Navigation Tips
Search in files
# Trouver une classe/interface
grep -rn "PaymentMethodHandler" references/
# Trouver un hook React
grep -rn "useDetailPage" references/reference/
# Trouver un composant UI
grep -n "Button" references/UI/ui.md
# Lister les sections d'un fichier
grep -n "^## " references/reference/typescript-api.md | head -30
Path structure
references/
├── Guides/ # Tutoriels et guides pratiques
│ ├── getting-started.md
│ ├── developer-guide.md
│ ├── core-concepts.md
│ ├── extending-the-dashboard.md
│ ├── how-to.md
│ ├── storefront.md
│ ├── deployment.md
│ ├── user-guide.md
│ └── migrating-from-v1.md
├── reference/ # Documentation API technique
│ ├── typescript-api.md # ⭐ Le plus important (21k lignes)
│ ├── core-plugins.md
│ ├── dashboard.md
│ ├── graphql-api.md
│ ├── admin-ui-api.md
│ └── reference.md
└── UI/ # Composants Dashboard React
├── ui.md # 42 composants UI
├── form-inputs.md # 11 composants formulaire
├── layout.md # Pages et layouts
├── framework.md # DataTable, etc.
└── VENDURE_UI_COMPONENTS_BASE.md
Additional Resources
scripts/
Utility scripts for interacting with Vendure GraphQL APIs.
Prerequisites
curl- HTTP requestsjq- JSON manipulationbash5+ - Required for associative arrays (macOS:brew install bash)
Available scripts
| Script | Description |
|---|---|
login.sh |
Authentication and help with curl requests |
query.sh |
Simplified execution of GraphQL requests |
login.sh - Authentication and curl help
Authentication script to obtain a JWT token and facilitate curl requests.
| Option | Alias | Description |
|---|---|---|
--from-last |
-l |
Uses last-account.json |
--superadmin |
-s |
Superadmin mode |
--email |
-e |
Login email |
--password |
-p |
Password |
--env |
-E |
.env path |
--export |
-x |
Displays shell exports |
--curl-example |
-c |
Full curl example |
--quiet |
-q |
Silent mode |
--verbose |
-v |
Verbose mode |
./login.sh -l # Login avec last-account.json
./login.sh -l -c # Affiche exemple curl complet
./login.sh -l -x # Affiche exports shell
./login.sh -s -E /path/.env # Login superadmin
./login.sh -e x@y.com -p z # Login manuel
./login.sh -l -q # Mode silencieux (scripts)
query.sh - Simplified GraphQL requests
| Option | Alias | Description |
|---|---|---|
--vars |
-V |
GraphQL JSON variables (replaces everything) |
--set |
- | Modify a variable (jq merge) |
--file |
-f |
.graphql file |
--superadmin |
-s |
Superadmin mode |
--env |
-e |
.env path |
--raw |
-r |
Raw JSON output |
--data |
-d |
Displays only .data |
--clear-cache |
-c |
Force reconnection |
--timeout |
-t |
Timeout in seconds |
--history |
-H |
Displays the last 10 requests |
--last |
-L |
Re-runs the last request |
--replay N |
-R |
Re-runs request #N from history |
--inspect N |
-I |
Displays query #N + variables (without executing) |
--save NAME |
-S |
Saves to queries/NAME.graphql |
--shop |
-p |
Uses /shop-api instead of /admin-api |
--time |
-T |
Displays execution time |
--diff "OPTS" |
- | Compares 2 executions (before/after OPTS) |
--diff-only |
- | With --diff: displays only changed values |
--no-fail |
- | Do not exit 1 on GraphQL error (continue despite errors) |
--dry-run |
- | Displays the request without executing it (no auth) |
--curl |
- | Generates the equivalent curl command (copy-paste) |
--jq FILTER |
-j |
Apply a jq filter to the result |
--assert EXPR |
-a |
Validate a jq condition (exit 1 if false) |
--quiet |
-q |
Silent mode (suppresses all stderr logs) |
--output FILE |
-o |
Write the result to a file |
--verbose |
-v |
Verbose mode |
./query.sh '{ me { id } }' # Requête simple
./query.sh -d '{ me { id } }' # Affiche seulement .data
./query.sh -s -e /path/.env '{ administrators { totalItems } }'
./query.sh -c '{ me { id } }' # Force reconnexion
./query.sh -t 60 '{ me { id } }' # Timeout 60s (défaut: 30s)
./query.sh -s -c -d '{ me { id } }' # Combinaison d'alias
# Historique et Replay (50 requêtes max, style Burp Repeater)
./query.sh -H # Affiche les 10 dernières
./query.sh -I 3 # Inspecte query #3 + variables (sans exécuter)
./query.sh -L # Ré-exécute la dernière
./query.sh -L -s # Dernière requête en superadmin
./query.sh -R 3 # Ré-exécute la requête #3
./query.sh -R 3 -s # Requête #3 en superadmin
./query.sh -R 3 --vars '{"take": 5}' # Requête #3 avec variables remplacées
./query.sh -R 3 --shop # Requête #3 sur shop-api
./query.sh -R 3 -T # Requête #3 avec timing
# Modifier des variables avec --set (merge intelligent)
./query.sh -R 3 --set '.take=10' # Modifier une variable
./query.sh -R 3 --set '.take=10 | .skip=20' # Modifier plusieurs (pipe jq)
./query.sh -R 3 --set '.filter.status="active"' # Objet imbriqué
./query.sh -R 3 --set '.take=10' --set '.id="99"' # Multiples --set
# Comparer deux exécutions avec --diff
./query.sh '{ me { id } }' --diff "--superadmin" # vendor vs superadmin
./query.sh -R 3 --diff "--set '.take=20'" # take=10 vs take=20
./query.sh '{ products { totalItems } }' --diff "--shop" # admin vs shop
# Mode compact avec --diff-only (affiche uniquement les chemins JSON modifiés)
./query.sh -R 3 --diff "--set '.take=1'" --diff-only
# Affiche: A .data.products.items[1].name = "Courgette"
# B .data.products.items[1].name = (absent)
# Prévisualiser sans exécuter avec --dry-run (pas d'authentification)
./query.sh '{ products { items { id } } }' --dry-run
./query.sh -R 3 --set '.take=10' --superadmin --dry-run
./query.sh --file queries/get-product.graphql --vars '{"id":"42"}' --shop --dry-run
# Affiche: 📝 Query, 📦 Variables, 🔑 Auth, 🌐 Endpoint + "(non exécuté)"
# Générer une commande curl équivalente (copier-coller)
./query.sh '{ me { id } }' --curl
./query.sh '{ products { items { id } } }' --superadmin --curl
./query.sh -R 3 --vars '{"take": 5}' --shop --curl
# Affiche:
# curl -X POST 'http://localhost:3000/admin-api' \
# -H 'Content-Type: application/json' \
# -H 'Authorization: Bearer eyJ...' \
# -d '{"query":"{ me { id } }","variables":{}}'
# Filtrer les résultats avec --jq
./query.sh '{ products { totalItems } }' --jq '.data.products.totalItems'
# → 42
./query.sh '{ products { items { name } } }' --jq '.data.products.items[].name'
# → Orange Sanguine
# → Courgette Longue verte
./query.sh '{ products { items { id name enabled } } }' \
--jq '.data.products.items[] | select(.enabled == true) | .name'
./query.sh '{ products { items { id } } }' -j '.data.products.items | length'
# → 5
# Valider avec --assert (exit 1 si condition fausse)
./query.sh '{ products { totalItems } }' --assert '.data.products.totalItems > 0'
./query.sh '{ product(id: "1") { id } }' -a '.data.product | type == "object"'
# Workflows conditionnels avec && / ||
./query.sh '{ products { totalItems } }' --assert '.data.products.totalItems > 0' \
&& echo "Catalogue OK" || echo "Catalogue vide!"
# Combiner --assert et --jq (valider puis extraire)
./query.sh '{ products { totalItems } }' \
--assert '.data.products.totalItems > 0' \
--jq '.data.products.totalItems'
# Mode silencieux avec --quiet (capture propre)
TOTAL=$(./query.sh -q '{ products { totalItems } }' -j '.data.products.totalItems')
echo "Total: $TOTAL"
# Écrire dans un fichier avec --output
./query.sh '{ products { items { id name } } }' --output /tmp/products.json
./query.sh '{ orders { items { id } } }' -o /tmp/orders.json
# Automatisation totale : --quiet + --output + --assert + --jq
./query.sh -q '{ products { totalItems } }' \
--assert '.data.products.totalItems > 0' \
--jq '.data.products.totalItems' \
-o /tmp/count.txt
# Sauvegarde
./query.sh -S get-me '{ me { id } }' # Sauvegarde dans queries/get-me.graphql
./query.sh -f queries/get-me.graphql # Charge et exécute
# Requête multi-lignes (guillemets simples)
./query.sh '
query {
products(options: { take: 5 }) {
items { id name }
}
}
'
# Avec variables (utiliser heredoc si la requête contient !)
./query.sh --vars '{"id": "42"}' <<'EOF'
query GetProduct($id: ID!) {
product(id: $id) { name }
}
EOF
# Depuis stdin
echo '{ me { id } }' | ./query.sh
# Shop API (storefront)
./query.sh --shop '{ products { items { id name } } }'
./query.sh --shop '{ activeCustomer { id emailAddress } }'
# Mesure du temps d'exécution
./query.sh -T '{ me { id } }' # Affiche "⏱ 74ms"
./query.sh -s -T '{ administrators { totalItems } }'
./query.sh --shop -T '{ products { items { id } } }'
⚠️ Limitation : The character
!(e.g.:ID!) causes problems inline due to bash history expansion. If error "Unexpected character", use heredoc (<<'EOF') or file (--file query.graphql) instead of single quotes.
Debugging workflow (Burp Repeater style)
The history and replay system allows you to efficiently debug GraphQL requests:
# 1. Exécuter une requête qui échoue ou retourne des résultats inattendus
./query.sh '{ products(options: { take: 5 }) { items { id name } } }'
# 2. Consulter l'historique pour voir les requêtes récentes
./query.sh -H
# Affiche:
# [1] 14:23:01 { me { id } }...
# [2] 14:25:33 query GetProducts($take: Int)...
# [3] 14:28:45 { collections { items { id }...
# 3. Inspecter une requête AVANT de la rejouer (voir query + variables)
./query.sh -I 2
# ═══════════════════════════════════════════════════════════
# Query #2 (2025-12-30 14:25:33)
# ═══════════════════════════════════════════════════════════
# query GetProducts($take: Int) { products(options: { take: $take }) { ... } }
# ───────────────────────────────────────────────────────────
# Variables: {"take": 5}
# ═══════════════════════════════════════════════════════════
# 4. Rejouer une requête avec modifications
./query.sh -R 2 # Identique
./query.sh -R 2 -s # En superadmin (voir plus de données)
./query.sh -R 2 --vars '{"take": 10}' # Remplacer toutes les variables
./query.sh -R 2 --shop # Sur shop-api au lieu d'admin-api
# 5. Modifier des variables spécifiques avec --set (merge)
./query.sh -R 2 --set '.take=10' # Modifier une seule variable
./query.sh -R 2 --set '.filter.status="pending"' # Modifier un objet imbriqué
./query.sh -R 2 --set '.take=10' --set '.skip=5' # Modifier plusieurs variables
# 6. Comparer les résultats avec --diff
./query.sh -R 2 --diff "--superadmin" # vendor vs superadmin (diff coloré)
./query.sh -R 2 --diff "--set '.take=10'" # take=5 vs take=10
./query.sh -R 2 --diff "--shop" # admin-api vs shop-api
./query.sh -R 2 --diff "--set '.take=1'" --diff-only # Mode compact (chemins JSON)
Typical use cases:
- Inspect before replaying : view the full query and its variables with
-I - Preview without executing : use
--dry-runto see query/variables/auth/endpoint without connecting - Generate curl : use
--curlto get a copy-paste curl command (Postman, CI/CD, sharing) - Edit surgically : use
--setto change a variable without retyping everything - Compare quickly : use
--diffto see the differences,--diff-onlyfor the compact format - Validate before acting : use
--assertto check conditions (conditional workflows) - Continue despite errors : use
--no-failto chain several requests without interruption - Extract and filter : use
--jqto extract specific values - Capture cleanly : use
--quietto remove logs and capture only the result - Save the results : use
--outputto write to a file (clean JSON without colors) - Easily modify nested objects with jq syntax
- Switch between admin-api and shop-api to compare behaviors
- Analyze permission errors by comparing vendor vs superadmin
Generated files
last-account.json: Credentials of the last created account (email, password, vendorId).token-cache.vendor: Vendor token cache (30 min).token-cache.superadmin: Superadmin token cache (30 min).query-history: History of the last 50 GraphQL requestsqueries/: Saved GraphQL requests with--save
Notes
- This skill is generated from the official Vendure documentation (docs.vendure.io)
- The code examples include language detection for highlighting
- All monetary values are represented as integers (divide by 100 for display)
- GraphQL is the main API interface (Shop API for storefront, Admin API for management)
- The Dashboard uses React and TailwindCSS - always import from
@vendure/dashboard
Update
To refresh this skill with updated documentation:
- Re-scrape the official documentation docs.vendure.io
- Reorganize the files into the Guides/reference/UI structure
- Update the line counts in this SKILL.md