6 tips for best practices in Retool

Isaac Pearl
Fender Engineering
Published in
6 min readFeb 28, 2023

What is Retool?

Retool is a user-friendly low-code WYSIWYG front end platform built to enable rapid development of internal applications. At Fender, we’re using it to create prototype clients in support of API development, and to build dashboards for our customer support team to adjust user data in production.

Although a big part of what makes Retool an attractive option is its ease of use and forgiving learning curve, projects can become disorganized and difficult to maintain if developers disregard best practices. Once you’ve gotten the hang of the basics, it’s worth taking some time to develop good habits before working on more complicated applications. Here are 6 tips for implementing best practices in your Retool development process:

1. Isolate business logic from UI state

Part of what makes Retool so powerful is the ability to write JavaScript in nearly every text field. When you write JavaScript into the fields of a component’s Inspect tab, it’s important to keep that logic very “local” in scope. If you encode business logic about query interactions, input validation, etc directly into an inline text field, it’ll be much less convenient to find and refer to it later than if it was stored as a query or JavaScript transformer.

A good rule of thumb is to only leave JavaScript inline in components if the code itself is concise, and the behavior it describes only applies to that component (e.g. displaying a nested JSON property, toggling a visual state based on a boolean value elsewhere). If the code describes business logic that depends on or modifies other components’ state, it’s better to pull it into its own JavaScript transformer/query, where it can more easily be organized into a directory and referred back to.

An example of good inline JavaScript that hides a form when a query returns no results or encounters an error
An example of misplaced form input validation in a Button component’s “Disabled” field
The logic from the previous example should be moved into a dedicated JavaScript Transformer (here called validateTextInputs), and referenced from the Button like so

2. Make use of environment switching

In many real-world use cases, you will have data sources with multiple copies corresponding to different environments, such as Development, QA, and Production. Under Settings -> Environments, you can create as many environments as you need to mirror your organization’s development stages. Then, when you create Retool resources for your databases, APIs, and other integrations, you can save all per-environment copies as a single resource in Retool, and easily switch an application’s data sources by using Retool’s built-in environment switcher GUI:

Fender’s Retool environment switcher

3. Use consistent naming conventions

Like pure coding workflows, staying organized with consistent variable naming conventions will help you stay organized and make it easier for newcomers to a project to get oriented fast. In Retool, I like to stick with the following naming and formatting conventions:

Resources

  • Mirror their deployed title exactly for ease of cross-reference outside of Retool
  • Ex: “fds-gateway”, “user_deletion_requests”

Query Library

  • Camel case simplification of deployed title
  • Ex: A GraphQL query called “play_adminGetStreak” in our GraphQL schema becomes “adminGetStreak” in Retool’s Query Library

Application queries

  • Query Library imports: use same name as Query Library source
  • JavaScript queries/transformers: using camel case, describe the operation, then the underlying data, with more specificity than I might use in a Query Library name. Examples: getAggregatedUserData, validateSubscriptionDeleteForm

Components

  • Camel case, describe the query/data source it connects with, then the business logic operation, then the component type
  • Ex: setStreakSubmitButton, getStreakDisplayTable

Personal preference counts for a lot when it comes to variable naming, so it’s less important that your convention follows a particular form, and much more important that whatever you choose, you stick with it consistently across all variable names in your project.

4. Learn JavaScript ES6 functional programming syntax

Teaching ES6 JavaScript syntax is far outside the scope of this article, but it’s worth investing a little time into learning its concise arrow function notation and array methods, as doing so will allow you to write much cleaner and sophisticated inline JavaScript, especially when populating table rows with query results. This article I found by @Ajinkyax does a good job of summarizing how to use these language features.

Here’s an example of a Table component that uses a call to the ES6 array function .filter() to dynamically remove query results with a name longer than 20 characters:

5. Utilize the Retool community

When I’m stuck on implementing a niche or complicated feature, more often than not I can find someone else who’s worked on a similar or equivalent issue in the Retool community forum. Both community members and Retool employees are generally pretty quick to respond, and in my experience, Retool’s developers seem to take feature requests seriously. If you start to lose momentum on your project, don’t be afraid to reach out on the forum!

6. Minimize number of query calls

Some Retool applications need to make expensive queries in order to support their requirements, like admin dashboards that need to list all users in an environment, or applications that perform bulk processing with the help of external cloud functions. Others may have lots of interdependent queries that execute in a chain according to user input. When including queries like these in your project, it’s worth taking some simple steps to make sure you don’t call them any more than you have to.

If the data from a query doesn’t change often, and can just be fetched once in a while, it’s a good candidate for caching. Enable caching in a query’s “Advanced” settings page, and Retool will just save and return the most recent queried data until a time threshold has passed:

Once the cache duration has been met, the next run will fetch fresh data. Query results can be cached for up to 1 day — evaluate each query’s caching requirements on a case-by-case basis.

Another situation that can come up in complex projects is queries that get run unintentionally due to user interaction, like row selection and text input. It’s worth walking through the queries in your application to make sure that only the ones that absolutely require it from a UX perspective get run automatically when their inputs change. For many situations, it’ll make more sense to manually trigger a query via an event handler on a component or query success/failure state. To change this setting, navigate to the query in the bottom panel, and click the dropdown menu below the “Resource” menu:

Closing thoughts

Although Retool is pretty simple to get started with, it ultimately affords developers a lot of flexibility in how they write applications. Because there are many different ways to implement any given feature, developers that consistently use best practices in Retool will end up with easier-to-maintain projects and more performant experiences for their end users.

--

--