Skip to main content

Using Codebase Components

warning

As this is still a closed beta feature, you may not be able to use it. Contact us at founders@firejet.io for access.

FireJet allows you to use components from your codebase in the outputted code, which minimises the amount of changes you have to make to the output code.

For example, if you have cards, or buttons in your codebase, you can link them to FireJet and the cards and buttons from your codebase will be used in the code generation instead of being generated from scratch.

Getting started

First, you need to install the FireJet CLI via npm, in your project root

npm i @firejet/cli
--or--
yarn add @firejet/cli

After installation you can run npx firejet to use the cli commands

Logging in

You can login by running npx firejet login. A new browser window will be opened where you will be instructed to login.

note

You need to login with the same account that you use in the FireJet plugin for your components to sync properly.

Creating the Components Config

You need to make a .firejet.config.(ts|js) file to tell firejet which components should be used in the output code, and how they should be used

You can generate a skeleton file by running

npx firejet init <optional-path>
# Example
npx firejet init
# Example 2
npx firejet init .

The default location for this file will be your repository's root, but you can place it elsewhere as well but you will need to manually specify the location of the file when registering components in that case.

Let's say you have the following react component

src/components/Card.tsx
import React from 'react';

export function Card({
title,
children,
}: {
title: string;
children: React.ReactNode;
}) {
return (
<div className="p-2 rounded-md shadow-md flex flex-col gap-2">
<span className="text-lg">{title}</span>
{children}
</div>
);
}

You can register the component with the following config

({
globalCss: ['./src/index.css'],
viteConfig: undefined,
components: {
Card: {
file: './src/components/Card.tsx',
defaultExport: false,
exportName: 'Card',
props: {
title: { type: 'element', implementation: 'literal'},
children: { type: 'element', implementation: 'literal'}
}
}
}
})

To see a more extensive example of the firejet config you can click here

Tailwind CSS

Tailwind CSS is automatically supported by us, but make sure your tailwind base styles are imported in the global CSS

src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
{
//Add to your firejet config
globalCss: ['src/index.css'],
}

Adding components from the config

Once you have setup your .firejet.config.(ts|js) file, you can add them to your project by running:

The project name will be used in Figma for you to select which components to use when exporting your design. It DOES NOT have to match your project's path.

We recommend calling your default project project, which is the last argument in the command, as shown in the sample.

Right now components from all projects will be used by default, but in the future there will be support to select components from different projects

npx firejet component add-from-config <project-name>
# Sample
npx firejet component add-from-config project

If there are any errors during this step, you can refer to the debugging section on this page to resolve the issue, or contact us on our discord or via email at founders@firejet.io

Using the components in Figma

Code base components

In order to use the codebase components in the output, select the Use Codebase Components checkbox. Right now it uses components from all projects - we are working hard to allow you to select between projects

Making sure components are detected

If your components are not being detected, you can enter debug mode by clicking the bug icon above the design. The bug icon is only visible when use existing components is enabled.

Debug icon

After clicking the debug icon, you will be able to see a skeleton view of your project.

Design skeleton view

FireJet detects components by comparing the skeleton view of the generate code with the components from your codebase and then performing a fuzzy match between the two.

We compare the following:

  1. The child structure must be the same
  2. For each child on the tree, the styles must be roughly the same
note

The sizes of components don't need to match - only the ordering of parent and child boxes

Component Skeleton View does not look like code component

If the component rendered in firejet does not look like the one from your codebase, ensure your global css imports are properly setup, and if you have custom build settings that are required for your component to work, make sure your vite config is properly setup as well.

Debugging structure mismatches

To debug differences in the structure, you can select your component in the components tab in debug mode to view the tree structure

Component skeleton view

The skeleton view of your component must match the skeleton view of the node you expect it to match in the design view. You can see the full skeleton view from the design by hovering over the component that failed to match.

Hovered green outline

From the green outlines, you can see which nodes are the children of the parent node, and you can ensure that it matches the component on the left.

Debugging style mismatches

If the tree structures match, such as in the above example, then you will need to ensure that the styles are able to match.

It could be that your props are not flexible enough for FireJet to perform the match, or if the props are meant to be fixed, the color in the rendered sample may be too different from the output.

We perform the following checks

CheckDescriptionSuccess Condition
ElementHTML Element or Text passed as a propAlways matches
Non-TextStatic HTML Element part of the componentFuzzy matching styles or has css-class prop
ImageAn image elementImage render looks simlar or has image-src prop
TextStatic text element part of the componentString must be an exact match

You can compare your codebase component with the generated code to see what the difference possibly is and the cause of the mismatch

Removing components, Removing Projects, Listing Components

Right now, while the feature is in beta there will be several changes to the CLI. However, you can use npx firejet --help to check the latest available features and use them.

Global CSS

In the Global CSS field, you will want to specify any CSS that is available globally. FireJet injects the CSS from these files into the global scope when styling your components, and if the global styles are not injected into your components, they may look different, resulting in FireJet being unable to detect your components properly.

Vite Config

Detecting existing components in your components requires our algorithm to capture rendered snapshots of your components. In case your components are unable to be rendered because of custom build settings, you can optionally pass a custom vite config object in order to ensure your component renders correctly.

Full FireJet Config

Full Sample

({
globalCss: ['/path/to/global/css/file1.css', '/path/to/global/css/file2.css'],
viteConfig: undefined, //If your components are not rendering properly you can provide a custom vite config, otherwise leave this empty
components: {
React: {
exportName: 'ReactComponentName',
/**This should be relative or absolute from where the firjet cli is invoked */
file: './relative/path/to/component.tsx',
/**Props definitions are used to tell firejet */
props: {},
/**When set to true, will get the component as the default export from the file.
* Otherwise will get the component by the key in the dictionary. */
defaultExport: false,
},
Vue: {
exportName: 'VueComponentName',
file: './relative/path/to/component.vue',
props: {
/**element is any valid element in html, like "<div>Hello</div>, or even just the text "Hello"
* literal means literally the element, like "Hello"
* implementation defaults to 'literal' if not specified
*/
title: { type: 'element' },
title2: { type: 'element', implementation: 'literal' },
/**function means to get the value, you have to call a function, like () => "Hello"
* The function must not require any arguments
*/
text: { type: 'element', implementation: 'function' },
/**
* object is a nested Record<FJ.Any> in JS, where you can nest your props
*/
author: {
type: 'object',
implementation: {
name: { type: 'element' },
title: { type: 'element', implementation: 'literal' },
},
},
/**image-src is for any string used as the source for an image
* implementation defaults to 'string-literal' if not specified
*/
src: { type: 'image-src' },
src2: { type: 'image-src', implementation: 'string-literal' },
/**
* boolean is for any true/false value
* Can be implemented as literal or function
*/
isVisible: { type: 'boolean' },
/**
* css-class is for any css classes
* Accepts values like 'custom-css-class' or 'p-2 rounded-md' for tailwind
* Can be implemented as string-literal
*/
className: { type: 'css-class' },
/**
* function is for stubbing any functions that need to be accepted by the component
* Accepts values like '(text) => log(text)'
* Can be implemented as any function
*/
onClick: { type: 'function' },
},
},
Svelte: {
file: './src/components/Button.svelte',
props: {},
exportName: 'SvelteComponentName'
},
},
})

Types

type FireJetConfig = {
groups: {
[x: string]: {
components: {
[x: string]: {
path: string;
defaultExport?: boolean | undefined;
exportName?: string | undefined;
importOverride?: string | undefined;
structure?: any;
dependencies?: {
[x: string]: {
path: string;
defaultExport?: boolean | undefined;
exportName?: string | undefined;
importOverride?: string | undefined;
};
} | undefined;
};
};
globalCss: string[];
viteConfig?: {
[x: string]: any;
} | undefined;
postcssPath?: string | undefined;
reactProviders?: {
[x: string]: {
path: string;
defaultExport?: boolean | undefined;
exportName?: string | undefined;
importOverride?: string | undefined;
};
} | undefined;
defaultExport?: boolean | undefined;
};
};
referenceDesigns?: {
[x: string]: {
url: string;
xpath?: string | undefined;
};
} | undefined;
};

Debugging

Component unable to be added

You can pass the --verbose flag to firejet during the npx firejet component add-from-config command to get additional data why the component adding fails

How do I run a command from the CLI that is not in the docs?

You can get information on all commands using npx firejet --help, if you are still unsure you can contact us in our discord or via email.

Component not being detected properly in output code

If your component is not being detected properly, please contact us in our discord, or at founders@firejet.io for us to help resolve the issue