.claude/skills/ts-fal-ai/SKILL.md
Deploy and run AI models instantly with fal.ai — image generation, video, audio, and custom models. Use when generating images with Flux/SDXL/LoRA, running ML inference at scale, building AI media features, or accessing state-of-the-art generative models via a simple API.
npx skillsauth add eliferjunior/Claude fal-aiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
fal.ai provides instant serverless inference for AI models — no GPU provisioning, no containers, pay per inference. The API is simple: pick a model ID, pass inputs, get outputs. Supports async jobs with webhooks, real-time streaming, and file uploads. Best-in-class for Flux image generation, video generation, and audio models.
npm install @fal-ai/client # JavaScript/TypeScript
pip install fal-client # Python
export FAL_KEY="your-api-key" # Get from fal.ai/dashboard
import * as fal from "@fal-ai/client";
// Configure (reads FAL_KEY from env by default)
fal.config({ credentials: process.env.FAL_KEY });
// Generate an image with Flux Schnell (fastest)
const result = await fal.subscribe("fal-ai/flux/schnell", {
input: {
prompt: "A futuristic city at night, neon lights, cyberpunk style",
image_size: "landscape_4_3",
num_images: 1,
},
logs: true,
onQueueUpdate: (update) => {
if (update.status === "IN_PROGRESS") {
console.log(update.logs?.map(l => l.message).join("\n"));
}
},
});
console.log(result.data.images[0].url);
import fal_client
def on_queue_update(update):
if isinstance(update, fal_client.InProgress):
for log in update.logs:
print(log["message"])
result = fal_client.subscribe(
"fal-ai/flux/schnell",
arguments={
"prompt": "A futuristic city at night, neon lights, cyberpunk style",
"image_size": "landscape_4_3",
"num_images": 1,
},
with_logs=True,
on_queue_update=on_queue_update,
)
print(result["images"][0]["url"])
// Flux Pro — highest quality
const pro = await fal.subscribe("fal-ai/flux-pro", {
input: {
prompt: "Portrait of a robot chef, photorealistic, soft lighting",
image_size: "portrait_4_3", // landscape_4_3, square, square_hd
num_inference_steps: 28,
guidance_scale: 3.5,
num_images: 1,
safety_tolerance: "2", // 1-6, higher = more permissive
}
});
// Flux Dev — high quality, faster than Pro
const dev = await fal.subscribe("fal-ai/flux/dev", {
input: {
prompt: "...",
num_inference_steps: 28,
seed: 42, // For reproducibility
}
});
// Flux Schnell — fastest, good quality
const schnell = await fal.subscribe("fal-ai/flux/schnell", {
input: { prompt: "...", num_inference_steps: 4 } // Only needs 4 steps
});
// Flux with LoRA
const lora = await fal.subscribe("fal-ai/flux-lora", {
input: {
prompt: "A photo of TOK wearing a tuxedo",
loras: [
{
path: "https://huggingface.co/your-lora/model.safetensors",
scale: 1.0
}
],
num_inference_steps: 28,
}
});
const result = await fal.subscribe("fal-ai/flux/dev/image-to-image", {
input: {
prompt: "Transform into oil painting style",
image_url: "https://example.com/photo.jpg",
strength: 0.85, // 0-1, how much to transform (1 = ignore original)
num_inference_steps: 28,
}
});
// AnimateDiff — animate a still image
const video = await fal.subscribe("fal-ai/animatediff-v2v", {
input: {
image_url: "https://example.com/frame.jpg",
prompt: "Gentle breeze moving through the trees",
num_frames: 16,
fps: 8,
}
});
console.log(video.data.video.url); // .mp4 URL
// Runway-style video gen
const runway = await fal.subscribe("fal-ai/kling-video/v1/standard/image-to-video", {
input: {
image_url: "https://example.com/start.jpg",
prompt: "Camera slowly pans right",
duration: "5",
}
});
// Upload audio file first
const audioUrl = await fal.storage.upload(fs.readFileSync("audio.mp3"), "audio.mp3");
const transcript = await fal.subscribe("fal-ai/whisper", {
input: {
audio_url: audioUrl,
task: "transcribe", // or "translate" (to English)
language: "en", // Optional, auto-detected if omitted
chunk_level: "segment",
version: "3",
}
});
console.log(transcript.data.text);
result = fal_client.subscribe(
"fal-ai/musicgen",
arguments={
"prompt": "Upbeat electronic music for a tech product demo, 120 BPM",
"duration": 30, # seconds
"top_k": 250,
"top_p": 0.0,
"temperature": 1.0,
}
)
print(result["audio"]["url"])
For long-running jobs, use submit → poll instead of subscribe:
// Submit job (returns immediately)
const { request_id } = await fal.queue.submit("fal-ai/flux-pro", {
input: { prompt: "..." },
webhookUrl: "https://your-app.com/webhooks/fal", // Optional
});
// Poll for result
const checkStatus = async () => {
const status = await fal.queue.status("fal-ai/flux-pro", {
requestId: request_id,
logs: true,
});
if (status.status === "COMPLETED") {
const result = await fal.queue.result("fal-ai/flux-pro", {
requestId: request_id,
});
return result.data;
}
if (status.status === "FAILED") {
throw new Error(`Job failed: ${status.error}`);
}
// Still in queue, check again in 2s
await new Promise(r => setTimeout(r, 2000));
return checkStatus();
};
const result = await checkStatus();
// app/api/webhooks/fal/route.ts
export async function POST(req: Request) {
const payload = await req.json();
if (payload.status === "OK") {
const imageUrl = payload.payload.images[0].url;
await db.update({ requestId: payload.request_id, imageUrl, status: "done" });
} else {
await db.update({ requestId: payload.request_id, status: "failed" });
}
return Response.json({ ok: true });
}
import * as fal from "@fal-ai/client";
import * as fs from "fs";
// Upload a file to fal.ai storage
const fileBuffer = fs.readFileSync("my-image.jpg");
const url = await fal.storage.upload(fileBuffer, "image.jpg");
// Returns: "https://fal.run/files/..."
// Use uploaded URL as model input
const result = await fal.subscribe("fal-ai/flux/dev/image-to-image", {
input: { image_url: url, prompt: "..." }
});
# Python file upload
import fal_client
url = fal_client.upload_file("./photo.png")
print(url) # https://fal.run/files/...
async function generateBatch(prompts: string[]): Promise<string[]> {
// Submit all jobs in parallel
const jobs = await Promise.all(
prompts.map(prompt =>
fal.queue.submit("fal-ai/flux/schnell", {
input: { prompt, num_images: 1 }
})
)
);
// Poll all results
const results = await Promise.all(
jobs.map(({ request_id }) =>
fal.queue.result("fal-ai/flux/schnell", { requestId: request_id })
)
);
return results.map(r => r.data.images[0].url);
}
const urls = await generateBatch([
"A red sports car",
"A blue mountain lake",
"A golden sunset over the ocean",
]);
fal.subscribe() for synchronous workflows (waits for completion, handles polling internally)fal.queue.submit() + webhooks for production async pipelinesonQueueUpdate for user-facing apps to show progressfal.ai/models for the full list of available models (100+)development
Expert guidance for Fireworks AI, the platform for running open-source LLMs (Llama, Mixtral, Qwen, etc.) with enterprise-grade speed and reliability. Helps developers integrate Fireworks' inference API, fine-tune models, and deploy custom model endpoints with function calling and structured output support.
development
Convert any website into clean, structured data with Firecrawl — API-first web scraping service. Use when someone asks to "turn a website into markdown", "scrape website for LLM", "Firecrawl", "extract website content as clean text", "crawl and convert to structured data", or "scrape website for RAG". Covers single-page scraping, full-site crawling, structured extraction, and LLM-ready output.
tools
Expert guidance for Firebase, Google's platform for building and scaling web and mobile applications. Helps developers set up authentication, Firestore/Realtime Database, Cloud Functions, hosting, storage, and analytics using Firebase's SDK and CLI.
development
When the user needs to build file upload functionality for a web application. Use when the user mentions "file upload," "image upload," "upload endpoint," "multipart upload," "presigned URL," "S3 upload," "file validation," "upload to cloud storage," or "accept user files." Handles upload endpoints, file validation (type, size, magic bytes), cloud storage integration, and upload status tracking. For image/video processing after upload, see media-transcoder.