Christian Toro, software developer

I build interactive web apps, API-powered experiences and practical automation tools. Five of them are below, each with its source.

See the work

Selected work

Five projects, each with its source. Pick what you want to see them built with.

  1. Aim AssistBrowser game and API2026
  2. HorrorscopeAI and public data2026
  3. Chinese CheckersMultiplayer web app2026
  4. RaspPi WebConnexHardware automation2025
  5. Dumpster FirePublic data, no build step2026

Aim Assist

An aim trainer you can send someone as a link.

Aim Assist landing page: the words “Train your aim” in cyan over black and cyan bands, with a tilted screenshot of the Gridshot mode beside a Start Training button.

The problem

Serious aim trainers are desktop downloads. Aimlabs ships through Steam and KovaaK's is paid, and both want an install, an account and a launcher for something most players use in five-minute warm-ups.

What I built

Six game modes, from Gridshot to an endless Survival, with a full match loop and reaction-time results. There is Google sign-in, daily, weekly and all-time leaderboards, and a profile where Claude reads your per-mode stats and suggests a mouse setup and games that suit your aim.

How it works

React never animates gameplay. React owns menus, routing, auth and stats. A plain Canvas engine owns the frame loop, and the two talk through a narrow lifecycle API, never per-frame state.

The result

After a 9,999,999 score reached the board, scoring moved to the server. The client now sends the match’s event log, and the server checks it against the mode’s rules and the real time played before computing the score. GitHub Actions run lint, 430+ tests and the build.

Status: Live. Branch shown: main. Solo project. Planned and reviewed by me, and built with Claude Code in reviewed milestones. Built with React 19, React Router 7, Canvas 2D, Tailwind CSS 4, Vercel Functions, Neon Postgres, Neon Auth, Anthropic API, Vitest.

The decoy: a “Celestial Birthday Reader” card in gold and violet on a starry navy background, asking for a date of birth.
The turn: a black screen with the words “…you have died…” in pale, old-style italic letters.

Horrorscope

A gothic prank dressed as a friendly astrology site.

The problem

A learning build: put a real AI model and a public data source behind one experience, without the API key ever reaching the browser and without either source being able to break the page.

What I built

Enter a birthday on a calm celestial reader and the page turns: a jump scare, a slow “…you have died…”, then a crypt lit only by a candle that follows your cursor. The reading pairs a dark horoscope with someone who died on your birthday, taken from Wikipedia, and an omen tying the two together.

How it works

A small Node server checks the date, limits each visitor to 10 readings a minute, fetches Wikipedia’s “On This Day” deaths and asks Claude Haiku for structured output. The front end is plain HTML, CSS and JavaScript.

The result

Checked in headless Chrome at desktop and phone widths. Text from the model and Wikipedia is only ever set with textContent, flashes stay under three a second, and reduced-motion visitors get no shake or flash. To run it, you need your own Anthropic key.

Status: Source code. Branch shown: feature/horrify. Solo project. Planned and reviewed by me, and built with Claude Code. Built with JavaScript, Node.js, Anthropic API (Claude Haiku), Wikipedia API, Web Audio.

The “Take a seat” sign-up form, with username and password fields and five illustrated animal avatars.

Chinese Checkers

Two players, two browsers, one shared board.

The problem

The first version was hot-seat: two people on one screen and a local SQLite file. Playing a friend somewhere else needed accounts, seats, and a game history that both players keep.

What I built

Sign up with a username and an avatar, open a table and send the link. Your opponent joins as Blue. Each player can move only their own colour on their own turn, and every game lands in both histories as won, lost, your turn or waiting.

How it works

The rules engine handles single steps and chains of hops that can change direction. The landing page replays a six-player game built once from that real move search with a fixed seed, so every visitor sees the same game.

The result

Rules, auth, repositories, API routes and the proxy are covered by Vitest against an in-memory PGlite database, so the suite runs without the cloud database. There is no public deployment yet.

Status: Source code. Branch shown: refactor/UI. Solo project. Planned and reviewed by me, and built with Claude Code. Built with Next.js 16, TypeScript, React 19, Neon Postgres, Tailwind CSS, Vitest, PGlite.

Chart from the project’s visualize script on sample data: three panels showing download and upload speed, ping, and packet loss over 24 hours.

RaspPi WebConnex

A Raspberry Pi that keeps a log of the home internet. The chart shows sample data.

The problem

Slow evenings and dropped calls are easy to complain about and hard to prove. Proving them takes measurements made on a schedule, not a one-off speed test.

What I built

A Python monitor for a Raspberry Pi 4B. It measures ping, download and upload with speedtest-cli and pings 8.8.8.8 to work out packet loss. Then it appends each run to a CSV and syncs the log to a Google Sheet.

How it works

A setup script installs a cron job that runs the monitor every 30 minutes, so the Pi keeps measuring with nobody watching. A separate script turns the log into charts of speed, ping and packet loss.

The result

The picture is the project’s own chart script, run on its own sample-data generator, because live runs need the Pi on the network. It plots a day of speed, ping and packet loss.

Status: Source code, needs a Raspberry Pi. Branch shown: main. Solo project. Built with Python 3, speedtest-cli, gspread, Google Sheets API, cron, pandas, matplotlib.

More work

Dumpster Fire

The US national debt, live, behind a burning dumpster.

Click the pixel-art dumpster and it shrinks into the header. A ticker then projects the debt to this second, with a chart of total public debt since 2000. One request to Treasury’s Debt to the Penny API feeds both. The rate is a five-day average over calendar time, because the data skips weekends and a per-record average would overstate the pace by 40%.

No build step, no framework, no API key: plain HTML, CSS and ES modules on any static host. Solo project. Planned and reviewed by me, and built with Claude Code in reviewed milestones.

A pixel-art green dumpster labelled “Dumpster” with orange flames and drifting smoke, on a dark navy screen.

What each one runs on

Interface, server and data, and status of each project
ProjectInterfaceServer and dataStatus
Aim AssistReact, Canvas 2DVercel Functions, Neon Postgres, ClaudeLive
HorrorscopeHTML, CSS, JavaScriptNode.js, Claude Haiku, WikipediaSource
Chinese CheckersNext.js, TypeScriptNext.js routes, Neon PostgresSource
RaspPi WebConnexGoogle Sheets, matplotlib chartsPython, cron, CSV on a Raspberry PiSource
Dumpster FireHTML, CSS, SVGNone: Treasury’s API from the browserSource

Other technologies I’ve used

AreaTechnologiesWhere to see it
Python web servicesFlask, Flask-SQLAlchemy, REST endpointsRESTful API on GitHub (opens in a new tab), Flask app on GitHub (opens in a new tab)
Node.js serversExpress, Sequelize, rate limiting, input validationStoring data on GitHub (opens in a new tab), Northline site on GitHub (opens in a new tab)
DatabasesSQLite from Python, Node and FlaskSQL in Python on GitHub (opens in a new tab), Database integration on GitHub (opens in a new tab)
Data and machine learningpandas, scikit-learn, seaborn: logistic regression, and a random forest tuned with grid searchEmployee attrition on GitHub (opens in a new tab)
AI and data APIsClaude tool use with a number-checking guard; cached third-party APIs within a daily quotaTarkov Price Terminal on GitHub (opens in a new tab), Free-Tier AI Finder on GitHub (opens in a new tab)
Front endRedux, Next.js with Tailwind CSS, vanilla JavaScriptReact and Redux on GitHub (opens in a new tab), Candidate site on GitHub (opens in a new tab)
Testing and CIJest, React Testing Library, ESLint, GitHub ActionsCI Journal on GitHub (opens in a new tab)
Build tools and scriptingGrunt, Babel, Bash scripts, Postman collectionsGrunt stopwatch on GitHub (opens in a new tab), Bash scripting on GitHub (opens in a new tab), Postman on GitHub (opens in a new tab)
Computer scienceSorting algorithms, linked lists, stacks and queues in PythonSorting on GitHub (opens in a new tab), Linked lists on GitHub (opens in a new tab), Stacks and queues on GitHub (opens in a new tab)

How I work

I’m Christian Toro, and I build software I can hand someone as a link. Most of what is here started as a written plan: the problem, the decisions that matter, and milestones small enough to check. I work through them one at a time with Claude Code, reviewing each step before it is committed, and the prompt history stays in the repository so anyone can see how it was made.

I like problems with a real edge: a canvas loop that has to hold 60 frames a second, a score that has to be proven on the server, a debt figure that has to count up honestly, a Raspberry Pi that keeps measuring when nobody is watching. Tests go in early and claims stay modest.

If you have something that needs building, let’s talk.

Get in touch