figma-graphql
figma-graphql copied to clipboard
v2 Roadmap
I'm planning on dedicating more time to this so I also wanted to set the goals and plans for the upcoming v2. You may call it public accountability but I'm also genuinely interested in what people think about this.
A bit of context first!
This library was something very experimental done on the back of the launch of the Figma API. Its main goal initially was to provide a 1:1 match with the Figma API using the awesome figma-js library as the interface.
While this works, it's also missing on a great opportunity to make the Figma API more accessible to people that aren't necessarily developers.
What to expect for v2
With that mindset, I bumped into this tweet from @jongold which made re-think the approach for this library...
What if we make design tools a little bit more human?
Take this Figma API response for a simple file
{
"document":{
"id":"0:0",
"name":"Document",
"type":"DOCUMENT",
"children":[
{
"id":"0:1",
"name":"Page 1",
"type":"CANVAS",
"children":[
{
"id":"1:6",
"name":"Rectangle",
"type":"INSTANCE",
"blendMode":"PASS_THROUGH",
"children":[
{
"id":"I1:6;1:2",
"name":"Rectangle",
"type":"RECTANGLE",
"blendMode":"PASS_THROUGH",
"absoluteBoundingBox":{
"x":24,
"y":-208,
"width":201,
"height":109
},
"constraints":{
"vertical":"SCALE",
"horizontal":"SCALE"
},
"fills":[
{
"blendMode":"NORMAL",
"type":"SOLID",
"color":{
"r":0.047058823529411764,
"g":0.9568627450980393,
"b":0.027450980392156862,
"a":1
}
}
],
"strokes":[
],
"strokeWeight":1,
"strokeAlign":"INSIDE",
"styles":{
"fill":"1:12"
},
"effects":[
]
},
{
"id":"I1:6;18:0",
"name":"Text",
"type":"TEXT",
"blendMode":"PASS_THROUGH",
"absoluteBoundingBox":{
"x":57,
"y":-163,
"width":63,
"height":20
},
"constraints":{
"vertical":"SCALE",
"horizontal":"SCALE"
},
"fills":[
{
"blendMode":"NORMAL",
"type":"SOLID",
"color":{
"r":0.8509803921568627,
"g":0.10980392156862745,
"b":0.10980392156862745,
"a":1
}
}
],
"strokes":[
],
"strokeWeight":1,
"strokeAlign":"OUTSIDE",
"styles":{
"fill":"1:11"
},
"effects":[
],
"characters":"Text",
"style":{
"fontFamily":"Roboto",
"fontPostScriptName":null,
"fontWeight":400,
"fontSize":12,
"textAlignHorizontal":"LEFT",
"textAlignVertical":"TOP",
"letterSpacing":0,
"lineHeightPx":14.0625,
"lineHeightPercent":100
},
"characterStyleOverrides":[
],
"styleOverrideTable":{
}
}
],
"absoluteBoundingBox":{
"x":24,
"y":-208,
"width":201,
"height":109
},
"constraints":{
"vertical":"TOP",
"horizontal":"LEFT"
},
"clipsContent":false,
"background":[
{
"blendMode":"NORMAL",
"visible":false,
"type":"SOLID",
"color":{
"r":1,
"g":1,
"b":1,
"a":1
}
}
],
"backgroundColor":{
"r":0,
"g":0,
"b":0,
"a":0
},
"effects":[
],
"componentId":"1:5"
},
{
"id":"7:0",
"name":"Frame",
"type":"FRAME",
"blendMode":"PASS_THROUGH",
"children":[
{
"id":"1:5",
"name":"Rectangle",
"type":"COMPONENT",
"blendMode":"PASS_THROUGH",
"children":[
{
"id":"1:2",
"name":"Rectangle",
"type":"RECTANGLE",
"blendMode":"PASS_THROUGH",
"absoluteBoundingBox":{
"x":-232,
"y":-208,
"width":201,
"height":109
},
"constraints":{
"vertical":"SCALE",
"horizontal":"SCALE"
},
"fills":[
{
"blendMode":"NORMAL",
"type":"SOLID",
"color":{
"r":0.8509803921568627,
"g":0.10980392156862745,
"b":0.10980392156862745,
"a":1
}
}
],
"strokes":[
],
"strokeWeight":1,
"strokeAlign":"INSIDE",
"styles":{
"fill":"1:11"
},
"effects":[
]
},
{
"id":"18:0",
"name":"Text",
"type":"TEXT",
"blendMode":"PASS_THROUGH",
"absoluteBoundingBox":{
"x":-199,
"y":-163,
"width":63,
"height":20
},
"constraints":{
"vertical":"SCALE",
"horizontal":"SCALE"
},
"fills":[
{
"blendMode":"NORMAL",
"type":"SOLID",
"color":{
"r":0.047058823529411764,
"g":0.9568627450980393,
"b":0.027450980392156862,
"a":1
}
}
],
"strokes":[
],
"strokeWeight":1,
"strokeAlign":"OUTSIDE",
"styles":{
"fill":"1:12"
},
"effects":[
],
"characters":"Text",
"style":{
"fontFamily":"Roboto",
"fontPostScriptName":null,
"fontWeight":400,
"fontSize":12,
"textAlignHorizontal":"LEFT",
"textAlignVertical":"TOP",
"letterSpacing":0,
"lineHeightPx":14.0625,
"lineHeightPercent":100
},
"characterStyleOverrides":[
],
"styleOverrideTable":{
}
}
],
"absoluteBoundingBox":{
"x":-232,
"y":-208,
"width":201,
"height":109
},
"constraints":{
"vertical":"TOP",
"horizontal":"LEFT"
},
"clipsContent":false,
"background":[
{
"blendMode":"NORMAL",
"visible":false,
"type":"SOLID",
"color":{
"r":1,
"g":1,
"b":1,
"a":1
}
}
],
"backgroundColor":{
"r":0,
"g":0,
"b":0,
"a":0
},
"effects":[
]
}
],
"absoluteBoundingBox":{
"x":-255,
"y":-230,
"width":252,
"height":151
},
"constraints":{
"vertical":"TOP",
"horizontal":"LEFT"
},
"clipsContent":true,
"background":[
{
"blendMode":"NORMAL",
"type":"SOLID",
"color":{
"r":1,
"g":1,
"b":1,
"a":1
}
}
],
"backgroundColor":{
"r":1,
"g":1,
"b":1,
"a":1
},
"effects":[
]
}
],
"backgroundColor":{
"r":0.8980392156862745,
"g":0.8980392156862745,
"b":0.8980392156862745,
"a":1
},
"prototypeStartNodeID":null
}
]
},
"components":{
"1:5":{
"key":"",
"name":"Rectangle",
"description":""
}
},
"schemaVersion":0,
"styles":{
"1:12":{
"key":"ea017aed6616af00f3c4d59e3d945c8c3e47adca",
"name":"Green",
"styleType":"FILL"
},
"1:11":{
"key":"e234400b962ffafce654af9b3220ce88857523ec",
"name":"Red",
"styleType":"FILL"
}
},
"name":"Untitled",
"lastModified":"2019-01-27T15:59:11.863713Z",
"thumbnailUrl":"https://s3-alpha-sig.figma.com/thumbnails/70c4fb68-1ed0-4f83-b871-3c00da8f7e36?Expires=1554076800&Signature=U780pTmEFpB6yyUJnCogFaJNWL1OlxnlH8mkCMq9jim-128~fDJvZql9X-69Di-SHs5cWJsl12Xw307F8uRDXH1~tHR44d36zyMnS7DXE4m05SNQQRqLEy0C5-twrGVFEQOL6vbQCg7VcusrQlQyi5Q99UB0UhRgUriMvdtuKZS4YNm7WiFXTsaTnCzKhIBfk~VtoX0Lea9tfVbm6~OQSb4BSqzQP~ULPGABNkdzR7BmGXXw-39icw87HglaZmYMURmNfR-~A4h-OLWI8Ol076iUTTaPLzqQy-l788VGng26ldUGT7rW1UCP0r1qL8XfzeWTxPkmwHLfni3yiDbsOg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA",
"version":"105584881"
}
For a developer, querying this data from the Figma API is already a bit complex, so it's even more difficult for non-tech people to get what they want easily and in a more human-readable way.
Imagine you're a designer that wants to get the name of all components in a specific artboard inside a file? Let's try...
file(id: "KViUntEBJqK4gWfiwft5NObl") {
frames(name: "Icons") {
components {
name
}
}
}
Ok, it might not be too complicated to get this without figma-graphql, but let's say we want to get a screenshot of all the artboards in a specific page of a file.
file(id: "KViUntEBJqK4gWfiwft5NObl") {
pages(name: "Hotel Journey") {
frames {
name
image(format: "png") {
images
}
}
}
}
Trying to get this information without technical knowledge would be almost impossible given the amount of stitching required. Instead, we're abstracting a complex interface to give people more power to do the task they're trying to accomplish.
To me GraphQL has the tremendous power of making complex data more accessible to everyone. It's a simple language that describes exactly what you want in a way that isn't too scary to most of us.
I can see organisations building tools that allow GraphQL queries to their Figma account so anyone in the business can get the information they need easily by using a language that is closer to their mental models. You can call it the democratisation of design.
Goals for v2
So to accomplish this mission, there are 3 main goals I'd like to achieve in the next milestone.
1 - Improve GraphQL code
It might be surprising that this is number 1 but I think that to achieve what we're proposing we need to start with stronger foundations. This project was very experimental when it started and with a big help from @SaraVieira it got much better, but there's a lot more work to do.
Better schema/resolvers I can see that @okonet has been spending some time improving the schema and resolvers in his fork and I'd love to have that integrated into the project. I'm sure there are plenty of ideas that we can consider going forward and this will only get better as people keep using it.
Use Typescript Another thing that we can consider is the use of Typescript to help building that robustness. There are many approaches to using TS in a GraphQL project and I'd like to spend some time understanding which would be the best fit for this.
Integration tests With TS and a good schema we'll be able to cover most of the issues that could happen in the code, but one of the things that we can't control and could affect us is the integration with the Figma API. At my current job, we've been working in integration tests to make sure the GraphQL side is always consistent with the API's it's using and I think we could benefit from having something like that too.
2 - Make API easier to use
Number 2 is of course making the API easier to use by everyone. This will be the most visible change of v2 and it's really important that we get this right as it's much harder to change the API once these decisions are made.
Normalisation/Grouping One of the things I've been working on is to normalise the response from Figma API and group the different node types to it's easier to query the file without having to respect the hierarchy of the file. People might just want the components that start the word "Button" and don't really know that in the file they are part of a group, that is part of a frame, that is part of a page. I think it's crucial that we break this structure while still allowing the traversing of the file for those who want precise control.
Helpers/Fragments This is still a bit vague in my mind, but I think it would be good to have easier ways to get the information. Given the declarative nature of GraphQL you need to be explicit in what you want to get, which might just be annoying for many people.
I did some explorations with #6 but to be honest I don't like that approach as it just makes it more complex and hard to understand. Maybe we could do something with fragments that would make it easier to query.
Easy installation
Having to get the code and run a bunch of commands might be a bit scary for non-technical people and if the goal is to get more people to use this then we need to have a way to quickly and easily deploy this to a place where anyone can test it.
Luckily we have CodeSandbox in our lives and with the container sandboxes we could literally have a one-click deploy for people to test it. I think we'll have this covered, right @SaraVieira? π
3 - Extend existing Figma API
Finally there's the big opportunity to extend the Figma API and give a lot more power to the users of the library.
@jongold mentioned getting the files for a project inside a team in #4 and I mentioned the example of getting screenshots for specific nodes in a files. All of this isn't possible with the Figma API without a good amount of stitching and GraphQL is a really good fit for this abstraction.
I'm also very excited about the exploration of subscriptions that @okonet is doing in his fork which is something that can be really useful to many people working with Figma.
And that's it, this is what I'd like to achieve with v2 and I honestly think it's pretty exciting if we can make it work!
I obviously won't be able to do this alone and would really appreciate any help I can get along the way so if you're reading this and feel excited about what I just wrote above please join the ride and let's build some stuff together!
So, what do you think about these ideas? π
OMG itβs so great! I have so many things coming your way. Regarding TS, @bebraw is doing something really exciting with it: it allows to skip writing Schemas and queries whatsoever and only rely on type definitions. BTW type definitions can be found in figma-js project.