{"id":13465304,"url":"https://github.com/almazrafi/Fugen","last_synced_at":"2025-03-25T16:31:35.151Z","repository":{"id":35470058,"uuid":"216640899","full_name":"almazrafi/Fugen","owner":"almazrafi","description":"Command line tool for exporting resources and generating code from your Figma files","archived":false,"fork":false,"pushed_at":"2023-10-28T12:25:35.000Z","size":3099,"stargazers_count":82,"open_issues_count":5,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-07-31T15:01:25.704Z","etag":null,"topics":["cocoapods","codegen","codegenerator","design-systems","design-tokens","figma","figma-api","figma-export","homebrew","ios","linux","macos","swift","tvos","watchos","xcode","xcode-assets"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/almazrafi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-10-21T18:44:33.000Z","updated_at":"2024-06-13T00:01:39.000Z","dependencies_parsed_at":"2023-02-14T04:10:44.912Z","dependency_job_id":"c789c175-c2e1-428e-a321-cef3cb86c6d1","html_url":"https://github.com/almazrafi/Fugen","commit_stats":{"total_commits":108,"total_committers":6,"mean_commits":18.0,"dds":"0.12962962962962965","last_synced_commit":"52793dc31d910d219b3ec3f9fcce0fe865805bc3"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/almazrafi%2FFugen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/almazrafi%2FFugen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/almazrafi%2FFugen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/almazrafi%2FFugen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/almazrafi","download_url":"https://codeload.github.com/almazrafi/Fugen/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222088535,"owners_count":16928976,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cocoapods","codegen","codegenerator","design-systems","design-tokens","figma","figma-api","figma-export","homebrew","ios","linux","macos","swift","tvos","watchos","xcode","xcode-assets"],"created_at":"2024-07-31T15:00:26.458Z","updated_at":"2024-10-29T17:30:41.021Z","avatar_url":"https://github.com/almazrafi.png","language":"Swift","funding_links":[],"categories":["Misc","Misc [🔝](#readme)","Developer Tools"],"sub_categories":["Vim"],"readme":"# Fugen\n[![Build Status](https://github.com/almazrafi/Fugen/workflows/CI/badge.svg?event=push)](https://github.com/almazrafi/Fugen/actions?query=event%3Apush)\n[![Version](https://img.shields.io/github/v/release/almazrafi/Fugen)](https://github.com/almazrafi/Fugen/releases)\n[![Xcode](https://img.shields.io/badge/Xcode-13-blue.svg)](https://developer.apple.com/xcode)\n[![Swift](https://img.shields.io/badge/Swift-5.5-orange.svg)](https://swift.org)\n[![Platforms](https://img.shields.io/badge/platforms-macOS%20%7C%20Linux-lightgrey)](https://swift.org/about/#platform-support)\n[![License](https://img.shields.io/github/license/almazrafi/Fugen.svg)](https://github.com/almazrafi/Fugen/blob/master/LICENSE)\n\nFugen is a command line tool for exporting resources and generating code from your [Figma](http://figma.com/) files.\n\nCurrently, Fugen supports the following entities:\n- ✅ Color styles\n- ✅ Text styles\n- ✅ Shadow styles\n- ✅ Images\n\n#### Watch the video\n[![Watch the video](Docs/PlayVideo.png)](https://youtu.be/SfZb8iu2bWY)\n\n#### Table of context\n- [Installation](#installation)\n    - [CocoaPods](#cocoapods)\n    - [Homebrew](#homebrew)\n    - [Mint](#mint)\n    - [ZIP archive](#zip-archive)\n- [Usage](#usage)\n- [Configuration](#configuration)\n    - [Base parameters](#base-parameters)\n    - [Figma access token](#figma-access-token)\n    - [Figma file](#figma-file)\n    - [Generation configuration](#generation-configuration)\n- [Color styles](#color-styles)\n- [Text styles](#text-styles)\n- [Shadow styles](#shadow-styles)\n- [Images](#images)\n- [Communication](#communication)\n- [License](#license)\n\n\n## Installation:\n### CocoaPods\nTo install Fugen using [CocoaPods](http://cocoapods.org) dependency manager, add this line to your `Podfile`:\n```ruby\npod 'Fugen', '~\u003e 1.4.0'\n```\n\nThen run this command:\n```sh\n$ pod install --repo-update\n```\n\nIf installing using CocoaPods, the generate command should include a relative path to the `Pods/Fugen` folder:\n```sh\n$ Pods/Fugen/fugen generate\n```\n\n\u003e Installation via CocoaPods is recommended, as it allows to use the fixed version on all team members machines\n\u003e and automate the update process.\n\n### Homebrew\nFor [Homebrew](https://brew.sh) dependency manager installation, run:\n```sh\n$ brew install almazrafi/tap/fugen\n```\n\n\u003e It's impossible to set a specific package version via Homebrew.\n\u003e If you chose this method, make sure all team members use the same version of Fugen.\n\n### Mint\n\nFor [Mint](https://github.com/yonaskolb/mint) package manager installation, run:\n\n```sh\n$ mint install almazrafi/Fugen@1.4.0\n```\n\n### ZIP archive\n\nEvery release in the repo has a ZIP archive which can be used to integrate Fugen into a project.\nTo use that method, the following steps should be taken:\n- Open [repository release page](https://github.com/almazrafi/Fugen/releases).\n- Download the 'fugen-x.y.z.zip' archive attached to the latest release.\n- Unarchive files into a convenient project folder\n\nIf this integration method was chosen,\nthe generation command should include a relative path to the folder with the ZIP-archive content, for example:\n```sh\n$ Fugen/fugen generate\n```\n\n\u003e It's recommended to include unarchived files into the Git index (`git add Fugen`).\n\u003e It will guarantee that all team members are using the same version of Fugen for the project.\n\n\n## Usage\nFugen provides a simple command for code generation:\n```sh\n$ fugen generate\n```\nAs the result, the source code files will be received according to the configuration (see [Configuration](#configuration)),\nwhich by default should be placed to `.fugen.yml` file.\n\nIf you need, you can use a specific path to the configuration, just pass it in the `--config` parameter. For example:\n```sh\n$ fugen generate --config 'Folder/fugen.yml'\n```\n\nFugen requests files data using [Figma API](https://www.figma.com/developers/api),\nso make sure you have the internet connection on while generating the code.\n\nThe resulting code could be easily customized with [Stencil-templates](https://github.com/stencilproject/Stencil).\nIf standard templates are not enough, a custom template could be used. Just\nspecify its path in the [configuration](#configuration).\n\n### Integration\nThere is no point to run `fugen generate` at the build stage, as Fugen doesn't work with local resources,\nwhich can be changed during development. All data for code generation is in Figma.\nAlso, there won't be any merge conflicts, if you use design versioning.\n\nSo, it is much better to generate code just once and keep it in the Git index.\nAlso run `fugen generate` for the following reasons:\n- to upgrade to a new design version in Figma\n- after updating Fugen version\n\nThere are also some recommendations on integration based on technologies used in a project.\nAll of them are listed in this section and will be updated as feedback is received.\n\nIn case you have any problems or suggestions related to integration,\nplease open the corresponding request in [Issues](https://github.com/almazrafi/Fugen/issues).\n\n#### CocoaPods\nIf you are using [CocoaPods](http://cocoapods.org) dependency manager,\nrun code generating command from `pre-install` event handler in `Podfile`:\n```ruby\npre_install do |installer|\n  system \"Pods/Fugen/fugen generate\"\nend\n```\n\nThat will allow connecting the code generation command with updating Fugen version\nand will reduce the number of commands executed while cloning the project.\n\n🚨 If you want to keep the generated files in the Development Pod, this integration method is ideal.\nIn this case the generation should be run after loading Fugen and before installing all Pods.\nOtherwise, new files will not be indexed on time and won't get included into the Xcode-project.\n\n\n## Configuration\n[YAML](https://yaml.org) file is used for Fugen configuration.\nDefine all necessary parameters of code generation in this file.\n\nConfiguration is divided into several sections:\n- `base`: base parameters that are actual for all other configuration sections (see [Base parameters](#base-parameters))\n- `colorStyles`: parameters of color styles generation step (see [Color styles](#color-styles)).\n- `textStyles`: parameters of text styles generation step (see [Text styles](#text-styles)).\n- `images`: parameters of the step of loading and generating code for images (see [Images](#images)).\n\nAny parameter from `base` section will be inherited and could be overwritten in the section of the particular generation step.\nIf some section of the generation step is missing in the configuration,\nit will be skipped during `fugen generate` command execution.\n\n### Base parameters\nEach step of generation is using the following base parameters:\n- `accessToken`: an access token string that is needed to execute Figma API requests (see [Figma access token](#figma-access-token)).\n- `file`: URL of a Figma file, which data will be used to generate code (see [Figma file](#figma-file)).\n\nIn order not to duplicate these fields in the configuration, you can specify them in the `base` section.\nThey will be used by those generation steps for which these parameters are not defined.\nFor example:\n```yaml\nbase:\n  accessToken: 25961-4ac9fbc9-3bd8-4c43-bbe2-95e477f8a067\n  file: https://www.figma.com/file/61xw2FQn61Xr7VVFYwiHHy/Fugen-Demo\n\ncolorStyles: { }\n\ntextStyles:\n  file: https://www.figma.com/file/SSeboI2x0jmeG4QO8iBMqX/Fugen-Demo-iOS\n```\n\nIf a base parameter is missing for both the generation step section and in the `base` section,\nthen as a result of the execution `fugen generate` command, the corresponding error will be received.\n\n### Figma access token\nAuthorization is required to receive Figma files.\nThe authorization is implemented by transferring a personal access token.\nThis token could be created in a few simple steps:\n1. Open [account settings]((https://www.figma.com/settings)) in Figma.\n2. Press \"Create a new personal access token\" button in the \"Personal Access Tokens\" section.\n3. Enter a description for the token (for instance, \"Fugen\").\n4. Copy the created token to the clipboard.\n\n![](Docs/AccessToken.png)\n\nThen paste the received access token in the `accessToken` field of the configuration.\nIt is enough to define it only in the `base` section if this token allows access to all Figma files,\nwhich appear in the configuration.\nFor example:\n```yaml\nbase:\n  accessToken: 25961-4ac9fbc9-3bd8-4c43-bbe2-95e477f8a067\n...\n```\n\nYou can also set the name of the environment variable in the `env` field instead of the access token value itself.\nFor example:\n```yaml\nbase:\n  accessToken:\n    env: FUGEN_ACCESS_TOKEN\n...\n```\n\nIf for a certain file you need to use a different access token,\nit should be specified in the corresponding section of the configuration (see [Base parameters](#base-parameters)).\n\n### Figma file\nFugen requests Figma file by using the identifier from its URL. This URL should be placed in the `file` field of the configuration.\nFor example:\n```yaml\nbase:\n  file: https://www.figma.com/file/61xw2FQn61Xr7VVFYwiHHy/Fugen-Demo\n...\n```\n\nIn addition to the file identifier itself, the URL could also contain additional parameters\nand generally has the following format:\n```url\nhttps://www.figma.com/file/:id/:title?version-id=:version-id\u0026node-id=:node-id\n```\n\nTo get the file, the following parameters are used:\n- `id`: the identifier of the file.\n- `version-id`: the identifier of the file version.\nIf this parameter is omitted, the current version will be used.\n- `node-id`: identifier of the selected frame.\nIf this parameter is present, then only the data from this frame will be used.\n\nThe URL of the Figma file opened in the browser can be easily obtained from the address bar.\n\n![](Docs/FileURL.png)\n\n🚨 Be careful with the `node-id` parameter, as in Figma the wrong frame could be selected.\nThen the wrong data will be used for generation.\n\n#### Alternative configuration\nSometimes using the file URL is not flexible enough.\nIn this case you can define an object with the following fields instead of the URL in the `file` parameter:\n- `key`: a string with the file's identifier. Is required.\n- `version`: a string with the file's version.\nIf this parameter is omitted, the current file version will be used.\n- `includedNodes`: an array of strings with nodes identifiers, that should be used for code generation.\nIf this parameter is omitted, all file nodes will be used.\n- `excludedNodes`: an array of strings with nodes identifiers that should be ignored when generating the code.\nIf this parameter is omitted, all file nodes specified in the `includedNodes` field will be used.\n\nThe values for these fields must be manually extracted from the file URL, according to its format.\nFor example, for URL  `https://www.figma.com/file/61xw2FQn61Xr7VVFYwiHHy/Fugen-Demo?version-id=194665614\u0026node-id=0%3A1`\nthe configuration will look like:\n```yaml\nbase:\n  file:\n    key: 61xw2FQn61Xr7VVFYwiHHy\n    version: 201889163\n    includedNodes:\n      - 0%3A1\n...\n```\n\nSuch a representation may be useful for implementing more complex filtering of nodes.\nFor example, when it is necessary to exclude several elements specific to another platform from the code generation.\n\n### Generation configuration\nBesides [base parameters](#base-parameters),\nfor each generation step the following configuration should be defined:\n- `template`: a path to the Stencil-template file.\nIf omitted, the standard template will be used.\n- `templateOptions`: a dictionary with additional options that will be used for generation in Stencil-template.\n- `destination`: a path to save the generated file.\nIf omitted, the generated code will be displayed in the console.\n\nThese generation steps also could have additional parameters.\nThe description of them and examples could be found in corresponding sections below.\n\n---\n\n## Color styles\nTo generate color styles [standard configuration set](#generation-configuration) with an additional parameter  is used:\n- `assets`: a path to the Xcode assets folder, in which all colors will be saved as a Color Set.\nThe parameter can be omitted if there is no need for assets.\n\nSample configuration:\n```yaml\ncolorStyles:\n  accessToken: 25961-4ac9fbc9-3bd8-4c43-bbe2-95e477f8a067\n  file: https://www.figma.com/file/61xw2FQn61Xr7VVFYwiHHy/Fugen-Demo\n  assets: Sources/Assets.xcassets/Colors\n  destination: Sources/ColorStyle.swift\n  templateOptions:\n    publicAccess: true\n```\n\n#### Xcode-assets\nIt's recommended to specify the path to a subfolder inside the Xcode-assets folder in the `assets` parameter,\nso all colors are saved in this subfolder. For example `Sources/Assets.xcassets/Colors`.\nThe whole assets structure be created if it was missing.\n\n🚨 Folder specified in the `assets` parameter will be emptied before saving colors there.\nYou shouldn't use the same path for different generation steps,\nbut you can use different subfolders of the assets folder,\nfor example `Sources/Assets.xcassets/Colors` and `Sources/Assets.xcassets/Images`.\n\n#### Standard template\nExamples of usage of the generated code:\n```swift\nview.backgroundColor = ColorStyle.razzmatazz.color\n// or\nview.backgroundColor = UIColor(style: .razzmatazz)\n```\n\nThe template could be configured using different options that are specified in `templateOptions` parameter:\n\nKey  | Type | Default value | Description\n---- | ---- | ------------- | -----------\n`styleTypeName` | String | ColorStyle | Style type name.\n`colorTypeName` | String | UIColor | Color type name. If the target platform is macOS, specify `NSColor`.\n`publicAccess` | Boolean | false | Adds `public` access modifier to the declarations in the generated file.\n\n## Text styles\nTo generate text styles [standard configuration set](#generation-configuration) is used.\n\nSample configuration:\n```yaml\ntextStyles:\n  accessToken: 25961-4ac9fbc9-3bd8-4c43-bbe2-95e477f8a067\n  file: https://www.figma.com/file/61xw2FQn61Xr7VVFYwiHHy/Fugen-Demo\n  destination: Sources/TextStyle.swift\n  templateOptions:\n    publicAccess: true\n```\n\n#### Standard template\nSample usage of the generated code:\n```swift\nlabel.attributedText = TextStyle.title.attributetemplateOptionsdString(\"Hello world\")\n// or\nlabel.attributedText = NSAttributedString(string: \"Hello world\", style: .title)\n// or\nlabel.attributedText = TextStyle\n    .title\n    .withColor(.white)\n    .withLineBreakMode(.byWordWrapping)\n    .attributedString(\"Hello world\")\n```\n\nThe template could be configured using additional options that specified in `templateOptions` parameter:\n\nKey  | Type | Default value | Description\n---- | ---- | ------------- | -----------\n`styleTypeName` | String | TextStyle | Style type name.\n`colorTypeName` | String | UIColor | Color type name. If the target platform is macOS, specify `NSColor`.\n`fontTypeName` | String | UIFont | Font type name. If the target platform is macOS, specify `NSFont`.\n`publicAccess` | Boolean | false | Adds `public` access modifier to the declarations in the generated file.\n`usingSystemFonts` | Boolean | false | If text style has system font (**SFProText** or **SFProDisplay**), then `font` property will be using `systemFont(ofSize:weight:)` method. \n\n## Shadow styles\n\nTo generate shadow styles [standard configuration set](#generation-configuration) is used.\n\nSample configuration:\n\n```yaml\nshadowStyles:\n  accessToken: 25961-4ac9fbc9-3bd8-4c43-bbe2-95e477f8a067\n  file: https://www.figma.com/file/61xw2FQn61Xr7VVFYwiHHy/Fugen-Demo\n  destination: Sources/ShadowStyle.swift\n  templateOptions:\n    publicAccess: true\n```\n\n#### Standard template\n\nSample usage of the generated code:\n\n```swift\n// If style contains only one shadow, you can set it to any view or layer\nlabel.shadow = .thinShadow\n\n// Styles with multiple shadows can only be set to an instance of ShadowStyleView\nlet cardView = ShadowStyleView()\n\ncardView.backgroundColor = .white\ncardView.shadowStyle = .cardShadow\n```\n\nThe template could be configured using additional options that specified in `templateOptions` parameter:\n\nKey  | Type | Default value | Description\n---- | ---- | ------------- | -----------\n`styleTypeName` | String | ShadowStyle | Style type name.\n`shadowTypeName` | String | Shadow | Shadow type name.\n`shadowStyleLayerTypeName` | String  | ShadowStyleLayer | Name of generated layer that provides rendering of shadow style.\n`shadowStyleViewTypeName` | String  | ShadowStyleView | Name of generated view to which the shadow style can be set.\n`colorTypeName` | String  | UIColor | Color type name. If the target platform is macOS, specify `NSColor`.\n`viewTypeName` | String  | UIView | View type name. If the target platform is macOS, specify `NSView`.\n`bezierPathTypeName` | String | UIBezierPath | Bezier path type name. If the target platform is macOS, specify `NSBezierPath`.\n`publicAccess` | Boolean | false | Adds `public` access modifier to the declarations in the generated file.\n\n## Images\n\nTo load and generate code for images, the [standard configuration set](#generation-configuration) is used with additional parameters:\n- `assets`: a path to Xcode-assets folder in which the images will be saved as Image Set.\nThe parameter could be omitted if there is no need for assets.\n- `resources`: a path to the resources folder in which the image files will be saved.\nThe parameter can be skipped, if, for example, you only want to save assets.\n- `format`: string with images format. `pdf`, `png`, `svg`, `jpg` are allowed.\nThe default format is `pdf`.\n- `scales`: array with integer scaling factors from 1 to 3.\nThe default scaling factor is 1, so the image will have the original size.\n- `onlyExportables`: renders only exportable components.\nThe default value is `false`.\n- `useAbsoluteBounds`: uses full dimensions of the node.\nThe default value is `false`.\n- `preserveVectorData`: sets `Preserve Vector Data` flag in Xcode assets.\nThe default value is `false`.\n\n\nSample configuration:\n```yaml\nimages:\n  accessToken: 25961-4ac9fbc9-3bd8-4c43-bbe2-95e477f8a067\n  file: https://www.figma.com/file/61xw2FQn61Xr7VVFYwiHHy/Fugen-Demo\n  assets: Sources/Assets.xcassets/Images\n  destination: Sources/Images.swift\n  onlyExportables: true\n  useAbsoluteBounds: true\n  templateOptions:\n    publicAccess: true\n```\n\n#### Figma components\nFugen only uses nodes that are [components](https://help.figma.com/article/66-components) as images.\nSo, make sure that the chosen frame in the file URL (see [Figma file](#figma-file))\nallows to filter out the components that should not render images in Figma file.\n\n#### Only exportables\nIf you want to export only those components\nthat have [export settings](https://help.figma.com/hc/en-us/articles/360040028114-Getting-Started-with-Exports) in Figma,\nset the `onlyExportables` flag to `true`.\n\n#### Use absolute bounds\nBy default Fugen exports the images using only space that is actually occupied by them, so if the node has extra space\naround, it will be cropped. If you want to preserve this space set the `useAbsoluteBounds` to `true`.\nSee [Image Endpoint Description](https://www.figma.com/developers/api#get-images-endpoint) for details.\n\n#### Xcode-assets\nIt's recommended to specify the path to a subfolder inside the Xcode-assets folder in the `assets` parameter,\nso all colors are saved in this subfolder. For example  `Sources/Assets.xcassets/Images`.\nThe whole assets structure be created if it was missing.\n\n🚨 Folder specified in the `assets` parameter will be emptied before saving colors there.\nYou shouldn't use the same path for different generation steps,\nbut you can use different subfolders of the assets folder,\nfor example `Sources/Assets.xcassets/Colors` and `Sources/Assets.xcassets/Images`.\n\n#### Formats\nFor Xcode projects, it is recommended to use PDF format without additional scaling factors,\nfor that it is enough not to specify the `format` and `scales` parameter.\n\nThere is no point to use SVG for Xcode projects, as it only could be used in other platforms (for example in Android).\n\n#### Scaling factors\nAn image of the corresponding size will be rendered for each scaling factor in the `scales` array,\nregardless of the specified format in the `format` parameter.\nHowever, it is not recommended to use additional scaling factors for vector PDF and SVG formats.\n\nWhen saved in Xcode assets, files of each scaled image will be kept in the same Image Set with Individual Scales option.\nIf the `scales` parameter is omitted in the configuration, the Image Set will have the Single Scale scaling type.\n\n#### Default template\nSample usage of the generated code:\n```swift\nimageView.image = Images.menuIcon\n```\n\nThe template could be configured using additional options specified in `templateOptions` parameter:\n\nKey  | Type | Default value | Description\n---- | ---- | ------------- | -----------\n`imagesEnumName` | String | Images | Name of a generated enum with static image fields\n`imageTypeName` | String | UIImage | Image type name. If the target platform is macOS, specify `NSImage`.\n`publicAccess` | Boolean | false | Adds `public` access modifier to the declarations in the generated file.\n\n---\n\n## Communication\n- If you need help, open an issue.\n- If you found a bug, open an issue.\n- If you have a feature request, open an issue.\n- If you want to contribute, submit a pull request.\n\n## License\nFugen is available under the MIT license. See the [LICENSE](LICENSE) file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falmazrafi%2FFugen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falmazrafi%2FFugen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falmazrafi%2FFugen/lists"}