Skip to main content

Example: the top 5 movies in theaters

This is a full, real build, the way it actually goes: you start with a rough idea, the AI gets something on screen, and then you reprompt it and hand-edit it, over and over, until it looks right. We'll build a Now Playing panel from the TMDB API (The Movie Database) and watch it grow from a plain text list into a poster card with star ratings and per-movie colors.

Final movie card: Toy Story 5 with poster, stars, and scoreFinal movie card: Scary Movie with a red score
Where we're headed: a card per movie, posters and accent colors pulled from the data, the score colored by its rating.

First, the ingredients

An API key. TMDB is free: make an account at themoviedb.org, then go to Settings and open API to copy your key. The endpoint we'll use returns the movies in theaters right now:

https://api.themoviedb.org/3/movie/now_playing?api_key=YOUR_TMDB_API_KEY&region=US

Each result includes the fields we'll draw: title, vote_average (the rating), poster_path (the image), and popularity (for ranking).

Your key stays a secret

Never paste your real key into app.star. Declare it as an input instead; in the Glance app the user enters their own key, GDN stores it encrypted on the server, and your code reads it as ctx.inputs["tmdb_key"]. In this doc it's always shown as YOUR_TMDB_API_KEY.

Now hand the AI the cheat-sheet and start.

Iteration 1: just get the titles on screen

Prompt to the AI
Build a GDN app for a 128x32 panel that lists the top 5 movies now playing from the
TMDB now_playing API. One line each: rank number, then the title.
A plain text list of five movie titles

It works, and it's dull, which is fine for a first pass. The AI fetches the data and prints five uppercase rows. Now we make it look like something.

Iteration 2: one card per movie, with the poster

Prompt to the AI
Nice start. Instead of a list, make it a five-page app: one page per movie, movie_1
through movie_5. On each page show the poster on the left and the title on the right.
The posters live in the app folder as poster1.png ... poster5.png, already 21x32.
A card with the movie poster on the left and the title on the right

Now it has a face. This is the images lesson in action: the poster is a bundled PNG, sized to the panel's 32px height and placed at the left edge. (A live panel can't fetch a remote poster per render, so the poster pack is a snapshot you refresh now and then; the text stays live.)

The first pass looked muddy, though: a full movie poster shrunk this small washes out. You don't need to know any photo-editing terms to fix that; just describe the problem in plain words and let the AI handle the technical side:

Prompt to the AI (make the posters look good)
The posters look muddy and washed out at this tiny size. Fix them so they look punchy and
clear on the panel: crop them to fit, keep the colors vivid, boost the contrast, and
sharpen them a little. Save each one at 21x32.

Behind the scenes the AI picks a good shrink method and boosts the color, contrast, and sharpness, the details you'd never think to ask for by name. That's the value of describing what you want instead of how to do it.

Rotating one movie per page makes Now Playing a five-page app. In the manifest, the pages list names one function per page, in order, and the panel cycles through them:

# One page per movie. The panel rotates through all five in order.
# Page 1 draws movie_1 (the #1 film), page 2 draws movie_2, and so on to movie_5.
pages: [movie_1, movie_2, movie_3, movie_4, movie_5]

Each name maps to a function of the same name in app.star (def movie_1(c, ctx): …), so page 1 maps to movie_1, page 2 to movie_2, right through the top five.

Iteration 3: colors from the data, stars and a score

Prompt to the AI
Add the rating under the title: draw vote_average / 2 as gold stars out of five, and
show the number too, colored green if it's 7 or higher, amber if 6 or higher, red below.
The card now has gold stars and a green scoreA lower-rated film shows fewer stars and a red score
The rating drives the picture: four gold stars and a green 7.4, versus three stars and a red 5.4.

This is the "colors from the API" idea: the numbers in the response decide what's drawn. A great film lights up green; a stinker turns red, automatically.

Iteration 4: each movie's own color, and a rank badge

Prompt to the AI
Two more touches. Sample the dominant color from each poster and use it as a thin accent
stripe beside the poster and as the fill of a small rank badge in the top-right. Then
wire it to the live API with my key input so it updates on its own.
The finished card with an accent stripe and a rank badge

Every movie now carries its own color, pulled straight from its artwork, plus a ranking badge. Here's the live-data part the AI wrote, the reason we needed a key:

def _movies(ctx):
key = ctx.inputs.get("tmdb_key", "")
if key == "":
return SAMPLE # offline fallback
resp = http.get(
"https://api.themoviedb.org/3/movie/now_playing",
params = {"api_key": key, "region": ctx.inputs.get("region", "US")},
ttl_seconds = 3600,
)
if resp["status_code"] != 200 or resp["json"] == None:
return SAMPLE # API down? show the snapshot
return [_row(m) for m in resp["json"]["results"][:5]]

Notice the two guards: no key falls back to a bundled sample, and a failed request does too, so the panel is never blank. The key is read from ctx.inputs, never hardcoded.

Don't be afraid to edit it yourself

The AI is a starting point, not the finish line. To get exactly what you want, open the code and change it yourself:

  • In Glance Dev Studio, edit app.star, hit Save & Render, and watch the panel update. Nudge a coordinate, swap a color, try a bigger font.
  • Or open the file in a code editor like VS Code and tweak it there.

Half the moves in this build were one-liners you'd just as easily do by hand: change 24 to 23 to raise the stars a pixel, swap "amber" for a hex color, bump the title to a bigger font. You don't need the AI's permission, and every small edit teaches you the API.

The loop is prompt, edit, reprompt, edit. Ask the AI for a change, hand-fix the thing it got slightly wrong, then ask for the next one. That back-and-forth is the work, and it's how every panel above went from plain to polished.

What this example taught

StepThe moveThe takeaway
1List the titlesGet something on screen first.
2Add postersBundle images and size them to 32px.
3Stars + colored scoreLet the data choose the colors.
4Poster accent + live fetchGuard every http.get; keep the key in an input.

Keep going with more app ideas on the Examples & lessons page, or when yours is ready, submit it.