Before trying Thunkable, I had low expectations for a "no code" native app builder. Although there are plenty of web app / PWA builders that save an icon to your home screen, current tech isn't ready to create non-templated, drag-and-drop, actual native apps.
I've never been so wrong!
Once I realized Thunkable's potential, I instantly thought of a weather app I had in the app store a few years ago. Could I recreate "Yesterday's Weather" in Thunkable? It uses a proprietary API that I coded years ago, so there's definitely no pre-built integration, but I had a feeling I could get it done.
It was a perfect, real-world-ish demo, and not only did I ultimately recreate the app, I finished it less than two hours after signing up for an account!
Here's what I saw and what I learned about Thunkable. I'm brand new to it, so take everything with a grain of salt, but after you read this, you should have a good idea of what Thunkable is and what it really can do (a lot).
Before I start: I wasn't paid by and am not affiliated with Thunkable. I'm just a curious maker sharing my "first impression" experience using the software.
Thunkable starts you with a choice of a blank new app or one of their pre-built templates. Here's what that looks like.
If you start blank, you'll see this blank "Design" tab:
And this blank "Blocks" tab:
(Those orange shapes are the choices under the "control" category in the blocks submenu.)
A built out blocks tab for a simple app screen ends up looking something like this:
That screenshot includes variables, the device's location sensor, and a couple custom API calls for data. It's all built logically, similar to writing code, but instead of typing words, you connect blocks to each other.
There are really only three top-level concepts in Thunkable, but don't be fooled... there's a whole lot to learn. This initial demo I made doesn't even scratch the surface.
The three concepts are Screens, the Design tab, and the Blocks tab.
Screens are exactly what you'd expect... screens, or views, in your app. Each screen gets its own Design tab and its own Blocks tab, so each screen has a layout and a set of visual blocks for functionality.
Screens are a familiar concept to native app makers, but the way you visually build each screen is a bit different.
To visually design a screen, you drag and drop pre-set elements. Everything starts in the horizontal and vertical middle of the screen and is styled with CSS flexbox in the "styles" panel to the right (I don't know if it's called that).
In this screenshot, you can see the styles panel, where there are input fields for familiar CSS properties. Under the Advanced tab, you can more or less set any CSS property (I didn't find any that were missing, but I'm sure some are?).
It took me a minute to realize I should wrap everything in a "row" or "column" element, like I would use a div on a webpage. This way, I could better standardize styling (everything is flexbox, so widths and vertical position vary more than you might expect at first).
The components you can drop in range from the layout components I just mentioned to text, images, Airtable bases, Stripe payments, and even blockchain wallets. Here's a look at the list of options:
Once you have elements on a screen, the next step is to switch to the Blocks tab and start programming the Design elements.
The Blocks tab is essentially visual coding.
Here, you have several categories for blocks you can drag onto the main canvas. The blocks allow you to make the components in the Design tab interactive. They range from "control," "logic," "math," "text," (and many more) to component-specific options like "Web API 1" (or whatever you name it).
This section is where the magic happens. I had to look a few things up initially (there's a good forum that comes up in search results), but once I understood the concepts, I barely needed help.
This screenshot shows the Blocks for a Screen that has an input and a "back" button (basically). Even though it looks like a lot is going on, this is a relatively simple screen.
I didn't label things well in my quick demo, but you can see "Button2" clears some variables and sends the user back to "Screen1," and "Button4" makes an API call based on the value of "Text_input1" and saves parts of the returned data into variables. Then it also sends the user back to "Screen1."
The Blocks use code logic and code concepts, but the code is obviously written in a completely different way. This part was especially eye-opening for me, because 1) the breadth/depth really impressed me and 2) I really wonder what this would feel like to someone who isn't a developer. Or how hard it would be to learn.
But as a developer... wow!
My Weather App Demo
I used to have an app in the app store that I loved. It was called Yesterday's Weather, and you open the app to a single sentence that tells you what it's like outside right now, relative to yesterday.
"Today, it's 4 degrees warmer than yesterday, but it's windier."
I didn't maintain the app, so it was removed from the app store at some point, but I always wanted to revive it. This was my perfect chance.
Here are a few iterations of Yesterday's Weather over the years (non-Thunkable, original native app versions):
Here's what my Thunkable demo ended up looking like. I could have matched any of the designs/UIs above with Thunkable, but I purposely simplified the design.
For the magic of that single-sentence weather assessment, I rely on an API that I built years ago (that uses the Dark Sky weather history API). To rebuild this app with Thunkable, I need to pull data from that.
I also need to use the device's location sensor to initially find someone's location so I can look up their weather.
The only other functionality for the demo would be to set/change the location manually, so I also need to have an input where someone can type their location and run the query again.
I started in the Design tab by dragging in an image component for the logo and a text component for the main sentence. I used the placeholder text "Finding weather..." because I knew right when someone opened the app, I'd look up their weather and replace that text with their weather sentence.
To get the weather sentence, I'd need to use an API (a custom one, as I mentioned), but to get data out of my API, I needed to send latitude and longitude coordinates into it.
We can get those coordinates from the device's built-in location sensor, so the first non-layout task was to trigger that and use the results.
I saw a Location Sensor component and dragged it onto my canvas area in the Design tab (this is an "invisible" component because it doesn't have a visual part to it, so it appears on the canvas but under the actual screen). Then I switched to the Block tab and saw I had new options for the location sensor (because it was now on the canvas). Here's a raw Location Sensor block, ready to hook up:
Notice that it's "grayed" out. That's because it's not hooked up to anything... it's just a random location sensor trigger floating in the middle of nowhere.
I noticed there was a category on the left for "Screen 1" which was my current screen, and under that there was a block for "when Screen 1 opens." By wrapping the When Screen Opens block around the Location Sensor block, all of the blocks became active (and full color). Now when Screen 1 opens, the app knows to get the current location. Here's what it looked like:
You can see that the Location Sensor block returns pre-determined data based on the response from the actual device (Error, Latitude, Longitude, and Location... the green pieces on the right).
If you understand code logic, this is probably starting to all click. If you don't, you might need to take a minute to wrap your head around this type of thinking. Either way, it eventually will become easy and intuitive to set this stuff up.
In that screenshot, starting with the orange Screen block and moving into the purple Location Sensor block, you can read what's happening:
"When [Screen 1] [Opens], do: [Location Sensor 1] call: [GetCurrentLocation] and return: [error, latitude, longitude, location], and then do: [something... whatever we stick in that empty slot]."
What I want to do with the returned latitude and longitude is query my own API, so for the next step, I switched back to the Design tab and dragged a Web API component onto my canvas.
Web API blocks work just like the Screen and Location Sensors, so I won't go into detail. You're just nesting these blocks within each other. In this case, I placed the Web API block into the empty slot in the Location Sensor block, right after the words "then do."
Here's another look at the final layout, so you can see how things work, but I'll leave it at that. Your app will surely be different, so my goal here is just to explain the concepts.
I didn't name anything in my demo. In real life, you could name your components properly, and these code blocks below would be even easier to understand.
Before wrapping up, there are three smaller concepts that stood out as important and pretty universal.
Most apps are going to use variables. My demo stores a latitude and longitude variable, in case the person inputs it themselves. I chose to store those variables on their device. That way, next time they open the app, we can use the variables instead of their location sensor. (This is especially important for people who don't allow apps to access their location.)
There are three types of variables in Thunkable- "app," "stored," and "cloud."
App variables live and die within the currently running instance of an app. They can be used anywhere, but they don't save across sessions.
Stored variables are like "localStorage" in a web browser. They're saved on the person's device and will save across sessions. This is the type of variable I used for latitude and longitude. I needed it to save across sessions, but I didn't need to save it in my own database or access it for any other reason.
Lastly, the Cloud variables, which use Firebase, allow you to save information across sessions and across devices. It's like having your own database that you can use for other things or query from other apps.
In my app, because I get the weather when the app opens and again if they set their own location, I decided to use a function to wrap all of the "get weather" logic up.
This is how it would be done with "real" code, and this means in the future, I can edit that function once, and it updates wherever it's called.
This isn't an enormous deal, especially if you come from traditional coding, but it's something I wasn't sure if I should expect or not in a "no code" tool. I should 👍.
Object and string manipulation
I also wanted to quickly touch on using JSON, objects, and strings. I needed to form the API url from text and variables, and I needed to turn the API's JSON response into an object to pull the values I needed.
Here's a look at how how both of these things generally work. Notice the "join" blocks for string/variable concatenation, and notice the "get property of object" and "get object from JSON" blocks. Really cool!
Another quite useful feature is that you can live-test apps you're building on a real device using Thunkable's native app.
This reminded me of the PhoneGap app back in the day, but Thunkable is more intuitive and automatic.
Since building the Yesterday's Weather demo, I've been using it through the Thunkable test app like a real app every day. However, if I want to share it with the world and/or charge for it, I need to publish it to an app store (or two).
I've been through the app publishing process before (although last time I published was two or three years ago), so I had my doubts about this part. It's just a generally tedious process.
I did have hope, because a few weeks ago, I was pleasantly surprised by the near seamless integration that VoiceFlow offered for publishing a voice skill, so I knew there was a chance Thunkable could streamline publishing to an app store.
I haven't actually published the app at the time of this writing (but I will soon), so I haven't gone through the full process, but when I read through the documentation, it looks like you export the source and go through a pretty standard app submission process.
I can imagine all the certificates and signing stuff would be pretty confusing for someone who just built their first app without code, but technically you can just follow the instructions in Thunkable's documentation. That's more or less what I did for the first version of Yesterday's Weather. I had no clue what I was doing at the time, but the app made it into the app store.
I can commit right now to building and playing with Thunkable more. I'd love to push the limits and see how far it can go. I'd also love to experiment with push notifications.
I currently need to build a native app for Really Simple Store- one that integrates with OST's "no code" blockchain and token solution. It's the next step in a large integration I've been working on for more than a year. I have a hunch Thunkable can do everything I need, and if so, it would suddenly go from a really fun toy to a very valuable business tool.
I'll document the process when the time comes!
In the meantime, I'd love to see or hear about what other people are building on Thunkable! @ me!