# Go Outside: On-Device Gemma Writes You One Tiny Mission, Then Tells You to Put the Phone Away

> Source: <https://dev.to/jackydu/go-outside-on-device-gemma-writes-you-one-tiny-mission-then-tells-you-to-put-the-phone-away-3na4>
> Published: 2026-10-12 01:56:55+00:00

*This is a submission for the [Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass](https://dev.to/challenges/hacktoberfest-week1-2026-10-05)*

Most apps measure success in minutes on screen. I wanted to build one that counts it as a win when you close it.

**Go Outside** is a one-button web app. You tap *Give me a mission*, and Gemma, running inside your browser on your own GPU, writes **one** short outdoor mission for the next 20, 30 or 45 minutes, fitted to your weather, the time of day and the season. Something like:

**Puddle Mirrors.** Find three puddles that reflect something tall: a tree, a lamppost, a roofline. Pick a favourite.

Then the app gets out of the way. The screen goes almost black, shows a big countdown and says **Phone away. Go.** When you're back, it asks one optional question, *what did you see?*, and saves your one-line answer to a little field journal that lives only on your device.

It's for anyone who thinks "I should go outside" and needs a reason small enough to actually do. A mission isn't a hike or a workout. It's something specific to notice: three leaf colours, five bird calls, the lit windows on a dark street.

The challenge says the best builds should "make the screen the shortest part of the experience." Here the screen is on for about as long as it takes to read one sentence.

**Live app:** [https://jackydu1981.github.io/go-outside/](https://jackydu1981.github.io/go-outside/)

Works best in a recent Chrome or Edge with WebGPU (desktop or Android). Without WebGPU you still get a weather-aware, hand-written mission, and the app tells you why.

**One tap. One small outdoor mission written on your own device by Gemma. Then the screen goes dark until you're back.**

Go Outside is a tiny web app for the moment you notice you've been scrolling for too long. Tap one button and a small open-weight model, Google's **Gemma**, running *in your browser* through [WebLLM](https://github.com/mlc-ai/web-llm), writes a single mission for the next 20, 30 or 45 minutes. It's fitted to your weather, the time of day and the season. Something like:

Then the app gets out of the way. The screen turns almost black, shows a big countdown and says **Phone away. Go.** When you come back you can leave one line, *what did you see?*, in a small field journal that never leaves your device.

Built for the…

Plain HTML, CSS and ES modules. No build step, no backend, MIT licensed.

**Gemma in the browser.** The model runs through [WebLLM](https://github.com/mlc-ai/web-llm) (`@mlc-ai/web-llm@0.2.85`), MLC's open-source engine that compiles models to WebGPU. The default is **`gemma-2-2b-it-q4f16_1-MLC-1k`**: Gemma 2 2B instruct, 4-bit quantized, with a 1k context window, which is plenty for a single short prompt and saves memory. If the GPU lacks 16-bit shader support, the app switches to the `q4f32` build of the same model. A "lighter" setting uses **Gemma 3 1B** (`gemma3-1b-it-q4f16_1-MLC`, about 600 MB) for phones. Inference runs in a Web Worker so the progress bar and UI stay smooth.

**Context in, one mission out.** Before Gemma sees anything, the app builds a short list of plain facts:

```
- Time: evening, Saturday
- Season: autumn
- Light: daylight, sunset in about 75 minutes
- Weather: light rain, 11°C (feels like 9°C), wind 14 km/h
- Where: a park or green space
- Time available: 30 minutes
```

Weather and sunset come from [Open-Meteo](https://open-meteo.com/), which is free and needs no key, and only if you opt in to location. The rules are short and depend on the conditions: one concrete, finishable task; on foot; nothing risky; no photos or apps. When it's dark, keep to lit streets. When it's raining, make the rain part of the mission. In a thunderstorm, stay at the porch. Gemma's chat template has no system turn, so everything goes into one user message. The model answers in a fixed format:

```
TITLE: Puddle Mirrors
MISSION: Find three puddles that reflect something tall...
```

**Small models need a safety net.** A 2B model writes short, vivid instructions well but doesn't always follow a format. The parser strips markdown and quotes, copes with missing labels, trims long answers at sentence boundaries, and rejects anything too short. A bad reply gets one retry. If that also fails, or the model can't load, the app uses one of 22 hand-written missions filtered by the same flags (day/night, wet/dry, cold, hot, windy). You always walk out the door with something.

**Respecting the download.** About 1.5 GB shouldn't arrive unannounced, so the first mission asks first and offers a hand-written mission instead. After that, WebLLM keeps the weights in Cache Storage and a service worker caches the app and the pinned WebLLM bundle. **After the first run, it works in airplane mode.**

**The away screen** stores an end time instead of counting ticks, so the countdown stays correct if you lock your phone or close the tab.

**Testing.** The headless test environment has no GPU, so the automated tests cover the rest: unit tests for weather, prompt and reply parsing; a jsdom run of the real page through the no-WebGPU flow; a model-fails-to-load fallback test; and a check against the exact pinned WebLLM bundle that the functions I call and the Gemma model ids exist.

For this project, open weights decided whether it could work the way I wanted.

One honest caveat: Gemma is open-weight under Google's Gemma Terms of Use, not an OSI-approved license. For this app, what mattered was being able to download it, run it locally and ship it to users without a server, and the open weights allow all of that.

**Best Use of Gemma**: Gemma is the core of the app. Gemma 2 2B (or Gemma 3 1B on the lighter setting) runs entirely in the user's browser via WebLLM and WebGPU, turning live weather, light, season and place into one specific outdoor mission. No server and no API, and it works offline after the first run.

*Built with AI assistance: an AI assistant helped write the code, the tests and a draft of this post.*
