Toit is a high-level language for live reloading of code on microcontrollers such as ESP32. The written code runs incrementally as we write it, and we receive instant results. We can push changes over WiFi in two seconds. What is unique to Toit is that it uses virtual machine technology to support running multiple containers on ESP32. It is like running a micro-scale Docker on ESP32. Naturally, you can run 2-3 completely different applications at a time on one ESP32.
Jaguar is a small Toit service that runs in a container on ESP32. It updates and restarts code through an HTTP server that runs on the device and is accessed via WiFi.
Both Toit and Jaguar are completely free and open source. Naturally, exactly like the Docker ecosystem, you need a fleet management system for ESP32 devices running the Toit platform. That system is named Artemis (which is a freemium service). Artemis connects the devices to their cloud ecosystem and helps to update the firmware, containers, and configurations that run on the devices. It is free for up to ten devices. The total Toit ecosystem helps build devices with the power of edge computing – now we can easily combine 2-3 other services such as openAI, and Telegram with ESP32.
---
Toit also has an extension for Microsoft Visual Code.
How To Install Toit & Jaguar on Windows PC
This guide requires that your Windows PC already:
- Have Windows PowerShell installed
- Have Microsoft Visual Code installed and configured for Arduino
- Connected with an ESP32 dev board
The easiest way to install Jaguar (and toit) is to download the latest .exe file from their GitHub repository’s releases:
1 | https://github.com/toitlang/jaguar/releases/ |
After downloading the .exe file, run it on your Windows PC. Next, open PowerShell as administrator. Run the below command after installation:
1 | jag setup |
This will download the Toit SDK and associated firmware images.
We already have ESP32 connected to our PC with a serial cable. We will run:
1 | jag flash |
It will ask you for the serial port to use (in my case, it is COM 8) and the WiFi credentials. Because it will ask WiFi credentials every time we flash, we can store the settings in Jaguar’s config file with this command:
1 | jag config wifi set --wifi-ssid SSID --wifi-password PASSWORD |
Now, the ESP32 will be running the Toit virtual machine. We can monitor the serial output of our ESP32:
1 | jag monitor |
This will return this output, notice the output carefully:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | C:\WINDOWS\system32> jag monitor Starting serial monitor of port 'COM8' ... ets Jun 8 2016 00:22:57�ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0030,len:184 load:0x40078000,len:13252 load:0x40080400,len:2920 entry 0x40080578 [toit] INFO: starting <v2.0.0-alpha.146> [toit] DEBUG: clearing RTC memory: invalid checksum [toit] INFO: running on ESP32 - revision 1.0 [wifi] DEBUG: connecting [wifi] DEBUG: connected [wifi] INFO: network address dynamically assigned through dhcp {ip: 192.168.0.173} [wifi] INFO: dns server address dynamically assigned through dhcp {ip: [192.168.0.1]} [jaguar.http] INFO: running Jaguar device 'remote-buyer' (id: 'c6acba62-8015-4694-9d0a-f31685c61e47') on 'http://192.168.0.173:9000' |
It gave our ESP32 a name (remote-buyer) and asked us to visit http://192.168.0.173:9000 on the browser. This is that webpage:

If you have a lot of ESP32 devices running the Jaguar application, you can find a device by scanning, as long you are on the same local network (open a new PowerShell window):
1 | jag scan |
You will get this type of output, it is one device in my case:
1 2 3 4 5 | C:\Users\abhishekghosh> jag scan Scanning ... Use the arrow keys to navigate: ↓ ↑ → ← ? Choose what Jaguar device you want to use: > remote-buyer (address: http://192.168.0.173:9000, 32-bit) |
On a new PowerShell window, type:
1 | nano hello.toit |
Paste this content:
1 2 3 4 | main: while true: print "Hello, World!" sleep --ms=3000 |
Press CTRL + O to save, CTRL + X to exit. Run this file on ESP32 with this command:
1 | jag run hello.toit |
It will take a few seconds to give this output to indicate success:
1 2 | C:\Users\abhishekghosh> jag run hello.toit Running 'hello.toit' on 'remote-buyer' ... Success: Sent 33KB code to 'remote-buyer' |
You have two PowerShell windows open – the first one is running the jag monitor command. You’ll get the serial monitor output on that window, else you had to run:
1 | jag monitor --attach |
On another PowerShell window, you can run:
1 | jag watch hello.toit |
This will keep watching your Toit code on disk and live reload it whenever the file changes. Now, on the 3rd PowerShell window, edit hello.toit:
1 | nano hello.toit |
As I have changed it to:
1 | print "Hello, Abhishek!" |
Whenever I saved the changes, the output of the serial monitor changed to “Hello, Abhishek!” from “Hello, World!”. It is fast. That is the basic example of live reloading.
In the beginning, I told you about containers. The above example was running without mentioning containerization. It was actually running inside a container, which we will see in the next steps. We can run this hello.toit inside a container named ghosh:
1 | jag container install ghosh hello.toit |
The PowerShell window running jag monitor informed me:
1 | [jaguar] INFO: container 'ghosh' installed and started |
I ran jag container list command and got this output:
1 2 3 4 | PS C:\Users\abhishekghosh> jag container list DEVICE IMAGE NAME remote-buyer f97852cc-b1d8-f5aa-1665-4b623b45aaab jaguar remote-buyer 9ca21f3c-0cf5-faa3-0968-746388be2c5c ghosh |
That jaguar named container was automatically created and was running that hello.toit.
I issued another command to create another container named thecustomizewindows to check whether we can create three containers.
1 2 | cp hello.toit hello2.toit jag container install thecustomizewindows hello2.toit |
The above command automatically deleted the first container:
1 2 3 4 | C:\Users\abhishekghosh> jag container list DEVICE IMAGE NAME remote-buyer 9ca21f3c-0cf5-faa3-0968-746388be2c5c thecustomizewindows remote-buyer f97852cc-b1d8-f5aa-1665-4b623b45aaab jaguar |
Be careful about this thing. Next, I uninstalled the container thecustomizewindows:
1 2 3 | C:\Users\abhishekghosh> jag container uninstall thecustomizewindows Uninstalling container 'thecustomizewindows' on 'remote-buyer' ... PS C:\Users\abhishekghosh> |
Still, the serial monitor was giving the output Hello, Abhishek!. That means, if we do not mention the container name, the code will run on jaguar container. You can not easily delete this container, that will return the error:
1 2 3 4 5 6 7 | Error: Put "http://192.168.0.173:9000/uninstall": EOF Usage: jag container uninstall <name> [flags] Flags: -d, --device string use device with a given name, id, or address -h, --help help for uninstall |
So, with ESP32, you can simultaneously run a maximum of two different “sketches” in two containers.
As an optional next step, you can visit https://console.toit.io/ to add your ESP32 device. It seems to be buggy at the time of writing this article and you may need to try a few times. It is a typical IoT platform but the supported system is only their Toit ecosystem.
Exactly like Arduino, they have their ecosystem of libraries (they say drivers and packages) – https://pkg.toit.io/packages. You can list them with the jag pkg list command. They can be installed with the jag pkg install command. You can try various examples from here – https://github.com/toitware/examples.
Conclusion
This much is basic about Toit & Jaguar. The whole thing shows a lot of effort on the part of developers but in reality, it has limited use cases. It is good to know that it exists. It is a matured ecosystem for professional IoT device development with unique containerization.