FractionFriends
ActiveA gentle full-stack fraction-reasoning app with spaced review, admin tooling, and child-centered UX for neurodivergent learners.
- Education
- Full-stack
- AI-assisted learning
- Neurodivergent-friendly UX
- Admin tooling
Updated 2026-05-21

Overview
FractionFriends is a full-stack educational app that treats fraction reasoning as a product and UX problem, not a quiz generator. It teaches young learners through guided lessons, multiple visual renderers, spaced review, and a parent/admin dashboard — all running on a local-first stack designed to be operable by one person.
It is the most active subbrand under Beaconbridge, where the broader mission is software for neurodivergent kids.
The problem
Most fraction apps are quiz wrappers. They ask "what is 1/2 + 1/4?" and call it learning. That misses the actual difficulty: fraction reasoning is built on a small set of knowledge components — equivalence, partitioning, comparison, representation — and a learner who's shaky on any one of them will fail later problems for reasons the app can't see.
The opportunity was to build something closer to how a patient tutor works: track which underlying ideas a student has, show fractions in multiple visual forms (not just pies), and bring weak concepts back into rotation through spaced review.
Audience
- Primary: young, often neurodivergent learners — calm UI, large targets, no time pressure, no streak guilt.
- Parents and educators: progress dashboards, per-student profiles with PINs, settings for things like struggle thresholds and optional local-LLM features.
What I built
- A React + Vite SPA with multiple visual renderers (blocks, pie, vertical, polygons including octagon, pentagon, triangle, square, star, rectangle) so a concept can be shown in whichever form clicks for a given learner.
- Multiple step types — compare, build-fraction, free-input — so practice isn't reduced to multiple choice.
- A knowledge-component model with per-KC mastery tracking, feeding a spaced review schedule that surfaces weak concepts when they're due.
- An admin/parent dashboard with student CRUD, guided-mode stats, practice recommendations, a growth timeline, and concept trend charts.
- An Express + SQLite (better-sqlite3) server with auth, rate limiting, admin-gated endpoints, and a clean route surface for sessions, reviews, analytics, and admin settings.
- Optional Ollama integration — local-LLM features behind an admin toggle, so the app remains useful (and private) with no cloud dependency.
- Curriculum scaffolding: knowledge components, standards mapping, lesson outlines, and a syllabus committed alongside the code.
Product decisions
A few calls that shaped the rest of the app:
- Knowledge components over question banks. Mastery is tracked per concept, not per problem. The review schedule operates on concepts, which means the app can decide what to practice next without me hand-curating playlists.
- Multiple renderers as a first-class feature. Fractions look different in different shapes. The app supports many because "the pie one didn't make sense to me" is a real learning moment, not a content gap.
- Local-first by default. SQLite on disk, optional local LLM, no required external services. A parent can run it on a home machine and own the data.
- Calm by design. No streak pressure, no leaderboards, no urgent red states. The audience is kids who get enough of that elsewhere.
- One changelog, always updated. A single
changelog.jsis bumped on every code change. This sounds small; it's the discipline that lets the app evolve fast without losing the thread.
Technical architecture
Two-process app during development, one process in production:
- Frontend: React + Vite, served on port 5173 in dev with HMR.
host: truefor LAN testing on real devices. - Backend: Express 5 on port 3001, serving
/api/*and (in production) the built SPA fromdist/. - Database: SQLite via
better-sqlite3. Tables include students,kc_review_schedule, sessions, events, analytics, and admin settings. - Auth: bcryptjs PIN hashes for student profiles, an
authenticatemiddleware for token checks, and arequireAdmingate for admin-only endpoints.express-rate-limiton auth-sensitive routes. - Routes:
auth,students,studentData,sessions,bugReports,notifications,suddenDeath,infiniteMode,adminSettings,kcMastery,reviews,analytics. - LLM integration: a
VITE_OLLAMA_URLpointing at a local Ollama instance, behind an admin-toggleable setting so the app degrades cleanly when LLMs aren't available. - Tests: 387 Vitest tests covering the engine, scheduler, and route surface — the kind of safety net that lets one person keep shipping confidently.
The app currently runs locally with the production path being npm run serve:prod (build + serve via Express). A hosted deployment on the same LXC +
Cloudflare Tunnel pattern used elsewhere is the natural next step.
Design and brand
FractionFriends is a subbrand of Beaconbridge — its identity inherits the
parent's warmth, calm typography, and emphasis on dignity for neurodivergent
users. The UI is built on a shared @beaconbridge/design-system package so
visual decisions stay consistent across the family of apps.
Current status
- Version 0.55.x, active development.
- Phase 5D in progress: ongoing TypeScript migration (~39% of modules typed at v0.55.0).
- Recently shipped: Phase 6 (analytics + recommendations + QA pass), Phase 5B (build-fraction and free-input step types), Phase 3 (spaced review wired into KC mastery).
- 387 tests passing.
- Live deployment pending; runs locally and on LAN.
What I would do next
- Hosted deployment on a dedicated LXC behind Cloudflare Tunnel, matching the pattern used for other apps in the portfolio.
- Finish the TypeScript migration to clean up the lint backlog and harden the scheduler/analytics modules.
- Parent-facing weekly summary email driven by the existing analytics.
- A small case-study walkthrough video once the deploy is live.
Proof
Screenshots and a short walkthrough are still being captured. This page will be updated as that proof lands. Until then, the status badge above is the honest read on where this project is.