← Playbook

One keystroke, four flips: flying a drone from Go at GopherCon 2026.

At the TinyGo hack session in Seattle I flew a Parrot minidrone through a stunt routine from a Go program on my laptop, on a library written by one of TinyGo's maintainers, who was in the room. What the code does, what broke, and what the rest of the conference taught me about where Go is going.

2026-10-15/6 min read/Levelbrook AI Practice

By Patrick Donahue.

The setup

GopherCon 2026 was in Seattle in early August, close enough to home that I could go for the week. Most of my career has been in other languages, and I went to get a feel for the Go community from the inside rather than from blog posts. The thing I did not expect to be the highlight was a table of small drones.

The TinyGo session was run by Ron Evans, known on GitHub as deadprogram, one of TinyGo’s maintainers and the creator of Gobot. TinyGo is a Go compiler for small places: microcontrollers, WebAssembly, devices with kilobytes of memory. Ron’s team had a set of Parrot minidrones, palm-sized quadcopters controlled over Bluetooth Low Energy, and a tutorial that takes you from “scan for the drone” to “fly it from the keyboard” in six steps, using his tinygo-minidrone package.

What I built

I worked through the tutorial with an AI coding agent alongside me, which is how I write most code now: I read the package, the agent drafts, I decide what runs. The first program was a test flight: find the drone, connect, take off, climb at full throttle for a second, hover, land. The second was a routine. Climb to a safe height, then a front flip, a back flip, a right flip and a left flip, a fast spin, and a clean landing, all started with one keystroke.

It worked. Ron posted a clip of it, the conference photographer took a run of pictures, and one of the organisers came over to say it was the best thing he had seen all day, mostly because I was standing still with my hands off the keyboard while a drone did somersaults in front of me. The code is short enough to read in a couple of minutes, and it is in a gist exactly as I ran it.

How it works

The control path, from the Go program to the rotors. The 50 ms loop is in the package source (StartPcmd).
The control path, from the Go program to the rotors. The 50 ms loop is in the package source (StartPcmd).

There are three layers. At the bottom, tinygo.org/x/bluetooth is a cross-platform BLE package: on my Mac it talks to CoreBluetooth, on Linux to BlueZ, and on a microcontroller with a radio it talks to the hardware directly. That is the trick that makes the whole thing interesting. The same Go code that flew the drone from my laptop can be compiled with TinyGo and flashed onto a conference badge.

In the middle, tinygo-minidrone speaks Parrot’s protocol. A minidrone exposes two GATT services, one for commands and one for notifications, and you fly it by writing small byte packets to a characteristic. Steering is not a one-shot command. The package starts a goroutine that sends the current piloting state (roll, pitch, yaw, throttle) every 50 milliseconds, and calls such as Up(70) or Clockwise(100) change the values that loop sends. Discrete manoeuvres like TakeOff() and FrontFlip() are single packets. It is a tidy example of the Go idiom of a long-lived goroutine owning a piece of state while the rest of the program talks to it through method calls.

At the top is my program, which is deliberately boring. It enables the adapter, scans until it sees a device whose advertised name matches the drone, connects, starts the package, and then runs a straight line of commands with sleeps between them. It also subscribes to the drone’s flying-state notifications and prints them, so the log shows “taking off”, “hovering”, “flying”, “landing” as they actually happen rather than as the sleeps assume they happen.

What broke first

The first attempt scanned forever and found nothing, with no error. The cause was physical: these drones go to sleep after a few idle minutes and stop advertising, and a BLE scan for a device that is not advertising simply never returns. Pulling the battery and putting it back fixed it. The lesson I took into the stunt script was to make the scan handler print every named device it sees, so a silent hang becomes a visible list that does not contain the drone.

The second surprise was addressing. On macOS, CoreBluetooth never gives you a device’s MAC address. It gives you a UUID that is stable for that host only, so a program that hard-codes an address from one machine will not find the drone from another. The script matches on the advertised name as well as the UUID for that reason.

The third was choreography. A flip takes a moment to complete and the drone needs a moment to settle afterwards, so the timing between commands is the routine. I gave every manoeuvre four seconds, which is conservative and looks deliberate on video. It also matters that the drone accepts one BLE connection at a time, so the official phone app has to be closed or the program cannot connect at all.

What else I learned that week

The drone was the fun part, but the talks and the hallway were the useful part, and I left with more notes than I expected.

The conference had quietly become a conference about building with AI agents in Go. The workshop I was told not to miss, “Agents the Hard Way”, builds an agent from the ground up rather than starting from a framework, which is a very Go-shaped way to approach it. Lightning talks covered making tool calls durable so an agent can resume after a crash, and encoding a team’s conventions as linters so that neither people nor models re-argue them in review. The Go team’s closing panel struck the same note. The approach the community seems to be settling on is to use AI inside the guard rails that Go already has (the type system, go vet, gofmt, table tests) rather than around them. I find that persuasive, and it matches how I already work.

Ron’s package fits that pattern neatly. Besides the tutorial, tinygo-minidrone ships an MCP server, which lets an AI agent fly the drone through a small set of typed tools. The interesting design choice is how little it exposes: take off, land, move, flip. The safety of the whole system comes from the narrowness of that interface, which is a lesson that generalises well beyond drones.

The best hallway argument of the week was about time. A group of us started with “store everything in UTC and let the client localise it”, which is what I have done in every system I have run, and it lasted about a minute against scheduled jobs. What happens to a job scheduled in local time on the day a time zone changes? On a day with a leap second? In a place like northern Arizona, where the Navajo Nation observes daylight saving time, the state does not, and the Hopi reservation, which sits inside the Navajo Nation, does not either? We did not reach a neat answer. The practical one was to stop pretending a timestamp is enough and keep the metadata with the job: the zone it was scheduled in, the rule that was in force, and what “run once” means for that job.

I also had a long dinner-table conversation over pizza with an engineer who builds terminal tools in Go for every datastore he uses, and who pointed me at the agents workshop in the first place. Most of what I learned about how working Go developers actually spend their days came from conversations like that one.

Why this matters to me

I write Go because it rewards the things I care about in production code: explicit control flow, small interfaces, a standard library that covers the sensitive parts, and binaries that run anywhere without ceremony. Flying a drone from the same language that runs my childcare compliance backend is a small demonstration of the reach that buys. The code that steers four rotors over Bluetooth and the code that hashes a signed PDF read the same way, and that consistency is most of the reason the language is worth learning well.

The drone routine took an afternoon. Meeting the people who build the tools, and hearing where they think the language is going, was worth the whole week.

Sources and things reacted to
  1. The routine, on video (Ron Evans, Instagram) filmed at the GopherCon 2026 TinyGo session
  2. The stunt script (GitHub gist) the exact program I ran, plus the first take-off test
  3. hybridgroup/tinygo-minidrone Ron Evans's package for Parrot minidrones over Bluetooth LE; includes a tutorial and an MCP server
  4. tinygo.org/x/bluetooth the cross-platform BLE package it sits on
Keep reading

This is what we do all day.

Support automation, AI phone agents, n8n back-office work, and the engineering loop itself — always behind a gate you control.