Lucid Flight
Lucid Flight is an Android app I wrote in Kotlin to help with lucid dreaming. It is a working proof of concept, not a medical device or a finished consumer product. The source is private, so this is a record of what I built and how it worked.
![]()
I chose the name and icon because flying is one of the most common things people try once they realize they are dreaming.
Lucid dreaming is simply realizing that you are dreaming while the dream is still happening. Once that happens, you can make deliberate choices inside it. The benefits are larger than I want to get into here. Suffice it to say that it is awesome, in the literal sense of the word.
The idea
A number of lucid-dreaming devices have tried to help people reach that moment. Most are masks or other dedicated hardware that watch for signs of REM sleep and then flash a light or play a sound. With practice, the sleeper learns to recognize that signal inside the dream without waking up.
Several of these devices were expensive, crowdfunded, and never actually shipped. I wanted to see how far I could get with the phone and fitness tracker I already had.
Some devices use EEG or eye-movement sensors. Lucid Flight used heart-rate data because consumer watches already collected it. Heart rate alone cannot tell you with certainty that someone has entered REM. In the prototype it was a rough signal: changes in heart rate, the timing of normal sleep cycles, and a threshold that could be adjusted while testing.
At the time, Google Fit gave the app one place to read that data. A Wear OS watch could provide continuous readings; other trackers were only as useful as the rate at which they synced their data into Fit.


The prototype looked for departures from the sleeping baseline rather than treating the smooth nightly curve itself as the signal. Heart-rate curve: Oura.
The alarm
The main screen showed the incoming heart-rate data along with its minimum, mean, and maximum. I used that view to tune the detection threshold. The middle switch turned dream detection on. The other three controlled the cue: flashing the phone screen and light, playing a tone or recording, and vibrating the phone.

The cue has a narrow job. It has to be noticeable enough to enter the dream and quiet enough not to wake the person having it. A light on the face might become an oncoming train in the dream. A recorded voice saying “you are dreaming” might be heard as part of a conversation. If the cue is too strong, the experiment is over because you are awake.
That is why the alarm was customizable. You could choose any combination of light, sound, and vibration, record your own message, set how long it ran, and preview it while awake. There was no universal setting. The useful threshold was whatever an individual could recognize without waking up.


Where it ended up
The Android prototype worked. It read heart-rate data, displayed it, applied the REM estimate, and triggered the selected cues. I also started an iOS version in Swift, but neither version became a finished store release.
Lucid dreaming is difficult, and software does not remove the need to practice recognizing when you are dreaming. What the software can do is deliver the same cue consistently and give you a way to tune it. Motivation still matters more than the alarm, which is why the home screen also showed short reminders about lucid dreaming.
The Google Fit APIs used by the prototype are now at the end of their life. A current Android version would need to use Android Health APIs instead. The implementation would change, but the experiment would be the same: use hardware people already own to place a recognizable signal inside a dream.