Figma deploy integration
Skill jeremylongshore/claude-code-plugins-plus-skills/skills/.curated/figma-deploy-integration
425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill figma-deploy-integrationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
'Deploy Figma-powered applications to Vercel, Cloud Run, and Fly.io.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
5.9 KB, as published. Nobody here has run it
Figma Deploy Integration
Overview
Deploy Figma webhook receivers and design API services to production platforms with proper secret management and health checks.
Prerequisites
- Figma PAT for production environment
- Platform CLI installed (vercel, fly, or gcloud)
- Application tested locally with Figma API
Instructions
Step 1: Vercel Deployment (Webhook Receiver)
# Store Figma secrets
vercel env add FIGMA_PAT production
vercel env add FIGMA_WEBHOOK_PASSCODE production
# Deploy
vercel --prod
// api/webhooks/figma.ts (Vercel serverless function)
import { NextRequest, NextResponse } from 'next/server';
import crypto from 'crypto';
export async function POST(req: NextRequest) {
const payload = await req.json();
// Verify passcode
const expected = process.env.FIGMA_WEBHOOK_PASSCODE!;
const received = payload.passcode || '';
const a = Buffer.from(received);
const b = Buffer.from(expected);
// timingSafeEqual throws on length mismatch — guard first
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return NextResponse.json({ error: 'Invalid passcode' }, { status: 401 });
}
// Process webhook event
switch (payload.event_type) {
case 'FILE_UPDATE':
console.log(`File updated: ${payload.file_name} (${payload.file_key})`);
// Trigger token re-sync, invalidate cache, etc.
break;
case 'FILE_COMMENT':
console.log(`New comment on ${payload.file_name}`);
break;
case 'LIBRARY_PUBLISH':
console.log(`Library published: ${payload.file_name}`);
break;
}
return NextResponse.json({ received: true });
}
export const config = { maxDuration: 10 };
Step 2: Google Cloud Run (Design Token API)
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY dist/ ./dist/
ENV PORT=8080
CMD ["node", "dist/server.js"]
PROJECT_ID="${GOOGLE_CLOUD_PROJECT}"
SERVICE="figma-token-api"
REGION="us-central1"
# Store PAT in Secret Manager
echo -n "${FIGMA_PAT}" | gcloud secrets create figma-pat --data-file=-
# Build and deploy
gcloud builds submit --tag gcr.io/$PROJECT_ID/$SERVICE
gcloud run deploy $SERVICE \
--image gcr.io/$PROJECT_ID/$SERVICE \
--region $REGION \
--platform managed \
--set-secrets="FIGMA_PAT=figma-pat:latest" \
--allow-unauthenticated \
--max-instances=5 \
--timeout=30s
Step 3: Fly.io (Persistent Webhook Service)
# fly.toml
app = "figma-webhook-service"
primary_region = "iad"
[env]
NODE_ENV = "production"
[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = "suspend"
auto_start_machines = true
min_machines_running = 1
[[http_service.checks]]
grace_period = "10s"
interval = "30s"
method = "GET"
path = "/health"
timeout = "5s"
fly secrets set FIGMA_PAT=figd_your-token
fly secrets set FIGMA_WEBHOOK_PASSCODE=your-passcode
fly deploy
Step 4: Health Check Endpoint
// src/health.ts -- works on any platform
import { figmaFetch } from './figma-client';
export async function healthHandler(req: Request): Promise<Response> {
const start = Date.now();
try {
const res = await fetch('https://api.figma.com/v1/me', {
headers: { 'X-Figma-Token': process.env.FIGMA_PAT! },
signal: AbortSignal.timeout(5000),
});
return Response.json({
status: res.ok ? 'healthy' : 'degraded',
figma: {
authenticated: res.ok,
latencyMs: Date.now() - start,
},
timestamp: new Date().toISOString(),
});
} catch {
return Response.json({
status: 'unhealthy',
figma: { authenticated: false, latencyMs: Date.now() - start },
}, { status: 503 });
}
}
Output
- Application deployed with Figma secrets configured
- Webhook endpoint receiving Figma events
- Health check validating Figma connectivity
- Platform-specific optimizations applied
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| Secret not found in runtime | Wrong env name | Verify with platform CLI (vercel env ls) |
| Webhook timeout | Processing too slow | Return 200 immediately, process async |
| Cold start latency | Serverless cold boot | Use Fly.io min_machines_running: 1 or Cloud Run min instances |
| Health check fails | PAT expired | Rotate token via platform secret management |
Examples
Deploy the webhook receiver to Vercel (Step 1) and verify end-to-end:
vercel deploy --prod
curl -s -X POST https://figma-hooks.example.vercel.app/api/figma/webhook \
-H 'Content-Type: application/json' \
-d '{"event_type":"PING","passcode":"'"${WEBHOOK_PASSCODE}"'"}'
# 200 {"ok":true}
Then point Figma at it and watch a real event arrive:
POST /api/figma/webhook 200 event=FILE_UPDATE file=AbC123 triggered_by=mia.designer
Probe the deployed health endpoint (Step 4) — it checks Figma reachability, not just process-up:
curl -s https://figma-hooks.example.vercel.app/api/health | jq .
# {"status":"ok","figma_api":"reachable","uptime_s":86400}
Cloud Run and Fly.io equivalents: references/google-cloud-run-design-token-api.md, references/fly-io-persistent-webhook-service.md.
Resources
Next Steps
For webhook handling, see figma-webhooks-events.