Skip to content

Code File (Custom Classes) Docs #363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 30, 2025
195 changes: 195 additions & 0 deletions docs/ff-concepts/adding-customization/code-file.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
---
slug: /concepts/custom-code/code-file
title: Code File
description: Learn how to create and use custom classes and enums in FlutterFlow.
tags: [Code File, Custom Code]
sidebar_position: 5
keywords: [FlutterFlow, Custom Classes, Custom Enums, Customizations, Flutter, Dart, Pub.dev]
---

# Code File

FlutterFlow allows you to add your own custom Dart files with [classes](https://dart.dev/language/classes) and [enums](https://dart.dev/language/enums). This means you can create reusable building blocks to manage your app’s data and logic more easily. Using custom classes, you can create custom data types, use their properties in the UI, call methods in action flows, and much more.

## Key Use Cases

- **Custom Models**: Define your own data models, such as `UserProfile`, `Product`, or `Order`, and use them throughout your app.
- **Business Logic**: Add reusable utility methods like tax calculations, formatting, or conditional evaluations.
- **Reusable Enums**: Define enums and use them in UI conditions and dropdowns.

:::warning[Limitations]

- **No Generics:** Classes with generic types (e.g., `class ApiResponse<T> {}`) are currently not supported.
- **No Function-Typed Parameters:** Methods or fields that have function types as parameters or fields are ignored (e.g., void Function(int) onTap).
- **No Extensions:** Dart Extensions (e.g., `extension StringX on String { … }`) are not supported yet.

:::

## Add Custom Class

To add a custom class, go to the **Custom Code** from the left navigation menu, click **plus (+)** button, and select **Code File**. Set the name of the file, add your code, and hit the **Save** button. Now, you must **validate** your code in the editor to catch basic syntax errors. If there are no errors, click the **Parse** button. FlutterFlow will scan your code and automatically detect supported classes and enums.

Here’s an example of adding a Review custom class:

<div style={{
position: 'relative',
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding
height: 0,
width: '100%'}}>
<iframe
src="https://demo.arcade.software/sX8BKGhdsUGj7IZJCSpN?embed&show_copy_link=true"
title=""
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
colorScheme: 'light'
}}
frameborder="0"
loading="lazy"
webkitAllowFullScreen
mozAllowFullScreen
allowFullScreen
allow="clipboard-write">
</iframe>
</div>
<p></p>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

admonition tip somewhere that we can add any imports in our custom classes and can refer to any generated classes too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!


## Create Class Instance

You need to create an instance of a class so you can work with actual data and use the class’s properties and methods in your app. Here’s a simple explanation:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mention how it is similar to datatype instance and point to that doc?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean point to here or here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we don't have any docs in custom data type about creating a datatype instance?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we don't have it yet.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you create a linear ticket for the same and reference this PR comment?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


- A **class** is like a blueprint or template. For example, the `Review` class describes what a review is, but doesn’t hold any real review information itself.
- An **instance** (or “object”) is a real, usable item made from that blueprint. See the code snippet below:

```jsx
Review review1 = Review(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THis may be incomplete if we don't show the code for the Review class first. I know its added to the Arcade but its not enough since the rest of the explanations is so tied to the Review class, but we dont show the class definition in code here. I'd suggest add the Review class snippet after the Create Custom Class Arcade

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree! added.

'r001',
'p123',
'u456',
'Alex Morgan',
'Great quality T-shirt!',
4.5,
DateTime(2025, 5, 22),
3,
ReviewStatus.approved,
);
```

- You can reuse the same class structure multiple times with different review data.

When you create an instance of a class, you can:

- Store actual review details.
- Access and update the fields (e.g., `review1.rating` or `review1.comment`).
- Call methods that do something with that data (e.g., `review1.markHelpful()` or `review1.shortComment()`).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another point where these methods are confusing because we dont have the code for Review class somewhere here where we can reference it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, now worries. added the code snippet for the Review class.


To create an instance of a custom class, open the **Set from Variable** dialog and select **Create Custom Class Instance**. Choose the class you want to use, then select the class name from the **Constructor** dropdown. After that, set values for each of the required fields.


<div style={{
position: 'relative',
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding
height: 0,
width: '100%'}}>
<iframe
src="https://demo.arcade.software/0CQju0ZUuhOEnkRhbxP4?embed&show_copy_link=true"
title=""
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
colorScheme: 'light'
}}
frameborder="0"
loading="lazy"
webkitAllowFullScreen
mozAllowFullScreen
allowFullScreen
allow="clipboard-write">
</iframe>
</div>
<p></p>

:::tip[When You Don't Need an Instance]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldnt call it a tip rather its a feature. Im afraid this entire section with the description (for e.g "skip instance creation" language) can make non coders feel like this is the easiest approach so lets go with it, and they will have static methods everywhere and more bugs because the logic will not work the way a non static class is expected to work.

We should treat it as its own section and talk about when its useful with more examples

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, in that case, let's remove (comment out) this part and revisit with more detail!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it will take more time to rewrite this part?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see a bunch of new actions under custom class, see here: https://linear.app/flutterflow/issue/SUP-2529/custom-class-method-is-not-appearing-in-actions-list#comment-34cd1a72
also some related to static fields. I think it should be covered in the v1 version of the docs (as a separate section)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you say this 'should be covered in the v1 version of the docs' you mean in this PR only right? yes, we can do it. Could you please help with that ticket? it is is not opening for me.
Screenshot 2025-05-27 at 5 18 17 PM

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes in this PR, can you check the linear ticket again?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Added a new 'Using Static Classes' section.


You can skip instance creation when everything in the class is `static`, meaning it's shared across all uses (like a utility class). For example, look at the class below:

```jsx
class Utils {
static int square(int x) => x * x;
}
```

In such cases, you can directly access the class data and methods via the **Set from Variable** menu.

![static-class-methods.avif](imgs/static-class-methods.avif)
:::

## Using Custom Class

Once the custom class is added successfully, you can access its fields and methods in the Variable Dialog, call its methods in the Action Flow Editor, assign instances to state variables, pass them to page or component parameters, and use enum values in dropdowns or conditionals.

### Data Types

You can select your custom class as a Type for variables, state, or parameters, just like a [Custom Data Type](../../resources/data-representation/custom-data-types.md).

![custom-class-as-data-type.avif](imgs/custom-class-as-data-type.avif)

### Access Fields and Methods

You can use custom class fields to display values directly in the UI, and call its methods in variable dialogs to return a result.

![access-fields-methods.avif](imgs/access-fields-methods.avif)

### Call In Action Flows
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this is more important to show with an Arcade. and if I remember correctly this is not the name of the action. we must have the action name the way we do it for other features.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right. However, there's currently an issue where custom class methods aren't showing up in the actions list, so I’m unable to see any details or record the arcade.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added now!


You can also add your custom class’s methods directly within an Action Flow. For example, you can trigger the `markHelpful()` method when a user taps a “Mark as Helpful” button to update a field or increment the helpful count of a review.

## Enums
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its ###?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

definitely the name shouldnt be just Enums, same reason as Data Types comment. Custom Enums?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the name to "Custom Enums" but kept the heading as ## only to avoid nesting it under "Using Custom Classes." Since enums are different from classes, I think they deserve their section.


Similar to how you add a custom class, you can also add Custom Enums in your app. [Enums](../../resources/data-representation/enums.md) are a great way to define a fixed set of values, such as user roles, order statuses, or content types. Once parsed, these enums become available throughout your app and can be used in dropdowns, conditionals, and UI bindings.

For example, you could define an enum called `ReviewStatus` with values like `pending`, `approved`, and `rejected`.

![custom-enums.avif](imgs/custom-enums.avif)

You can access the custom enums from **Set from Variable** menu > **Custom Enum** section. You’ll see your Dart file listed by name. Select the enum you want to use, such as `ReviewStatus`, and then choose the specific value you want to assign.


<div style={{
position: 'relative',
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding
height: 0,
width: '100%'}}>
<iframe
src="https://demo.arcade.software/wFd9NKYGdb2Jp7ZYkaR8?embed&show_copy_link=true"
title=""
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
colorScheme: 'light'
}}
frameborder="0"
loading="lazy"
webkitAllowFullScreen
mozAllowFullScreen
allowFullScreen
allow="clipboard-write">
</iframe>
</div>
<p></p>

## Tips & Best Practices

- Keep your custom class files modular and focused; ideally one class per file for better organization and reusability.
- Avoid advanced Dart features that are not supported by FlutterFlow’s parser, such as generics or function-typed fields.
- Re-parse your code after making changes to ensure FlutterFlow updates the parsed structure correctly.
- Document your code with comments to make your custom classes easier to understand and maintain over time.
2 changes: 2 additions & 0 deletions docs/ff-concepts/adding-customization/custom-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ There are a few different ways to make custom code accessible in FlutterFlow:

* **[Custom Functions](custom-functions.md):** Custom Dart functions that can be used to set Widget or Action properties.
* **[Custom Actions](custom-actions.md):** Custom Dart functions that can be triggered by [Action Triggers](https://docs.flutterflow.io/resources/functions/action-triggers/) or used as nodes in an [Action Flow](https://docs.flutterflow.io/resources/functions/action-flow-editor#action-flow-editor). These are usually `async` functions and are able to import [custom package dependencies](#adding-a-pubspec-dependency).
* **[Code File](code-file.md):** You can define custom classes, enums, and logic to manage your app’s data and behavior.
* **[Custom Widgets](custom-widgets.md):** Custom Flutter widgets that can also import [custom package dependencies](#adding-a-pubspec-dependency) and be used in the same way as [Components](https://docs.flutterflow.io/resources/ui/components) throughout your project.
* **[Configuration Files](configuration-files.md):** You'll have the ability to edit native files for Android and iOS.



:::tip[Why Write Custom Code?]

- **Extend Functionality:** Add features that are not included in the standard FlutterFlow
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.