Make Local AI Toys, Robots, Devices that work with a MacBook and an Arduino ESP32
See the codeEnglish | 中文
OpenToys is the local-first platform version of ElatoAI. No cloud required, no subscription lock-in, and your data stays private on-device with inference running locally with a websocket transport to connect to your ESP32-S3.
Apple Silicon · Rust + React · ESP32-S3 · Whisper ASR · Qwen3-TTS · MLX LLMs
The New Wild West of AI Kids Toys
Read the WIRED article →
AI kids' toys roundup
Read the ArsTechnica article →
The Easy Way to Build Interactive AI Toys for Your Kids
Read the Hackster article →

git clone https://github.com/akdeb/open-toys.gitcurl https://sh.rustup.rs -sSf | shcd appnpm installnpm run tauri devCreate experiences with personalities that can play games, tell stories, engage in educational conversations. Here are some of the default characters with more prompt details in personalities.json.
mlx-community (Gemma 4, Qwen3.8, Muse Glimmer, Qwen3, Llama, Mistral3, etc.)Settings → Connect your ESP32 Here, pick your serial port and click Flash.bootloader, partitions, firmware) directly.The toy hosts its own WiFi network and your Mac joins it, so there is no router setup, no captive portal, and no home network involved.
ELATO
(no password) at 192.168.4.1. Its LED glows pink while it waits.ELATO from your Mac. It appears in the macOS WiFi menu like any other
network. macOS will warn that the network has no internet — that is expected,
the toy is not a router.Ready on device.Play button. It is disabled until the toy is connected
(it reads "Connect your Mac to ELATO first" on hover) and enables itself the
moment the handshake lands. Press it and the toy is live — start talking.Leave OpenToys running while you play; it is doing the speech-to-text, the LLM, and
the text-to-speech on your Mac. To finish, press End in the app — it drops the session
and takes you to the transcript — or just power off the toy.
[!TIP] While your Mac is joined to
ELATOit has no internet access. Download your models and voices before joining, or hop back onto your normal WiFi to fetch them and then rejoinELATO.
Play button stays greyed outELATO isn't in the WiFi list — the toy isn't powered, or the firmware didn't
flash. Reflash and watch for the pink LED on boot.ELATO but nothing happens — make sure OpenToys is actually running on
the Mac. The toy probes ports 49320 and 8000 on whichever machine joins it, and
waits for one of them to answer.Download voice — the selected character's voice isn't on disk
yet. Click it to fetch the voice, then come back.AI systems (local or cloud) are not perfect. This project is built with data privacy and safety in mind, but there are still important limitations:
When using with children, use with parental awareness and treat this as a tool for exploration, not authority.
open-toys/
├── app/
├── arduino/
├── resources/
├────────── python-backend/
├────────── firmware/
└── README.md
Python 3.11 runtime binary, packages and HF models are downloaded on first app setup into the app data directory.
MIT
If you like this project, consider supporting us with a star ⭐️ on GitHub!
127 commits
TypeScript
39.8%
Python
29.6%
C++
19.7%
Rust
6.5%
CSS
3.9%
Make Local AI Toys, Robots, Devices that work with a MacBook and an Arduino ESP32
See the codeEnglish | 中文
OpenToys is the local-first platform version of ElatoAI. No cloud required, no subscription lock-in, and your data stays private on-device with inference running locally with a websocket transport to connect to your ESP32-S3.
Apple Silicon · Rust + React · ESP32-S3 · Whisper ASR · Qwen3-TTS · MLX LLMs
The New Wild West of AI Kids Toys
Read the WIRED article →
AI kids' toys roundup
Read the ArsTechnica article →
The Easy Way to Build Interactive AI Toys for Your Kids
Read the Hackster article →

git clone https://github.com/akdeb/open-toys.gitcurl https://sh.rustup.rs -sSf | shcd appnpm installnpm run tauri devCreate experiences with personalities that can play games, tell stories, engage in educational conversations. Here are some of the default characters with more prompt details in personalities.json.
mlx-community (Gemma 4, Qwen3.8, Muse Glimmer, Qwen3, Llama, Mistral3, etc.)Settings → Connect your ESP32 Here, pick your serial port and click Flash.bootloader, partitions, firmware) directly.The toy hosts its own WiFi network and your Mac joins it, so there is no router setup, no captive portal, and no home network involved.
ELATO
(no password) at 192.168.4.1. Its LED glows pink while it waits.ELATO from your Mac. It appears in the macOS WiFi menu like any other
network. macOS will warn that the network has no internet — that is expected,
the toy is not a router.Ready on device.Play button. It is disabled until the toy is connected
(it reads "Connect your Mac to ELATO first" on hover) and enables itself the
moment the handshake lands. Press it and the toy is live — start talking.Leave OpenToys running while you play; it is doing the speech-to-text, the LLM, and
the text-to-speech on your Mac. To finish, press End in the app — it drops the session
and takes you to the transcript — or just power off the toy.
[!TIP] While your Mac is joined to
ELATOit has no internet access. Download your models and voices before joining, or hop back onto your normal WiFi to fetch them and then rejoinELATO.
Play button stays greyed outELATO isn't in the WiFi list — the toy isn't powered, or the firmware didn't
flash. Reflash and watch for the pink LED on boot.ELATO but nothing happens — make sure OpenToys is actually running on
the Mac. The toy probes ports 49320 and 8000 on whichever machine joins it, and
waits for one of them to answer.Download voice — the selected character's voice isn't on disk
yet. Click it to fetch the voice, then come back.AI systems (local or cloud) are not perfect. This project is built with data privacy and safety in mind, but there are still important limitations:
When using with children, use with parental awareness and treat this as a tool for exploration, not authority.
open-toys/
├── app/
├── arduino/
├── resources/
├────────── python-backend/
├────────── firmware/
└── README.md
Python 3.11 runtime binary, packages and HF models are downloaded on first app setup into the app data directory.
MIT
If you like this project, consider supporting us with a star ⭐️ on GitHub!
127 commits
TypeScript
39.8%
Python
29.6%
C++
19.7%
Rust
6.5%
CSS
3.9%