DEV Community

Cover image for The Figma-to-n8n “Ninja Move”: Zero-Touch Asset Sync (with Chat Commands + AI Quality Checks)
Hoang Son
Hoang Son

Posted on

The Figma-to-n8n “Ninja Move”: Zero-Touch Asset Sync (with Chat Commands + AI Quality Checks)

Hey there, design warriors and code slingers! Ever feel like you're trapped in a never-ending loop of downloading Figma assets, renaming them like a digital janitor, and shoving them into repos while praying nothing breaks? Picture this: You're knee-deep in a sprint, the designer's dropped a "quick update" bomb, and suddenly you're playing asset Tetris across Android and iOS for multiple markets. Chaos ensues—mismatched icons, pixelated nightmares, and that one guy yelling, "It works on my machine!" We've all been there, and it's about as fun as debugging IE6.

But what if I told you there's a ninja move to flip the script? Enter n8n (that's "n-eight-n," an open-source workflow automation tool that's like Zapier on steroids). We're talking zero-touch syncing of Figma assets straight to your mobile repos, triggered by a casual chat command. No more manual handoffs. Add in AI-powered quality checks, delta detection for only-what-changed efficiency, and automated pull requests (PRs) on Bitbucket. Hands-free bliss for designers, design-ops folks, and engineers alike. By the end of this tutorial, you'll have a pipeline that delivers assets across markets and platforms like a well-oiled shuriken. Let's dive in and automate the tedium out of your life.

What We’re Building

In a nutshell, we're crafting a chat-driven n8n workflow that listens for commands like "Check Figma updates for GOPH" or "Quality check all markets TDS-200." It parses your intent, exports only the relevant Figma assets for specific markets (like Philippines via GOPH or South Africa via GOSA), detects changes, optionally runs AI vision analysis for quality/duplicates, and ships updates to Android/iOS repos with auto-generated branches, commits, and PRs. Notifications hit Slack or chat, logs go to Postgres, and the whole thing can evolve into scheduled runs. It's selective, efficient, and extensible—perfect for multi-market apps.
Here's a quick ASCII diagram of the pipeline:

User Chat
   │   (“check goph tds-100”, “quality check all markets”)
   ▼
n8n Chat Trigger → LLM Intent Parser → Fallback Parser
   │         (extract: action, markets, scope, ticket → auto-branch: feature/{ticket}-{action}-{markets}-{version})
   ├── Split by Market (e.g., GOPH, GOSA, SLSA)
   │     ├─ Env Setup (dependencies bootstrap)
   │     ├─ Figma Export (market-specific config: .figmaexportrc.<market>.js)
   │     ├─ Delta Detection (Python: new/modified/deleted → JSON output)
   │     └─ [Opt-in] AI Vision Quality Check (Ollama/LLaVA: score, issues, duplicates)
   │
   └── If Changes Detected:
         ├─ Copy Assets to Origin Dir
         ├─ Android Path: SVG → VectorDrawable Conversion → Repo Checkout → Deploy Assets → Update Changelog/Version → Commit/Push → Bitbucket PR
         ├─ iOS Path (Parallel): SVG Conversion (multi-worker) → .imageset Generation → Repo Ops → Commit/Push → Optional PR
         ├─ Notifications: Slack/Chat Summary (e.g., "5 new icons shipped!")
         └─ Logging: Persist Metrics/Interactions to Postgres

Enter fullscreen mode Exit fullscreen mode

Grounded Workflow Details

This isn't some hypothetical fluff—it's based on a real n8n setup I've battle-tested. We'll break it down with friendly subheads, bullets, and pseudocode to keep things digestible. The flow starts chat-driven for flexibility but can hook into cron schedules later.

Chat-Driven Intent → Filtered Execution

Everything kicks off with a chat trigger—think Slack, Discord, or even a custom webhook. Users drop commands like natural language ninjas.

Trigger Examples: "Check Figma updates for GOPH", "Quality check all markets TDS-200", "Full pipeline SLSA new_only".
Intent Parsing: An LLM (Large Language Model) node extracts key bits: action (e.g., check_updates, analyze_quality, find_duplicates, generate_report, full_pipeline), markets (GOPH for Philippines, GOSA for South Africa, SLSA for Sanlam; defaults to all if omitted), scope (new_only, modified_only, or all_assets; defaults to new_only), optional ticket (e.g., TDS-123), and auto-generates a Git branch like feature/{ticket}-{action}-{markets}-{version} (e.g., feature/TDS-100-update-goph-v1.2).
Selective Markets: Only process requested ones to save time—e.g., "check ph ticket tds-100" targets GOPH on branch feature/TDS-100-update-goph.
Fallback: If LLM parsing flakes, a simple function node with regex/string matching takes over.

Pseudocode for branch naming:
const ticket = items[0].json.ticket || '';
const action = items[0].json.action;
const markets = items[0].json.markets.join('-');
const version = getVersionFromChangelog(); // Custom func
return ticket ? `feature/${ticket.toUpperCase()}-${action}-${markets}-${version}` : 'main';
Enter fullscreen mode Exit fullscreen mode

Environment + Figma Export

We set up a lightweight env for exports, pulling from specific Figma folders like Icons, Integration Logos, Pictograms, and Other.

Setup: Bootstrap Python libs (e.g., Pillow for imaging) and CLI tools like figma-export via n8n's Execute Command node. Use market-specific configs.
Export Command: Run figma-export use-config .figmaexportrc.<market>.js per market. Configs define file IDs, component IDs, and output dirs.
Secrets Handling: Store Figma access tokens in n8n Credentials or env vars like $FIGMA_TOKEN—never hardcode!

Example config snippet (sanitized):

// .figmaexportrc.goph.js
module.exports = {
  fileId: '{{$env.FIGMA_FILE_ID}}',
  token: '{{$env.FIGMA_TOKEN}}',
  output: './exports/goph',
  components: [/* array of component IDs */],
};
Enter fullscreen mode Exit fullscreen mode

Delta Detection + Processing

No blind exports—detect changes to keep things lean.

Python Step: Script like getNewAssetsAndRename.py --market goph --folders "Icons,Integration Logos,Pictograms,Other" --scope new_only --chat-mode --output-json. Outputs JSON: { "new": 3, "modified": 2, "deleted": 0, "files": ["icon1.svg", ...], "timestamp": "2025-08-31" }.
Optional AI Vision: If commanded (or changes exist and opt-in), batch images to Ollama with LLaVA model. Returns { "quality_score": 0.95, "issues": ["blurry edge"], "duplicates": ["icon1 matches icon2"], "suggestions": "Sharpen borders" }.

If There Are Changes → Ship Them

Changes? Time to deploy like a boss.

  • Copy to Origin: Stash new assets in a central dir.
  • Android Path: Convert SVG to VectorDrawable via a Python script, checkout resources repo, deploy assets, bump version/changelog, commit, push, open Bitbucket PR.
  • iOS Path: Parallel conversion with svg2vector_enhanced.py -workers 4 -retry 3, generate .imageset folders, repo checkout, versioning, commit/push, optional PR.
  • Notifications: Slack summaries like "Ninja move complete: 5 assets updated for GOPH!" and chat replies.
  • Logging: Dump metrics (e.g., processed count, time taken) to Postgres for audits.

Prerequisites
Before we build, grab these:

  • Figma Stuff: Access token and file/component IDs—store in n8n Credentials or env vars like $FIGMA_TOKEN.
  • n8n: Self-hosted (docker-compose up) or cloud version.
  • Repos: Bitbucket/Git for Android/iOS resources; optional central storage (S3 or local).
  • Optional Extras: Python imaging libs (Pillow), node CLIs (figma-export), Ollama for local LLaVA vision model.

⚠️ Tip: Test on a staging Figma file to avoid prod mishaps.

Step-by-Step Build

Let's assemble this beast node by node in n8n. Assume you're in the workflow editor.
Trigger & Intent

  1. Add a Chat Trigger node (or Webhook for Slack integration).
  2. Connect to LLM Parser (e.g., OpenAI node with prompt: "Extract action, markets, scope, ticket from: {{$input.message}}").
  3. Add Fallback Parser (Function node with JS regex for robustness).
  4. Branch Naming: Function node to compute feature/{ticket}-{action}-{markets}-{version}. Masked example: Input "check ph tds-100" → Output branch "feature/TDS-100-check-goph-v1.0".

Market Splitting & Environment Setup

  1. Split by Market: Use a Switch or Loop node to handle arrays (e.g., markets: ["goph", "gosa"]).
  2. Env Setup: Execute Command: pip install pillow requests (one-time bootstrap; idempotent).

Figma Export

Per-market: Execute Command with figma-export use-config .figmaexportrc.{{$json.market}}.js.
High-level config: Defines SVG output, folders to pull.

Delta Detection

  1. Run Python: python getNewAssetsAndRename.py --market {{$json.market}} --folders "Icons,Integration Logos,Pictograms,Other" --scope {{$json.scope}} --chat-mode --output-json.
  2. Parse JSON output for decisions.

Optional AI Vision Analysis

  1. If opt-in: Batch Loop over images → HTTP Request to Ollama: POST /api/generate with LLaVA prompt like "Analyze quality: score 0-1, issues, duplicates".
  2. Non-blocking: Use Merge node to continue even if AI times out.

⚠️ Warning: Ollama needs GPU for speed; fallback to CPU if local.

Ship Changes

  1. Copy Assets: Move files to origin dir.
  2. Android: Execute svg_to_vector.py, Git nodes for checkout/commit/push, Bitbucket API for PR.
  3. iOS (Enhanced): Load config JSON, run svg2vector_enhanced.py -workers 4 -retry 3, generate .imageset, Git ops, optional PR via config flag.
  4. Update changelog: Append "Updated: [files] on [date]".

Inline tip: Use n8n's Git nodes for repo magic—set credentials securely.

Guardrails & Gotchas

Automation's great until it backfires. Here's how to ninja-proof it:

  • Secrets: Never log tokens; use n8n's encrypted Credentials.
  • Figma Limits: Batch exports (e.g., 50 components max); add Wait nodes for 429 rate limits.
  • Duplicates/Cache: Hash filenames or check ETags to bust caches.
  • Retries: Wrap long jobs in Try/Catch with exponential backoff.
  • Fallbacks: If AI parsing fails, default to check_updates all new_only.
  • Rollback: Revert commits or auto-close bad PRs via webhook.

⚠️ Gotcha: Git permissions—ensure n8n's service account has write access.

Power-Ups

Level up your ninja:

  • Auto-Changelogs/PRs: Generate PR bodies with asset thumbnails (base64 embeds).
  • Chat Scenarios: "Full pipeline" runs end-to-end; "Find duplicates" skips shipping.
  • Branch Strategy: Use staging branches for non-prod; merge to main post-review.
  • Optimizations: Add lossless compression (svgo) or LQIP (Low-Quality Image Placeholders) for previews.

Results & Impact

This setup saved my team ~10 hours weekly on asset wrangling—no more "works on my machine" drama. Fewer handoff errors mean happier designers and faster releases.

Before/After Table:

Aspect            | Manual Hell                     | Ninja Automation Heaven
------------------|--------------------------------|-----------------------------------
Time per Sync     | 1-2 hours/market               | <5 mins (background)
Error Rate        | High (mismatches, forgets)     | Low (deltas + AI checks)
Platforms         | Sequential, error-prone        | Parallel Android/iOS
Notifications     | Email chains                   | Instant Slack/chat + PRs
Scalability       | Breaks at 3+ markets           | Handles all with filtering

Enter fullscreen mode Exit fullscreen mode

Screenshots? Imagine a sanitized PR with "5 new icons: [thumbnails]" and a Slack ping: "Assets ninja'd successfully!"

Minimal Importable Starter

Here's a stripped-down n8n workflow JSON snippet (import via n8n editor). Covers chat → intent → single-market export → delta → commit → PR. Replace placeholders!

{
  "nodes": [
    {
      "name": "Chat Trigger",
      "type": "n8n-nodes-base.webhook",
      "parameters": { /* webhook setup */ }
    },
    {
      "name": "Intent Parser",
      "type": "n8n-nodes-base.openAi",
      "parameters": { "prompt": "Extract from: {{$input.message}}" }
    },
    // ... Add more: Figma Export (Execute Command), Delta (Python), Git Commit, Bitbucket PR (HTTP)
    // Placeholders: {{$env.FIGMA_TOKEN}}, {{$env.REPO_URL}}, reviewers: ["@team-lead"]
  ],
  "connections": { /* Link nodes */ }
}
Enter fullscreen mode Exit fullscreen mode

FAQ / Troubleshooting

  • 401 Unauthorized? Bad Figma token—regen and update creds.
  • 429 Rate Limit? Add delays; reduce batch size.
  • Git Permissions? Check service account keys.
  • Path Issues? Use absolute paths in scripts.
  • Ollama Not Found? Ensure it's running locally; fallback to no-AI.
  • No Changes Detected? Verify scope; clear caches.

CTA

Ready to unleash your inner asset ninja? Grab this template, import the starter into n8n, and tweak for your setup. Fork it on GitHub if you add twists like more AI smarts or platforms. Drop your customizations in the comments—let's crowdsource even better pipelines. Happy automating!

Top comments (0)