Skip to content
MrJev

Jev Pong

Pong where the ball moves one step per model decision, pitting Jev against chat LLMs.

View on GitHub →

Hands-on review

Pong where the paddle waits for a decision, so latency is something you watch rather than read. Its published numbers recompute from the repo.

Good for

  • Feeling the latency difference between a decision model and a chat model
  • A state builder worth copying: ten numbers, rebuilt field by field
  • Published numbers you can recompute from the data in the repository

Watch out for

  • One call per ball step: eight per court crossing, ~4.4 per second
  • One endpoint that spends gateway credit isn't behind the admin token
  • 537 tests and no CI: nothing runs them on push

Tested Sep 20, 2026 at d28d6ae34508 · Node 24 in Docker against a local gateway stand-in; 537 tests, tsc and eslint

How we reviewed this: we built and ran it in Docker against a local stand-in for the gateway, ran its tests and type checks, and recomputed every published figure from the data files in the repository. We made no Jev calls, and we did not probe the deployed site.

What it does

jev-pong, by Ably, is Pong with the right paddle driven by a model. Four lanes run four different models side by side, and the ball advances only when an answer comes back — so the ball’s speed is the model’s latency. It’s the clearest demonstration of what a decision model buys you that we’ve seen, because you don’t read the number, you watch it.

It reaches Jev through Vercel’s AI Gateway rather than TypeSafe directly, so the key involved is a gateway key.

The state is ten numbers

return { court:{w,h}, ball:{x,y,vx,vy}, paddle:{y,h}, interceptY, dir };

Rebuilt field by field, with a comment saying why: “so nothing a caller bolted onto the object leaks out”. Our captured request was 125 bytes — no game id, no client id, no player name. There is nothing to redact because nothing personal is collected. Both lanes read the same two prompt constants, so the chat model and Jev are asked the identical question.

The cost shape, exactly

One call per ball step, serially, with a comment at lib/worker/game-worker.ts:558 saying it’s deliberate: “the ball moves at exactly the speed of the model.” A step is an eighth of a court crossing, so one crossing is eight calls. The bundled 45-second recording shows the Jev lane making 198 decisions for 25 returns, with the score still 0-0 — about 4.4 calls a second.

The guards are real but they’re time guards, not spend guards: a 260 ms floor when a human is playing (not in demo mode), five points to win, and referee timeouts for an empty seat. A played game can run to roughly three thousand calls, and a game with a human never starts its ball loop until someone sits down — which is the right call and worth copying.

One spending endpoint isn’t gated

/api/record, /api/compare and demo games all check isAdminRequest. /api/decide — which calls the gateway with the project’s key — does not; it validates the body and nothing else. The README’s own table describes ADMIN_TOKEN as the “gate for anything that spends credit with nobody playing”, and lists three routes that aren’t this one.

Nothing leaks: there’s no personal data in the payload, the key stays server-side, errors are redacted twice over, and a spent balance returns a clean 402. The exposure is the bill. The route’s own doc comment calls it a debugging endpoint (“with curl, or from a test”), no front-end code calls it, and its test file has no admin case while the record route’s has three — so this reads as an oversight rather than a decision. We’ve raised it with the maintainers and asked them to turn on private vulnerability reporting, which the repository doesn’t have.

The numbers hold up

We recomputed all of them. The front-page table matches public/replay-stats.json digit for digit. The “decisions in 12 seconds” figure — 47 / 3 / 2 / 2 — comes out exactly right when you filter the replay yourself. The comparison table’s correct-answer counts match precisely; its latency medians differ by 0-2% only because it uses nearest-rank percentiles, and a comment says so: “Every counted latency, rounded, so a reader can recompute the percentiles.”

The sample is small — one 45-second recording, thirty states per model in the comparison — and the README says so.

Verdict

A demo that publishes its own raw data and invites you to check it. 537 tests, clean types, clean lint — and no CI running any of it, which for a repository under a company’s org is the odd part.

Gate the decide route before you deploy your own copy. For the same latency question measured rather than watched, see inference-benchmarks (formerly typesafe-ai-benchmark).

See how it compares with other tools in Best Jev tools, tested hands-on.

Review updated Sep 20, 2026. Numbers quoted from the project are its author's own; we don't publish our own measurements of Jev.

More in Games & Real-Time Demos

TypeSafe Mario

★ 458▲ 3

fhshaik/typesafe-mario

Jev picks NES controller inputs for Super Mario Bros. from emulator state, with no screenshots.

PythonReviewed

Jev experiments

★ 412▲ 3

dabit3/jev-experiments

Latency-focused demos from Nader Dabit, each app in its own directory with its own README. No licence file at the time of writing.

TypeScriptReviewed

jev-drone

★ 298▲ 9

RomanSlack/jev-drone

Camera-only quadrotor in MuJoCo with Jev making judgment calls at about 2.5 Hz.

PythonReviewed

Get new Jev projects every week

New Jev releases, pricing changes, and the best new projects, once a week. No spam; unsubscribe anytime.

Powered by Buttondown. See our privacy policy.