Data and workflow naming conventions
Use names to make the app searchable
Naming conventions are mostly about search and handoff.
If another developer cannot quickly find the backend workflow, field, reusable element, custom event, or option set they need, the app is harder to maintain. Bubble does not give you the same file structure and type navigation you get in code, so names carry more weight.
A backend workflow called send_welcome_email is better than new_user. A reusable element called Header Dashboard is better than Group Header if the app has several headers. A data type called Subscription Invoice is better than Invoice if the app also has Stripe invoices, internal invoices, or supplier invoices.
The exact convention matters less than having one. I would rather take a slightly ugly convention used everywhere than a theoretically nice convention used in half the app.
Signal the type where it helps
Names should help you see what type of value you are dealing with in the Bubble editor.
For primitive fields, we generally like compact names:
isArchivedfor a yes/no fieldstripeCustomerIdfor a text fieldsortOrderfor a number fieldarchivedAtfor a date field
For richer Bubble objects, Title Case is usually easier to scan:
Project Memberfor a data typeSubscription Planfor an option set or data typeOrder Statusfor an option set
The reason for this is simple. When you see Current User's isAdmin is yes, you know you are reading a yes/no field. When you see Current User's Role, you are probably reading an option set or linked data type.
If an app already has a clear field naming convention, follow that. The important bit is that fields, option sets, data types, custom states, reusable properties, and workflow parameters do not all blur together.
Do not add option set prefixes by default
I generally would not prefix every option set with OS, Option Set, or similar.
In most apps, User Role is easier to read than OS User Role. Order Status is easier to read than Option Set Order Status. Bubble's expression editor usually gives enough context, and the app's data model should make the type obvious.
Use a prefix only when it removes a real ambiguity. If you have a data type called Plan and an option set called Plan, fix the naming. That might mean Subscription Plan for the option set and Plan Feature for the data type, or it might mean a prefix if the app already uses that convention.
The same applies to option values. In an Order Status option set, use Draft, Awaiting Payment, Confirmed, and Cancelled. Do not write Order Status - Draft unless the repeated label helps in a specific expression or admin view.
Use option sets for product constants
Option sets are good for values defined by the app, not records users manage as source-of-truth data.
Good option-set candidates:
user roles
order statuses
subscription plan types
fixed page tabs
permission groups
supported countries, if the list is controlled by the product
Use a data type when users or admins need to create, edit, archive, permission, search, audit, or report on the records.
For example, Order Status is probably an option set. Product Category might be an option set in a small marketplace where the categories are fixed. It should probably be a data type if the client needs an admin page to add categories, reorder them, translate them, or report on them.
Option sets also do not need to be duplicated for every page. If a single-page app has separate tab option sets for Dashboard Tabs, Settings Tabs, and Billing Tabs, check whether one Tab option set with a Pages attribute would be cleaner. Each tab can say which pages it belongs to, and the page can filter the tabs it displays.
The same pattern works for statuses. You might have one Status option set and a Status Type attribute rather than separate option sets for order statuses and shipment statuses. Draft, Completed, and Cancelled can apply to both. Out For Delivery can apply only to shipments.
Do not force this if the concepts behave differently. Similar names are not enough. The options should share enough behaviour that one option set makes the app clearer.
Name backend workflows by how they run
Backend workflow names should make the trigger obvious.
There is a specific Bubble gotcha here: database trigger names can conflict with backend workflow endpoint names. If you have a database trigger called invoice and a backend workflow endpoint also called invoice, calling the endpoint may return a workflow-not-found style error while the trigger still runs.
So avoid generic backend names like invoice, customer, or subscription when the app has webhooks, database triggers, backend custom events, and scheduled workflows around the same thing.
Use names like:
endpoint_stripe_invoice_createdfor a backend workflow called by Stripe or the API Connectortrigger_invoice_updatedfor a database triggerevent_sync_invoice_statusfor a backend custom eventtask_send_trial_expiry_remindersfor a scheduled backend workflow
You do not need these exact prefixes. You do need a convention that lets a developer tell whether the workflow is an endpoint, database trigger, custom event, or scheduled task before opening it.
This matters most around payments and integrations. Stripe apps often have workflows for invoice, customer, subscription, payment, and checkout. Plain nouns are too easy to collide and too vague to debug.
Keep external endpoint names stable
Be careful renaming public backend workflows.
If a Stripe webhook, API Connector call, external service, or another Bubble app calls the endpoint URL, changing the endpoint name can break the caller. Rename internal custom events freely if it makes the app clearer. Rename public endpoints only when you can update and test every caller.
For existing apps, I would usually clean up names in this order:
backend workflows with vague or conflicting names
data types and option sets that are hard to search
reusable elements with generic names like
Group Maincustom states and reusable properties that hide their type
Do not rename everything for tidiness. Rename things that slow down debugging, confuse handoff, or make Bubble expressions harder to read.
Rule of thumb
Use the shortest name that tells another developer what the Bubble thing is and why it exists.
For fields, signal the value type where useful. For option sets, avoid arbitrary prefixes unless they remove confusion. For backend workflows, include whether the workflow is an endpoint, trigger, custom event, or scheduled task.