DEV Community

Cover image for 🏃 StrideBoard — A Community Hype Wall for Runners
Karthikeyan
Karthikeyan Subscriber

Posted on

🏃 StrideBoard — A Community Hype Wall for Runners

DEV Weekend Challenge: Community

This is a submission for the DEV Weekend Challenge: Community


The Community

Runners. All of them — from the person chasing their first 5K finish to the ultramarathoner logging 100-mile weeks. Whether you're training for TCS World 10K Bengaluru, a local park run, or a marathon on the other side of the world, every runner carries a goal that deserves to be said out loud.

I'm currently training for the TCS World 10K Bengaluru and I wanted a place where runners could declare their goals publicly — and have the community send energy back. Race day is personal, but the journey to the start line is communal.

StrideBoard is built for all of them.


What I Built

StrideBoard — a community race goal hype wall for runners everywhere.

Runners can drop their race goal on the board — their target time, goal type, target pace, and a short message about what's driving them. The community can then 🔥 hype each card. It's part bulletin board, part leaderboard, part pre-race ritual.

Features

  • 🎯 Goal Cards — post your race goal with target time, pace, and a motivation message
  • 🔥 Hype Button — one-tap community support, fully anonymous count
  • 🎭 Goal Types — Personal Best, Sub-60, First Ever Race, Just Finish Strong, Injury Comeback
  • 🕶️ Privacy by default — auto-generated runner nicknames (like SwiftGazelle47) with a one-click anonymous mode so no real names are ever stored
  • 📊 Community Stats — runners in, total hypes, sub-60 chasers, first-timers
  • 🏆 Top Hyped Leaderboard — the most-supported runners float to the top
  • ⏱️ Live Race Countdown — days to your target race + a 16-week training progress bar
  • 📡 Real-time Redis backend — shared state across all users, no stale data

Demo

🔗 https://strideboard-rose.vercel.app/


Code

StrideBoard 🏃

A community hype wall where runners everywhere can post their race goals and get hyped up by the crowd. 🔥

Deploy to Vercel

1. Get Upstash credentials

  1. Go to console.upstash.com and create a free Redis database
  2. Choose the Mumbai (ap-south-1) region for lowest latency
  3. Copy the REST URL and REST Token from the database page

2. Deploy

npm i -g vercel    # if you don't have it
vercel             # follow prompts — deploy as-is, no framework
Enter fullscreen mode Exit fullscreen mode

3. Add environment variables

In the Vercel dashboard → your project → Settings → Environment Variables, add:

Name Value
UPSTASH_REST_URL https://xxxx.upstash.io
UPSTASH_REST_TOKEN AXxxxx...

Then redeploy (or run vercel --prod again) — done.

Project structure

strideboard/
├── public/
│   └── index.html      # The full app — pure HTML/CSS/JS
├── api/
│   └── redis.js        # Vercel serverless proxy — keeps token server-side
├── vercel.json         # Tells Vercel to serve from /public
└── package.json

Redis


Screenshot

screen


How I Built It

This was a deliberately lean stack — the goal was to ship fast and keep it deployable in one command.

Tech Stack

Layer Choice Why
Frontend Vanilla HTML/CSS/JS Zero build step, fast to iterate
Backend Vercel Serverless Function Token proxy — credentials never hit the browser
Database Upstash Redis (REST API) Serverless, Mumbai region, instant reads
Deployment Vercel One vercel command, done
Fonts Bebas Neue + DM Mono Race bib aesthetic — felt right for runners

Architecture

The whole app is a single index.html served from Vercel's CDN. All Redis commands go through a thin /api/redis.js serverless function that proxies requests with an allow-list (LRANGE, LPUSH, HGETALL, HINCRBY only). The Upstash token never touches the browser.

Browser → /api/redis (Vercel Function) → Upstash Redis
Enter fullscreen mode Exit fullscreen mode

Redis schema:

  • stride:cards — a Redis List. Each card is LPUSH'd as JSON so LRANGE 0 99 always returns newest-first.
  • stride:hypes — a Redis Hash. Each field is a card ID, value is the hype count. Incremented with HINCRBY so concurrent hypes from different users don't collide.

Hype counts are separated from card data intentionally — it means we never need to rewrite card JSON just to bump a counter.

Privacy Decisions

One thing I thought carefully about was PII. A running community is a tight-knit group — real names on a public board felt uncomfortable.

The solution:

  1. Auto-generated nicknames on load (20 adjectives × 20 animals × 90 numbers = 36,000 combos). No real name is ever suggested.
  2. Anonymous mode checkbox — posts as 🕶️ Anonymous Runner, the nickname is never sent to Redis at all.
  3. Hypes are fully anonymous — just a count in Redis, no user identity attached.

Zero PII hits the database either way.

Challenges

The trickiest part was deciding how to handle hype state across sessions. Since there's no auth, I used sessionStorage to track "did this browser tab already hype this card" — which prevents double-hyping within a session without requiring login. It's a deliberate trade-off: refresh the page and you can hype again, but that felt fine for a community hype board rather than a voting system.

All writes are optimistic with rollback — the UI updates instantly and reverts if the Redis call fails.


Reflections

I usually build side projects that solve my problems. This one was different — I built it thinking about every runner who has a goal sitting in their head that they haven't told anyone yet.

The first-timers who are terrified. The comeback runners who've been off for months with an injury. The sub-60 chasers who've been trying for years. They exist in every city, in every running community, at every race.

StrideBoard is for all of them.

Whatever your race, whatever your goal — drop it on the board. The community's got you. 🏃


🙏 Thanks for reading! Would love any feedback or ideas in the comments.

Top comments (0)