# Configuration file 101

## Introduction

Whenever you want to work with the [GitHub](https://docs.specifyapp.com/distribute/available-destinations/github) or the [Specify CLI](https://docs.specifyapp.com/distribute/available-destinations/cli) destination, you need to create a Configuration file to instruct the [Parsers Engine](https://docs.specifyapp.com/concepts/parsers-engine) how to transform your design data, so it generate tokens that match your technical requirements.

A configuration file helps you:

1. request design tokens and assets from a Specify repository
2. transform them to fit your company standards thanks to [parsers](https://docs.specifyapp.com/reference/parsers)

{% embed url="<https://youtu.be/-zHEXQ4K9ZI>" %}

## Properties

A configuration is composed of 3 main properties:

* `repository`
* `personalAccessToken`
* `rules`

### Repository

The name of the Specify `repository` you want to pull your design tokens and assets from.

Let's say we have the following repository in Specify called "all-design-data" located in the "@acme-inc" organization.

<figure><img src="https://4265043194-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3998FFntXKzDmFTxxiPd%2Fuploads%2FhcAYbVlXivAc8YVLU4Ej%2FCleanShot%202023-12-22%20at%2014.36.57.jpg?alt=media&#x26;token=e461ac3e-7c91-49cc-be30-9d95d5041d84" alt=""><figcaption><p>An example Specify repository called "all-design-data-v2" located in the "@acme-inc" organization.</p></figcaption></figure>

We target it like this:

{% tabs %}
{% tab title="JavaScript (CommonJS)" %}

<pre class="language-javascript" data-title=".specifyrc.js" data-line-numbers><code class="lang-javascript">module.exports = {
  version: '2'
<strong>  repository: '@acme-inc/all-design-data-v2',
</strong>  personalAccessToken: '&#x3C;your-personal-access-token>',
  rules: [],
};
</code></pre>

{% endtab %}

{% tab title="JSON" %}

<pre class="language-json" data-title=".specifyrc.json" data-line-numbers><code class="lang-json">{
  "version": "2"
<strong>  "repository": "@acme-inc/all-design-data-v2",
</strong>  "personalAccessToken": "&#x3C;your-personal-access-token>",
  "rules": []
}
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="info" %}
You can only target one repository per configuration file. Want to pull design tokens from several Specify repositories? Create several configuration files and run them with the Specify CLI ([See example script](https://github.com/Specifyapp/pull-from-several-specify-repositories/blob/main/.github/workflows/update-design-tokens.yaml#L17-L28)).
{% endhint %}

### Personal Access Token

The Specify `personalAccessToken` used to authenticate you.

{% hint style="info" %}
Need a personal access token? [Generate one ↗](https://specifyapp.com/user/personal-access-tokens)
{% endhint %}

{% tabs %}
{% tab title="JavaScript (CommonJS)" %}

<pre class="language-javascript" data-line-numbers><code class="lang-javascript">module.exports = {
  version: '2'
  repository: '@workspace/repository',
<strong>  personalAccessToken: '&#x3C;your-personal-access-token>',
</strong>  rules: [],
};
</code></pre>

{% endtab %}

{% tab title="JSON" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
  "version": "2"
  "repository": "@workspace/repository",
<strong>  "personalAccessToken": "&#x3C;your-personal-access-token>",
</strong>  "rules": []
}
</code></pre>

{% endtab %}
{% endtabs %}

### Parser Rules

The Parsers Rules help you transform your design tokens and assets the way you want.

You can have as many `rules` as you want and you can have rules that transform several Token types at once.

{% hint style="info" %}
Looking for the rules configuration? 👉 review the [Parser Rule](https://docs.specifyapp.com/reference/parsers-engine#parserrule) reference.
{% endhint %}

Here are different kind of rules and parsers you can use to generate color tokens as CSS Custom Properties:

1. [filter](https://docs.specifyapp.com/sdtf-beta/parsers/filter) to target on a specific collection named "Colors" that contains our colors
2. [convert-color](https://docs.specifyapp.com/sdtf-beta/parsers/convert-color) to convert our colors in HSL
3. [change-case](https://docs.specifyapp.com/reference/parsers/change-case) to change the name of our tokens and modes to kebabCase
4. [to-css-custom-properties](https://docs.specifyapp.com/sdtf-beta/parsers/to-css-custom-properties) to generate a CSS file containing our tokens

{% tabs %}
{% tab title="JavaScript (CommonJS)" %}
{% code title=".specifyrc.js" lineNumbers="true" %}

```javascript
{
  version: '2',
  repository: '@organization/repository',
  personalAccessToken: '<your-personal-access-token>',
  rules: [
    {
      name: 'css',
      parsers: [
        {
          name: 'filter',
          options: {
            query: {
              where: {
                collection: '^Colors$',
                select: {
                  children: true
                }
              }
            }
          }
        },
        {
          name: 'convert-color',
          options: {
            toFormat: 'hsl',
            applyTo: {
              collection: true
            }
          }
        },
        {
          name: 'change-case',
          options: {
            change: 'names',
            toCase: 'kebabCase',
            applyTo: {
              collection: true
            }
          }
        },
        {
          name: 'change-case',
          options: {
            change: 'modes',
            toCase: 'kebabCase',
            applyTo: {
              collection: true
            }
          }
        },
        {
          name: 'to-css-custom-properties',
          output: {
            type: 'file',
            filePath: 'tokens.css'
          },
        },
      ],
    },
  ],
};
```

{% endcode %}
{% endtab %}

{% tab title="JSON" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "css",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "collection": "Colors",
                "select": {
                  "parents": true,
                  "children": true
                }
              }
            }
          }
        },
        {
          "name": "convert-color",
          "options": {
            "toFormat": "hsl",
            "applyTo": {
              "collection": true
            }
          }
        },
        {
          "name": "change-case",
          "options": {
            "change": "names",
            "toCase": "kebabCase",
            "applyTo": {
              "collection": true
            }
          }
        },
        {
          "name": "change-case",
          "options": {
            "change": "modes",
            "toCase": "kebabCase",
            "applyTo": {
              "collection": true
            }
          }
        },
        {
          "name": "to-css-custom-properties",
          "output": {
            "type": "file",
            "filePath": "tokens.css"
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Examples

### How to run these examples

The following examples are made to be used with the Specify CLI.

Requirements:

* a Specify repository containing design tokens
* a valid personal access token ([Generate one ↗](https://specifyapp.com/user/personal-access-tokens))

Run all examples by copying the code and running the `specify pull` command.

### Basic

Here's a basic configuration file that targets a Specify repository called `design-system` from the `@acme-inc` organization:

{% tabs %}
{% tab title="JavaScript (CommonJS)" %}
{% code title=".specifyrc.js" lineNumbers="true" %}

```javascript
module.exports = {
  version: '2',
  repository: '@acme-inc/design-system',
  personalAccessToken: '<your-personal-access-token>',
  rules: [
    {
      name: 'Generate colors as CSS Custom Properties',
      parsers: [
        {
          name: 'to-css-custom-properties',
          output: {
            type: 'file',
            filePath: 'colors.css'
          },
        },
      ],
    },
  ],
};
```

{% endcode %}
{% endtab %}

{% tab title="JSON" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@acme-inc/color-themes",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Generate colors as CSS Custom Properties",
      "parsers": [
        {
          "name": "to-css-custom-properties",
          "output": {
            "type": "file",
            "filePath": "colors.css"
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

This example config file will return a `colors.css` file containing all design tokens stored in the `design-system` repository.

Here's an example of a token value returned by Specify:

```json
{
  "colors": {
    "$collection": {
      "$modes": [
        "Light",
        "Dark"
      ]
    },
    "core": {
      "blue-100": {
        "$type": "color",
        "$description": "token 1 aliased with n modes within collection within n groups",
        "$value": {
          "Light": {
            "red": 219,
            "blue": 254,
            "alpha": 1,
            "green": 236,
            "model": "rgb"
          }
        }
      }
    }
  }
}
```

### Pull colors as CSS Custom Properties

Now let's update our previous configuration to only pull colors and transform them as CSS Custom Properties in RGB.

{% tabs %}
{% tab title="JavaScript (CommonJS)" %}
{% code title=".specifyrc.js" lineNumbers="true" %}

```javascript
module.exports = {
  version: '2',
  repository: '@acme-inc/design-system',
  personalAccessToken: '<your-personal-access-token>',
  rules: [
    {
      name: 'Generate colors as CSS Custom Properties',
      parsers: [
        {
          name: 'convert-color',
          options: {
            toFormat: 'rgb',
            applyTo: {
              collection: true
            }
          }
        },
        {
          name: 'to-css-custom-properties',
          output: {
            type: 'file',
            filePath: 'colors.css'
          },
          options: {
            tokenNameTemplate: '--{{groups}}-{{token}}',
            selectorTemplate: '[data-theme=\'{{mode}}\']',
            includeCoreTokensInScopes: true
          },
        },
      ],
    },
  ],
};
```

{% endcode %}
{% endtab %}

{% tab title="JSON" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json

{
  "version": "2",
  "repository": "@acme-inc/design-system",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Generate colors as CSS Custom Properties",
      "parsers": [
        {
          "name": "convert-color",
          "options": {
            "toFormat": "rgb",
            "applyTo": {
              "collection": true
            }
          }
        },
        {
          "name": "to-css-custom-properties",
          "output": {
            "type": "file",
            "filePath": "colors.css"
          },
          "options": {
            "tokenNameTemplate": "--{{groups}}-{{token}}",
            "selectorTemplate": "[data-theme=\"{{mode}}\"]",
            "includeCoreTokensInScopes": true
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

Here is the input returned by Specify and the output generated by Specify after executing our configuration.

{% tabs %}
{% tab title="Input (Before)" %}
{% code lineNumbers="true" %}

```json
{
  "colors": {
    "$collection": { "$modes": ["Light", "Dark"] },
    "core": {
      "blue-100": {
        "$type": "color",
        "$description": "token 1 aliased with n modes within collection within n groups",
        "$value": {
          "Light": {
            "red": 219,
            "blue": 254,
            "alpha": 1,
            "green": 236,
            "model": "rgb"
          },
          "Dark": {
            "red": 41,
            "blue": 67,
            "alpha": 1,
            "green": 52,
            "model": "rgb"
          }
        }
      },
      "blue-700": {
        "$type": "color",
        "$description": "token 2 aliased with n modes within collection within n groups",
        "$value": {
          "Light": {
            "red": 17,
            "blue": 249,
            "alpha": 1,
            "green": 125,
            "model": "rgb"
          },
          "Dark": {
            "red": 96,
            "blue": 250,
            "alpha": 1,
            "green": 168,
            "model": "rgb"
          }
        }
      }
    },
    "semantic": {
      "background": {
        "button": {
          "primary": {
            "hover": {
              "$type": "color",
              "$description": "alias token with n modes within collection within n groups",
              "$value": {
                "Dark": {
                  "$mode": "dark",
                  "$alias": "colors.core.blue-100"
                },
                "Light": {
                  "$mode": "light",
                  "$alias": "colors.core.blue-700"
                }
              }
            }
          }
        }
      }
    }  
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="Output (After)" %}
{% code title="colors.css" lineNumbers="true" %}

```css
[data-theme="dark"] {
  --core-blue-100: rgb(41, 52, 67);
  --core-blue-700: rgb(96, 168, 250);
  --semantic-background-button-primary-hover: var(--core-blue-100);
}
[data-theme="light"] {
  --core-blue-100: rgb(219, 236, 254);
  --core-blue-700: rgb(17, 125, 249);
  --semantic-background-button-primary-hover: var(--core-blue-700);
}
```

{% endcode %}
{% endtab %}
{% endtabs %}
