A web application for testing and tracking your cognitive abilities, inspired by Human Benchmark. Built with React, TypeScript, and Node.js/Express.
-
โก Reaction Time Test
- Measures how quickly you can respond to a visual stimulus
- Wait for red to turn green, then click as fast as possible
- Complete 5 rounds with averaged results
- Scores measured in milliseconds (lower is better)
-
๐ฏ Aim Trainer
- Tests your mouse accuracy and speed
- Click on 30 targets as quickly as possible
- Average time per target is calculated
- Scores measured in milliseconds (lower is better)
-
๐ข Number Memory
- Memorize an increasingly long number
- Each level adds one more digit
- Game ends on a wrong entry
- Scores measured in levels (higher is better)
-
๐ง Verbal Memory
- Track whether words are new or seen
- Three mistakes ends the game
- Score is the number of correct answers
- Scores measured in words (higher is better)
-
๐งฉ Sequence Memory
- Repeat a growing sequence of tiles
- Each level adds one more step
- Game ends on a wrong tile
- Scores measured in levels (higher is better)
-
โจ๏ธ Typing Test
- Type the displayed paragraph as quickly and accurately as possible
- Timer starts on your first keystroke
- Reports words per minute (WPM) and accuracy
- Scores measured in WPM (higher is better)
-
๐ต Chimp Test
- Memorize the positions of numbers that briefly appear
- Click the numbers in ascending order after they disappear
- Three strikes ends the game
- Scores measured in highest number reached (higher is better)
- Personal Stats: Best score, average score, games played per test
- Score History: Track all your attempts over time
- Progress Tracking: See how you improve with detailed breakdowns
- Seeded Randomness: Everyone gets the same challenge each day
- Daily Leaderboard: Compete with others on the same exact challenge
- One Attempt Per Day: Makes each daily challenge count!
- Global Rankings: See top performers for each test
- All-Time & Daily Views: Switch between overall and daily rankings
- Your Position: Highlighted when you appear on the board
- Simple Login: Just enter a username to start
- Persistent Progress: Data saved across sessions
- Profile Page: View all your stats in one place
- React 18 - UI framework
- TypeScript - Type safety
- React Router 6 - Client-side routing
- Vite - Build tool and dev server
- CSS3 - Modern styling with CSS variables
- Node.js - Runtime
- Express - Web framework
- better-sqlite3 - SQLite database for persistence
- TypeScript - Type safety
humanbench/
โโโ frontend/ # React frontend
โ โโโ src/
โ โ โโโ components/ # Reusable components
โ โ โโโ pages/ # Page components
โ โ โโโ hooks/ # Custom React hooks
โ โ โโโ utils/ # Utility functions
โ โ โโโ types/ # TypeScript types
โ โโโ public/ # Static assets
โ โโโ package.json
โโโ backend/ # Express backend
โ โโโ src/
โ โ โโโ server.ts # Express server
โ โ โโโ database.ts # SQLite database
โ โโโ data/ # SQLite database file
โ โโโ package.json
โโโ README.md
- Node.js 18+
- npm or yarn
-
Clone the repository
git clone <repo-url> cd humanbench
-
Install backend dependencies
cd backend npm install -
Install frontend dependencies
cd ../frontend npm install
# Build the frontend
cd frontend
npm run build
# Start the backend (serves both API and frontend)
cd ../backend
npm run build
BACKEND_PORT=3000 node dist/server.jsThe full app will be available at http://localhost:3000
-
Start the backend server (in one terminal)
cd backend npm run devThe API server will run on http://localhost:3000
-
Start the frontend dev server (in another terminal)
cd frontend npm run devThe app will be available at http://localhost:5173
If accessing over SSH, forward the appropriate port:
# For production mode (single port):
ssh -L 3000:localhost:3000 user@server
# For development mode (need both ports):
ssh -L 5173:localhost:5173 -L 3000:localhost:3000 user@server-
Build the backend
cd backend npm run build npm start -
Build the frontend
cd frontend npm run build npm run preview
POST /api/users- Create or get userGET /api/users/:id- Get user by ID
POST /api/scores- Submit a scoreGET /api/scores/:userId- Get user's scores
GET /api/stats/:userId- Get user statistics
GET /api/leaderboard/:testType- Get leaderboard for a test- Query params:
limit,daily=true
- Query params:
GET /api/daily- Get today's daily seedGET /api/daily/check/:userId/:testType- Check if user played today's daily challenge
GET /api/health- Service health check
# Create or get a user
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"username":"alex"}'# Submit a score (reaction test)
curl -X POST http://localhost:3000/api/scores \
-H "Content-Type: application/json" \
-d '{"userId":"<user-id>","testType":"reaction","score":245,"isDaily":false}'# Get a user's recent scores (optionally filter by testType)
curl "http://localhost:3000/api/scores/<user-id>?testType=reaction&limit=10"# Leaderboard for a test (daily=true for daily leaderboard)
curl "http://localhost:3000/api/leaderboard/reaction?limit=10&daily=true"# Daily info and check if a user already played today
curl "http://localhost:3000/api/daily"
curl "http://localhost:3000/api/daily/check/<user-id>/reaction"The app is designed to be easily extensible. To add a new test:
-
Add the test definition to
frontend/src/types/index.ts:export type TestType = /* ... */ | 'new-test'; export const TESTS: Record<TestType, TestInfo> = { // ... existing tests 'new-test': { id: 'new-test', name: 'New Test', description: 'Description here', iconClass: 'icon-new-test', color: '#color', unit: 'ms', instructions: ['Step 1', 'Step 2'], scoreBetterWhen: 'lower' } };
-
Create the test page component in
frontend/src/pages/ -
Add the route in
frontend/src/App.tsx -
Add the test type to the backend validation in
server.ts -
If the new test should sort with lower scores first, update the
lowerIsBetterlogic inbackend/src/database.ts(used for best-score and leaderboard ordering).
-- Users table
CREATE TABLE users (
id TEXT PRIMARY KEY,
username TEXT UNIQUE NOT NULL,
created_at TEXT DEFAULT (datetime('now'))
);
-- Scores table
CREATE TABLE scores (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL,
test_type TEXT NOT NULL,
score REAL NOT NULL,
is_daily BOOLEAN DEFAULT 0,
daily_seed TEXT,
created_at TEXT DEFAULT (datetime('now'))
);
-- User stats table (aggregated)
CREATE TABLE user_stats (
user_id TEXT NOT NULL,
test_type TEXT NOT NULL,
best_score REAL,
games_played INTEGER DEFAULT 0,
average_score REAL DEFAULT 0,
last_played TEXT,
PRIMARY KEY (user_id, test_type)
);MIT License - feel free to use this project for learning or building your own cognitive testing platform!