3 min read

Low-code First Impressions

Over the past three days, I used a low-code tool to build a working prototype of an administrative dashboard, which is updated in real time by a companion mobile app for users.

Overall I am pleased with what Retool enabled me to create. I made two barebones applications in a matter of days.

This was my first experience with low-code software, so what I’m writing here is raw. I’m going to share my experience and the main takeaways below.

The Good Parts of Low-Code

  • Fast creation/deployment of database resources
  • Fast creation of UI elements with decent default styling
  • Everything is in the same place (i.e. less context switching between terminals / editors / browser tabs )

The best part of using a low-code tool by far was being able to deploy instantly. I avoided pull requests, code reviews, pipeline delays, and other deployment-related processes that are safer but slower.

Having everything in one place also saved time and reduced the mental overhead from context switching between repos, terminals, editors, and browser tabs.

In Retool, my queries were always at the bottom of the screen. The UI was always front and center. The frontend logic lived in a sidebar to the right. The only context switch comes when opening the database in a new tab.

The Bad Parts of Low-Code

  • New, quirky syntax to learn
  • Hidden “magic” variables and iterators do a lot of the heavy lifting
  • Sparse documentation on things developers care about (i.e. the nitty gritty)
  • Anything beyond the built-in functionality is frustrating to implement due to platform-specific limitations

My biggest frustration with Retool was its use of hidden iterators and other magic behind the scenes which isn’t always explained.

For example, a list collection component can iterate over the results of a query. There are typically two ways to achieve iteration in list components: item and [i]. The former does not seem to play well with any event triggers, or at least it was unclear to me how it connects to the “backend” logic. The latter plays well with the backend, but has its own caveats when combined with Retools syntax.

The tool tells you that you can access [i] as an iterator in the components and in your queries. What isn’t clear is how this iterator is passed to the “backend” and its queries.

In the queries, I often had to access the results of another query and use the magic [i] iterator like this: {{getSomeData.data.foo[i]}} while hoping that it would be in sync with whatever value is being passed from the component in the UI.

Surprisingly, this worked when the frontend component triggering the query was iterating over the same query. That is, UNLESS that component was a table, in which case I had to access a different object entirely. Queries triggered by table events looked like this: {{tableName.selectedRow.foo}}.

This kind of inconsistency only cost me a couple minutes of head scratching and searching through docs/forums, but it does underline the trade off I made by using the ~magical~ iterators and objects provided by Retool.

One other limitation (which the Retool team has indicated is a tracked feature request) is that table columns cannot be dynamically generated based on a custom transformation of a query. You must have a known number of table columns.

The limitation of the table highlights that there is only so much which can be accomplished with a low-code tool before it’s better to stick with what you know as a developer.

Final Thoughts

I believe low-code tools are great for simple MVPs that just need basic CRUD. It allows a product manager / developer to get important feedback on the core functionality and flow of an application.

In the future, if the project requires anything beyond the built-in functionality, I will seriously consider spinning up a small instance of whatever my existing stack is and jamming there instead.

As soon as I was beyond basic CRUD, I started to miss the tools of my trade.

Using low-code tools, I found it hard to deliver anything more complicated than a few tables when I was missing powerful tools such as:

  • version control
  • type checking
  • linting
  • the full suite of the browser’s developer tools

Low-code tools are in a strange gray area for me. I see them as extremely valuable for the first 10% of developing a product, but can’t imagine using them for anything beyond that.

Time will tell if I come to lean on low-code tools more in the future. For now, they’re worth a shot for testing new ideas without spinning up new resources in the existing stack.