Option sets let you store a static list of options in a database-like structure, without using the database. They're useful for information like days of the week, marital status, colors, states, countries, and other data that you want to load quickly and that rarely changes.
Option sets can be used to store static options and use them around your app. In this example we have saved a list of colors as options in a set
What is an option set?
An option set becomes part of your app's source code, which means it's downloaded as part of the JavaScript file that makes up your app. Because of that, it doesn't require a database lookup, and it's cached on the user's device until you deploy a new version, making it fast to load and lightweight.
It also means an option set can't be added to, edited, or deleted by your users, and you have to redeploy your app before new options become available in Live.
Unlike the database, option sets aren't encrypted, and they become part of your app's source code. Option sets should never contain sensitive information.
How option sets are structured
An option set, as the name suggests, is a set of options. To each set you can add a list of attributes, which are similar to the fields on a data type. An attribute can be one of the following types:
text
number
date
date interval
yes / no
file
image
geographic address
[other Option sets]
To summarize: each option set is a collection of options that share the same attributes, each of one of the types above.
Option sets are often used to define a fixed set of values for a field on a data type. For example, in a blog platform you could create a Status option set with the options Draft, Review, and Published, then add a Status field on the Post data type that uses it. Every post then draws from the same fixed list, and you can't end up with typos or stray values like "publised".
A Status option set for a blog app, with the options Draft, Review, and Published stored in the built-in Display attribute.
Bubble doesn't require Display values to be unique, but it's worth keeping them unique anyway. If you later filter options by their Display value and you have duplicates, you may not get the results you expect.
Creating option sets
You create and manage option sets in the Data tab, in the Option sets section.
Create the set. In the Option sets section, type a name into the New option set field and click Create. Your new set appears in the list on the left.
Add options. With the set and its attributes in place, add the options themselves. For a City set, the options would be the cities you want to list, like Boston and Washington. Select the set, type a name into the New option field, and click Create. The name you enter is stored in the option's Display attribute.
Set up attributes. Add the attributes you need to describe each option. In many cases, the built-in Display attribute is enough to hold each option's main identifier, such as the statuses in this example. Let's add one more attribute that determines what user roles (another option set) that edit a blog post. Click Create new attribute and name it (for example, Can be edited by). The attribute will show up in the list of attributes on this option set. We've set the Can be edited by attribute to Editor, which is another option set that sets user roles.
Editing the attributes. To edit an option set's attributes, click the pencil icon next to the set in the list. This link only appears once you've created at least one option.
Using option sets
Unlike data types, you don't search for option sets. They're all loaded on page load, and you reference them in elements and workflows as needed.
Using option sets in an element
Unlike data types, you don't search for option sets. They're all loaded on page load, and you reference them in elements and workflows as needed.
Add a dropdown. Place a dropdown element on the page and give it a placeholder, such as Choose an option. This is the element your users will pick a status from.
Open the Choices property. In the element's property editor, find the Choices setting under Content.
Switch to Dynamic choices. In the Choices popup, select Dynamic. This lets you pull the options from an option set rather than typing them in by hand.
Set the type of choices. Select the Status in the Option set category.
Set the choices source. In Choices source, enter All options to load every option in the set. This is the key difference from data types: you don't search for the options, you load them all. To narrow the list, add the :filtered operator, such as All Status:filtered.
Set the option caption. In Option caption, choose which attribute to show as each option's label. Here we use Current option's Display, so the dropdown shows each status's Display value (Draft, Review, Published).
Using option sets in an expression
You can also use an option set as a data source in an expression. This example ties the linked option set together. The Status option set has a Can be edited by attribute pointing to a Role option set, and here we use it to save a post only when the current user's role matches the role allowed to edit that status.
Set up the event. Start a workflow from the user action that saves the post, such as Save post is clicked.
Add the Make changes action. Add a Make changes to a thing action, and set Thing to change to Current page's Post.
Add the condition. In the action's Only when field, build this condition: Current page's Post's Status's Can be edited by is Current User's Role. The action now runs only when the current user's role matches the Can be edited by role on the post's current status. If the roles don't match, the save is skipped.
Option sets versus data types
Option sets and data types both let you store structured information, but they serve different purposes. Choosing between them comes down to whether the information is static and known in advance, or dynamic and tied to user actions. The two also have very different security profiles.
Security
Option sets and data types are stored and accessed in fundamentally different ways, which has direct security implications. Choosing the right one for a given piece of information is as much a security decision as a structural one.
Option sets are part of your app's source code
Option sets are included in the JavaScript files Bubble sends to the client when your app loads. Every option set, including all its options and their attributes, is visible in your app's source code. Anyone who inspects the page in their browser's developer tools can see the full list.
This is by design. Option sets are meant for static, non-sensitive information the app needs instantly, like categories, statuses, or fixed configuration values. The trade-off for that speed is visibility.
For this reason, never use an option set to store:
API keys, tokens, or other credentials
Internal business logic that shouldn't be exposed
Information about features you don't want users to discover
Any value that needs to be hidden from the client
Data types are stored in an encrypted database on the server
Data types live in the database, on the server. The client only receives data type records when it explicitly requests them, and only the fields it's allowed to see. That makes data types the right choice for anything sensitive, dynamic, or tied to specific users.
The key security mechanism for data types is privacy rules. They let you control who can see which records and which fields, evaluated on the server before any data reaches the client. With privacy rules in place, sensitive fields can be hidden entirely from users who shouldn't have access, even when the rest of the record is visible.
Comparison
Feature | Option set | Data type |
How is the data stored? | In your app's source code | In the database, server-side and encrypted |
How is data created? | Defined in the editor at build time | Created at run time or in Bubble's database editor |
When is it loaded? | Whenever any page loads | Only when requested |
When is it updated | On first page load after app has been deployed | Instantly |
Who can modify the data? | The app developer | Users, workflows, and the app developer |
Performance | Loaded instantly with the app | Fetched from the database when needed |
Privacy rules | Not supported | Supported |
Suitable for sensitive data | No, since values are visible in the source code | Yes, when protected by privacy rules |
Editable in run mode | No | Yes |
Typical examples | Categories, statuses, country lists, fixed configuration values | Users, orders, blog posts, messages |
When to use which
Use an option set when:
The values are known in advance and won't change based on user actions
The list is relatively short and stable, like a set of statuses or categories
You want the values available instantly, without a database lookup
You don't need privacy rules to control who can see the values
Use a data type when:
The data is created, updated, or deleted by users or workflows
The number of records can grow over time
You need privacy rules to control access
The data is tied to specific users or other database records through relationships
In practice, most apps use both. Option sets handle the fixed structure of the app, while data types hold the dynamic content users interact with.
Creating option sets with Bubble AI
You don't have to build option sets by hand. Bubble AI can create them for you from a plain-language description, including the options and their attributes, which is often the fastest way to set one up.
Ask the Bubble AI Agent for what you need, and it builds the option set in your app. You can then review it, adjust it, or keep prompting to refine it. A few examples of prompts you could give Bubble AI:
Create a Status option set with the options Draft, Review, and Published.
Create a Country option set with an attribute for the two-letter country code.
Create a Role option set, then add a Can be edited by attribute to my Status option set that links to it.
Because option sets are static, the Agent defines them in the editor the same way you would, so everything covered in this article still applies to what Bubble AI creates. You stay in full control: review what the Agent built, edit any option or attribute directly, and redeploy when you're ready for the changes to reach your live app.
This is a quick look at using Bubble AI for option sets. To learn more about building with Bubble AI and the Bubble AI Agent, see the article below.
FAQ: Option sets
What is an option set?
What is an option set?
An option set is a static list of predefined values stored in your app's source code. Option sets are used for information that doesn't change based on user actions, such as categories, statuses, country lists, or fixed configuration values.
How is an option set different from a data type?
How is an option set different from a data type?
Option sets are static and stored in your app's source code, while data types are dynamic and stored in the database. Option sets are defined at build time and don't change based on user actions, whereas data types can be created, updated, and deleted by users and workflows.
Read more in Option sets versus data types.
Can option sets be modified at run time?
Can option sets be modified at run time?
No. Option sets are part of your app's structure and can only be modified in the editor. If you need values that can change based on user actions, use a data type instead.
Are option sets visible to users?
Are option sets visible to users?
Yes. Option sets are included in your app's source code and visible to anyone who inspects the page in their browser's developer tools. This includes all of an option set's data, not just its names. Don't use option sets to store sensitive information.
Can I add custom attributes to options?
Can I add custom attributes to options?
Yes. Each option set can have its own attributes, similar to fields on a data type. Attributes can be text, numbers, dates, yes/no values, or references to other option sets. They're useful for storing related information alongside each option, such as a display label or a color code.
How many options can an option set have?
How many options can an option set have?
Option sets are designed for small, static lists. There's no strict limit, but very large option sets can slow down your app's load time, since the entire set is included in the source code. If you find yourself with a long or growing list, consider a data type instead.
Can I apply privacy rules to an option set?
Can I apply privacy rules to an option set?
No. Privacy rules only apply to data types. If you need to control who can see certain values, store them in a data type and use privacy rules to restrict access.
When should I use an option set instead of a data type?
When should I use an option set instead of a data type?
Use an option set when the values are known in advance, won't change at run time, and don't need privacy controls. Use a data type when the values are dynamic, tied to users, or need access restrictions. Most apps use both, with option sets for fixed structure and data types for user-generated content.
See Option sets versus data types for more.
Can I convert an option set to a data type, or the reverse?
Can I convert an option set to a data type, or the reverse?
There's no built-in conversion tool. To switch, you'll need to recreate the structure manually in the other format and update any references in your app.
Can option sets reference each other?
Can option sets reference each other?
Yes. An attribute on one option set can reference another option set. This is useful when one set of options is related to another, such as a list of regions tied to a list of countries.
See Linking option sets.
How do I display options to users?
How do I display options to users?
Options can be displayed in dropdowns, radio buttons, and other input elements by setting the choices source to your option set. You can also reference specific options directly in dynamic expressions throughout your app. See Using option sets.
How do I search for or filter option sets?
How do I search for or filter option sets?
You don't search option sets the way you search data types, since they're already on the user's device and aren't part of the database. Loading an option set always returns all its options. To narrow that list, add the :filtered operator to the option set data source in a dynamic expression, then set your constraints inside the filter. You can also reference a single option directly without searching.
I changed an option set. Why can't I see the change in my live app?
I changed an option set. Why can't I see the change in my live app?
If you can't see the changes you've made, please check the following:
Changes in option sets are visible as follows:
Check that the Saving indicator next to the edit menu is showing Saved to confirm that the change has been synced to the Bubble server. If not, please check your internet connection.
Does Bubble only download the option sets used on a page?
Does Bubble only download the option sets used on a page?
No. All option sets are downloaded on every page, or the cached file is used if it's already on the user's device. Two things follow from this:
Avoid storing a lot of data in an option set, such as many long texts, since it can slow down page load and general performance.
Never store sensitive information in an option set, since it's visible in your app's source code whether or not it's used on the page.
Can an option set reference a database thing?
Can an option set reference a database thing?
No, an option set can't reference a database thing directly, since option sets are static and database records are dynamic. You can store a thing's unique ID in an option set, but this comes with risks:
Can an option set reference a database thing?
Can an option set reference a database thing?
Any database record can be deleted, which breaks the link.
A thing can have a different unique ID in your Live and Development databases, which can break the link when you deploy.
Exposing a unique ID isn't a vulnerability on its own, but it's generally not recommended, especially for things holding sensitive data. A visible unique ID combined with misconfigured privacy rules can open up vulnerabilities that would otherwise be harder to reach.
Other ways to learn
Core reference
Core reference
Get an option (loading an option set)
Video lessons
Video lessons
