# Wiggle Outside: weather, nearby places and a little inspiration in one short search

> Source: <https://dev.to/moonchichiii/wiggle-outside-weather-nearby-places-and-a-little-inspiration-in-one-short-search-25cc>
> Published: 2026-10-11 23:52:58+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)*

Before we can get outside, there's the planning: check the weather, find somewhere nearby, then think of something the kids might enjoy. By the time you've done all three, the moment has often passed.

I signed up for this challenge on Friday evening with one idea: put those steps into one quick search that answers the question a parent actually has: **where do we go, what do we do there, and what do I need to bring?**

**Wiggle Outside** is that search. You say who's coming (just you, or you and the kids, with their age groups), how much time you have, how much energy is in the room, whether there's a stroller, and roughly where you are, typed or from your device's location. Optionally, you say what they're into right now, in your own words.

Here's the search from the demo video: Capitol Hill in Seattle, a 3–5-year-old, two gentle hours, a stroller, and *"dogs, birds and pointing at everything"*. Back come **up to three outdoor ideas**, each an activity from a reviewed list paired with a real nearby park or playground when the map data has one; in the video, Nature bingo and a Leaf colour hunt. Each says why it fits and roughly how far it is, links to the place on OpenStreetMap, and opens a detail page with simple steps, another way to play, a safety line and a question to ask on the way home. Below the ideas, **"Before you go"** lists what to pack for that forecast, those ages and those activities, with a snack idea.

One thing changed late in the build. Parents often plan in the evening, after the kids are asleep, and my first version simply said "come back tomorrow". Now evening family searches can plan ahead for the next morning, using that outing's forecast and daylight. Between midnight and 04:30 it suggests getting some rest instead.

It's for parents and carers of children up to 12 who want to get out of the door without another round of planning, and for adults on their own who need a small escape.

**Live:** [wiggle-outside.fly.dev](https://wiggle-outside.fly.dev)

*The short intro and outro animations in the video are AI-generated; everything in between is a real screen recording of the live app, with the form entry sped up 2×.*

A few things worth knowing before you try it:

Find a realistic outdoor activity near you, for the next hour or two, then put the phone away.

Answer five short questions — who is coming, how long you have, how much energy, where you are, anything to account for — and Wiggle Outside offers up to three grounded ideas, each one a nearby place from OpenStreetMap paired with a reviewed activity that suits the forecast, the daylight and the ages you named. If nothing suitable exists right now, it says so rather than padding the list.

Built for the Hacktoberfest Open-Source AI Challenge, Week 1 ("Touch Grass").

`docs/`` docs/PLAN.md`
The model is Gemma 4 26B A4B (`google/gemma-4-26b-a4b-it`), reached through OpenRouter
Its job is deliberately small and fully checked:

FastAPI and Jinja render plain HTML on the server, with one small script for "Use my location" and the loading state. Tailwind 4 for styles, SQLite for caches and the daily quota, Fly.io for hosting. Around 1,700 automated tests, strict type checking, and an Apache-2.0 licence for the code. (The display fonts are licensed separately and aren't in the repository; a clone falls back to system fonts.)

On an emulated mid-range phone over slow 4G, Lighthouse scored the live form page 100 for performance, accessibility, best practices and SEO.

*The original concept board, made with ChatGPT. The shipped app keeps its palette, hand-drawn frame and margin illustrations, with a simpler single-column form. The screenshots above are the real app.*

The design is a split of responsibilities.

**Deterministic rules decide what's possible.** Each of the 26 activities in the reviewed list (19 for families, 7 for adults alone) carries its own limits: age groups, minimum temperature, maximum wind, rain tolerance, whether it needs daylight, what kind of place it suits. The app fetches the forecast from [Open-Meteo](https://open-meteo.com/) and nearby places from [OpenStreetMap](https://www.openstreetmap.org/) (Nominatim to find the town, Overpass for parks and playgrounds), then filters everything down to *eligible pairs*: this activity, at this place or needing none, for this time window.

**Gemma chooses among them.** When eligible pairs remain and the model is available, [Gemma 4 26B A4B](https://ai.google.dev/gemma) receives them as IDs, each with the hooks and reasons it may use, plus the optional "what are they into?" text. It ranks up to three pairs, picks a hook and reasons for each by ID, and maps the family's text to a small reviewed vocabulary of interests. That's the language part: turning *"birds and puddles"* into tags and putting Nature bingo and the Puddle jumping championship ahead of a Shape safari.

You can see its work on each card: the reasons it picked ("It's close by", "It's the right season for it") and the interests it recognised ("Matches: animals, birds"). Gemma never writes the text on the page and never invents a place: the cards, reasons and interest labels are rendered from reviewed copy, chosen by the IDs it returns. I tried letting it write a short personal note per idea and took it out again the same night: a length limit and a character filter can't make a sentence shown to parents of toddlers safe, so the reviewed-text boundary stayed. Its answer must match a strict JSON schema, and the app then validates every field. Unknown pairs, disallowed hooks or reasons, duplicates and repeated activities are dropped, never repaired, and cards are built only from what survives.

In a controlled run with live geocoding, forecast and model but fixture places, Gemma read *"birds and puddles"*, picked two valid pairs, and the page rendered exactly those two cards; the model call took about 1.8 seconds. The search in the demo video ran fully live against the deployed app: real geocoding, real places, real forecast and the hosted model. The server log for it reads `source=model ideas=2`: Gemma made the selection. The whole search, measured on the server, finished in about 1.5 seconds, but I had searched the same area while preparing the demo, so places and forecast may have come from cache; it isn't a cold-start time.

My first version stopped at the ideas, and it felt flat. A parent doesn't only need *what*; they need *where* and *what to grab on the way out*. So the results page now leads with one short notice instead of a stack of them, shows each idea's reasons and place, links the place on OpenStreetMap by its own map ID (no coordinates of yours in the link), and ends with "Before you go". The packing list is deliberately rules, not AI: weather items come first, then the little ones' essentials, then each activity's own bits, at most ten, with "Your usual age-appropriate snacks and drinks" whenever a baby is in the group.

Gemma runs hosted, through [OpenRouter](https://openrouter.ai/), with tight limits:

The request deliberately leaves out your typed town, coordinates and place names: the model sees activity titles, place *kinds* (park, playground) and distance bands. Your optional interests text is sent as typed, which is why the form asks you not to include personal details. In the app, the raw text stays in server memory with your search for about an hour, as the form says (up to two hours in your session if you had to pick between towns with the same name), and is never written to the database or the logs. What the results page keeps is the recognised interest tags.

Every search runs under one 20-second deadline: about 3 seconds to find the place, 9 for places and weather together, 6 for the model, and 2 reserved for building the page. Whatever earlier steps use comes off the later ones, and the overall deadline always wins.

When something fails, the app says so:

`uniqueItems` in the JSON schema. I removed it from what's sent and kept uniqueness in my own validation, with tests proving duplicates can't reach the page.
I built this over the weekend with AI agents; I retained responsibility for product decisions and reviewed the agents' output. Claude Code wrote and tested the code against a written plan, ChatGPT drew the design and reviewed the plan and this post, and every change went through a tracked decision before it landed. The reviews earned their keep: one caught that I was about to call a test run "warm" when nothing had been cached, another that the privacy wording promised more than the code did, and a third talked me out of letting the model write free text on the page. The most useful feedback came from home, though: my partner pointed out that parents plan in the evening, after the kids are asleep, which is why the app now plans ahead for the next morning.

Three different kinds of openness make this app possible, and they matter in different ways.

**Open weights.** For this entry I use hosted Gemma through OpenRouter. Because the weights are published, the model itself isn't tied to that service: moving inference elsewhere would still take suitable hardware, integration work and fresh testing, but it's an option available under the model's licence terms.

**Open data.** The places come from OpenStreetMap, mapped by volunteers who decided a playground or a picnic spot was worth recording, and the forecast comes from Open-Meteo. Those services make a small project like this practical. They also create responsibilities: attribution, caching, respecting usage limits, and being honest when data isn't available.

**Open code.** The application is Apache-2.0 licensed, so the next person can take the rules, the tests or the whole thing.

This version needs an internet connection and depends on hosted services today. The open approach gives me more control over where it goes next; it doesn't make hosting free.

**Best Use of Gemma.** Gemma 4 26B A4B is the selection step: when eligible ideas remain, it reads the family's interests in their own words and chooses among validated activity-and-place pairs, with a strict schema, validation and a labelled fallback, and the reasons and recognised interests it chose are shown on every card.
