Thunkable, Adalo, and the Future of Citizen Development

Thunkable ( empowers citizen developers to bring their app ideas to life. You can prototype your idea quickly, even if you have little or no coding experience, and build fully-functioning apps that can run on iPhone, Android or the web. This article describes why Thunkable is powerful as a citizen coding tool, and how Thunkable can become even better by adding some features now found in nocode tools like Adalo.

A citizen developer is someone who does not have a CS degree or years of coding experience, but wants to create software to solve problems. Citizen developers include designers who want to add interactive behavior to their creations, entrepreneurs who need to quickly create a working prototype of their idea, employees who are called on to solve tech problems or automate laborious tasks, and young people who want to build games and other software for their friends. Citizen developer is a newer term because our coding tools have only recently made such democratic app development possible.

Thunkable is a visual blocks coding language which originated from the educational tools Scratch and MIT App Inventor. Though often characterized as a “nocode” tool, Thunkable is a fully expressive coding language with “if” conditionals, loops, variables and functions, so you can build anything from games to study guides to data-oriented social apps. It is coding, but coding with a user interface!

Adalo is representative of nocode tools, an ever-growing subset of software development that includes bubble, webflow, and Zapier. These tools originated from the demand for software and automation in the corporate world, and the great expense of hiring traditional software engineers. No code tools like Adalo are more restricted in scope than Thunkable, but they provide an incredibly intuitive method of building simple data-oriented apps with user registration and login.

With Adalo, you first set up spreadsheet tables for the data in your app. You are provided with registration and login screens, and Adalo also generates data entry forms based on the data you’ve defined. You can quickly build an app that allows users to create, read, update, and delete the data stored in a spreadsheet (in software engineering, this functionality is called CRUD). Adalo has restricted functionality as it doesn’t provide the expressiveness of coding constructs like loops, conditionals, etc., but it is terrific for quick prototyping of apps in which users view and post information.

You can build data-oriented apps with Thunkable, but it doesn’t provide some of the database operations and screen generation that make Adalo development so easy. With respect to database operations, Thunkable doesn’t provide high-level blocks for filtering, sorting, and pagination of database data. If you were building a Music app and you wanted to display the first ten albums made just in the United States, sorted by artist, you’d have to load all of the entries and process them in-memory. Such in-memory processing requires sophisticated coding, even with blocks, and it isn’t efficient enough to work on large datasets. 

In terms of screen generation, Thunkable doesn’t automatically generate registration/login screens, or CRUD forms. It does provide templates for registration and login, but they’re not integrated with the app creation process. 

This article describes the Adalo-like features that should be added to Thunkable. With the additions listed here, Thunkable can match Adalo and other nocode tools’ ease of use, while also providing the flexibility that a tool with fully expressive coding provides. 

Provide Login Screens and User Ids

When a new project is created, Adalo generates screens for signup and login, and a database table for users that includes email, password, and username:

Adalo users can customize both the design of the generated screens, and customize the interactive behavior to an extent.

Thunkable currently provides some template screens for registration and login, and it connects to a third-party tool, Firebase, which handles some registration-login details, like email verification. But Thunkable’s templates and Firebase connectivity aren’t integrated into the project creation process, and there is no automatic generation of a database table with user information. Just setting up an app with basic login capabilities is challenging (see this tutorial), whereas it is effortless in Adalo.

Suggestions for Thunkable

  • When a new app is initiated, the tool should generate registration/login screens for the app, unless the coder chooses not to have them. Firebase can still be used to handle the back-end; the user should be prompted to create a Firebase project and provide the settings in their Thunkable app.
  • Thunkable should also add user id information to its Firebase mechanism for registration and login. Currently, you can only access an email and a password for each user, and not a user name, as shown in the Sign_In call block below, which communicates with Firebase:

Because user names aren’t included with the Sign_In component, the developer must create a separate spreadsheet to map emails to user names. As most apps rely on user names for tagging posts and communication amongst users, this facility should be provided by default.

  • Thunkable should add blocks to easily access the current user’s information and make tagging posts with author easier.

Generate Input Forms

Adalo will generate an input form for any database table that you define. When you choose to add an Input Form component to a screen, you’re prompted to select a database table. A form is then generated with entries for each of the table columns:

In the above example, the citizen coder has created a spreadsheet table with Name, Content, pic, and Author properties. The right side is a screen, auto-generated by Adalo based on the table, which prompts the user to enter the given data. 

A generating a form based on the structure of the defined data saves the developer time. More importantly, the generated screens and behavior also provides scaffolding– it is much easier to edit a generated screen and behavior than build it from scratch. Such scaffolding is a key tenet of many traditional software development tools including Ruby on Rails.

Currently, Thunkable doesn’t generate input forms.

Suggestions for Thunkable

  • When the user creates a new screen, provide a choice for creating an input form based on any data source (spreadsheet) that has been loaded. The generated form should include a default screen design along with the blocks to add a new entry to the data source when the user clicks on “Submit”.

Provide Data Query Filters

When an Adalo developer specifies the database table that a list view should display, it allows a filter to be specified. You can specify, say, that only those rows of the spreadsheet authored by a particular user are shown, or the people in a particular people list (group): 

Thunkable doesn’t provide such an easy mechanism for filtering. You can filter data “in-memory” by coding blocks that load and loop through all the rows of a table, but it requires sophisticated coding skills and is too inefficient for anything other than small data sets.

Suggestions for Thunkable

  • Add a “filter” property for each Thunkable Data Viewer component and a form, in the Designer, for easily specifying the filter. Currently, the Data Viewer components only allow an entire table (spreadsheet) to be displayed, so behaviors like showing all posts by the current user can’t be specified.
  • Provide Thunkable blocks that allow a Data Viewer filter to be set dynamically (in blocks). Filtered query blocks would, for instance, allow for apps in which the user toggles between showing all posts and filtered posts.

    Note: Adalo doesn’t allow the filter for a view to be modified as the app runs. You can open a separate screen to show a filtered view, but you can’t allow the user to toggle a view within the same screen.
  • Modify Thunkable’s data source query blocks to allow a filtered list of the rows to be retrieved from a table. Thunkable provides query blocks for loading a column into a list variable for “in-memory” processing. However, it doesn’t provide a “filter” parameter on those blocks, so you can’t load in selected rows.

    Note: Adalo doesn’t provide a mechanism for retrieving data for “in-memory” processing, or coding constructs to process such data. 

Order By

When Adalo developers specify the data that should be displayed in a list view, the data can be sorted based on any column. 

Thunkable provides a “sort” block, but it only works on lists of scalar data. 

Suggestions for Thunkable

  • Add an “order by” property to the Thunkable Data Viewer components and allow any column of the given data source to be selected. 
  • Modify the data source query blocks to allow the retrieved list to be sorted.


Adalo automates pagination: when a user drags down in a list view, it loads the “next” rows from the database table. Adalo doesn’t provide flexibility in pagination– you can’t design a custom user interface for how the “next” or “previous” data is accessed.

Thunkable provides no support for pagination and indeed loads all data at once– there is no method for specifying how many items to retrieve or where to start. You can paginate in-memory, but it requires sophisticated coding and only works for small data sets.

Suggestions for Thunkable

  • Add start and count properties in Thunkable’s Data Viewer components, which can be set either in the Designer or dynamically in blocks. 
  • Add start and count properties to the data source query blocks.

Relational Data

When you create a table in Adalo, you can specify a type for each column, with one choice being “Relationshipl”. So you can define “linked records” such as a Group table having a column which refers to a list of Person records which are the group’s members. When you choose “Relatonship”, Adalo asks you if the relationship is 1-to-1, 1-to-many, or many-to-many:

Once a relational column is defined, Adalo lets you choose it as a filter. Using such a scheme allows you to, for instance, access the members in a particular group.

Thunkable allows data sources to be either AirTable or GoogleSheets. AirTable allows linked records to be defined, Google Sheets does not. Thunkable doesn’t, however, provide blocks to access data based on linked records (e.g., get all the persons in a group)

Suggestions for Thunkable

  • Generate data source query blocks for accessing and modifying sub-lists defined by “linked records”. A linked record is a column which stores either one or a list of references to another table (spreadsheet). So a Group table might have a linked record column that refers to a list of entries in a Person table. 

For the Person-Group sample, Thunkable would generate a block of the following form:

getLinkedPersons in ^Sheet1
    in Group <
    start <
    count <
    orderBy <

which would return a list of Person objects.

  • Blocks should also be provided for adding an item to a linked record. For instance, Thunkable should generate the following blocks for the Person-Group sample:
addPerson in ^Sheet1
    in Group <
    personRowId <

Structured Objects

In Adalo, all data is structured: you define the columns of each table statically. This structure eases development because the citizen coder can choose properties as opposed to typing in a key.

In Thunkable, when you load a row in from a spreadsheet, it is placed in a list of unstructured objects. The field names are “data” along with the values.

Suggestions for Thunkable

  • Provide explicit blocks for accessing the properties of any object retrieved from a database table. Currently, rows retrieved from a spreadsheet table are placed into objects defined as key-value pairs. To access the properties of the key-value object, the developer must type in the desired property instead of choosing it, i.e., replace “property name” with a column name.

This unstructured “typing” access is challenging for citizen developers and error prone for all. 

As Thunkable can determine the properties from the columns in a  spreadsheet that has been loaded, it can generate blocks for structured access to the retrieved data. Such a block would allow the property to be selected (e.g., “firstName” below) and a slot for placing a person object (row) that has been loaded from a spreadsheet.

get ^firstName from 
   person object <


No-code tools like Adalo empower citizen developers to rapidly create prototypes and even fully working and deployed apps in some cases. The tools don’t, however, provide a visual blocks coding layer, so citizen developers are restricted in the apps that can be built and in feature design. Some tools allow advanced programmers to add new components using traditional coding, but the citizen coder is reliant on the advanced programmer to add these extensions.

Thunkable originated from the visual blocks coding world and the MIT educational tools Scratch and App Inventor. Visual blocks tools provide a user interface to coding: they allow the developer to choose commands instead of remembering and typing cryptic code, and they provide high-level blocks and constructs, like event handlers, which significantly ease the development tasks for citizen developers These tools provide the same constructs as textual coding languages, including “if” conditionals, iteration, and functions, so they are, theoretically, just as expressive as traditional coding languages and thus not limited like no-code tools.

This article describes a vision for merging the two types of citizen coding tools, and specific suggestions for adding easy-to-use database operations and generated screens and scaffolding to Thunkable. Adding such features to Thunkable would be a relatively straight-forward task, whereas adding a blocks coding layer or some other “intermediate” citizen coding language to the nocode tools would require a major overhaul. Thunkable provides the right basis for a fully expressive citizen coding tool, but just needs to incorporate key features from the nocode world.