Dear community, I'm creating a Figma PLUGIN solution that finds all component nodes and filter only those, whose color variable matches a user's input.
Usecase:
- Designer wants to find where is a specific color variable used within a library file.
How it should work:
- User types in a plugin UI: “button/background/hover”
- Plugin search through all the component nodes.
- Plugin prints out all component nodes that have the typed variable in their color fills.
Problem:
- Any component node I retrieve, there is no “boundVariable.fills” available to inspect, so that I cannot think of a proper way how to get to the fills variable.
- For a context: ComponentNode id: 1:10 (from the screenshot) is paired to a variable color
- Plugin returns at “if (selectedNode.boundVariables?.fills)”

Code
async function findComponentsUsingVariable(typedName: string) {
try {
// Ensure that all pages are loaded properly
console.log("Loading pages...");
await figma.loadAllPagesAsync();
console.log("Pages loaded successfully.");
} catch (error) {
console.log("Could not load pages asynchronously. Error: " + error);
return; // Stop execution if loading pages fails
}
const components: { id: string; name: string }[] = [];
// Fetch only components
for (const page of figma.root.children) {
const nodes = page.findAll(node => node.type === "COMPONENT" || node.type === "COMPONENT_SET");
// Loop ensures the asynchronous operations to be awaited
for (const selectedNode of nodes) {
console.log(selectedNode)
if (selectedNode && "boundVariables" in selectedNode) {
console.log("Bound Variables:", selectedNode.boundVariables);
if (selectedNode.boundVariables?.fills) {
console.log("Fill is bound to a variable.");
// Access the first bound fill variable
// Is fill really the 1 in an array?
const fillBoundVar = selectedNode.boundVariables.fills[0];
if (fillBoundVar) {
const variableId = fillBoundVar.id;
console.log("Variable ID:", variableId);
// Retrieve the variable details
const colorVariable = await figma.variables.getVariableByIdAsync(variableId);
if (colorVariable && colorVariable.name == typedName) {
console.log("Variable Name:", colorVariable.name);
console.log("Default Value:", colorVariable.valuesByMode);
components.push(selectedNode)
}
}
} else {
console.log("Fills are NOT bound to a variable.");
}
} else {
console.log("No bound variables found for this node.");
}
}
}
if (components.length > 0) {
console.log("Matched Components:", components);
figma.ui.postMessage({ type: "foundComponents", components: components });
figma.notify(`Found ${components.length} components using "${typedName}"`);
} else {
figma.ui.postMessage({ type: "noResults", typedName });
figma.notify(`No components found using "${typedName.toString}"`);
}
}
figma.showUI(__html__);
figma.ui.onmessage = async msg => {
if (msg.type === "findComponentsUsingVariable") {
await findComponentsUsingVariable(msg.variableName);
}
};