A modern, feature-rich Rubik's cube timer built with Next.js, React, and TypeScript. Inspired by cstimer, this application provides a clean and professional interface for speedcubing practice and competition.
- Accurate Timer: High-precision timing with millisecond accuracy
- WCA Scramble Generator: Official World Cube Association compliant 3x3x3 scrambles
- Spacebar Controls: Standard speedcubing timer controls (hold to prepare, release to start)
- Time Tracking: Comprehensive solve history with timestamps
- Comprehensive Stats: Best, worst, mean, and current session statistics
- Standard Averages: Ao5, Ao12, Ao50, and Ao100 calculations
- Visual Feedback: Color-coded times based on performance
- Time Management: Add penalties (+2, DNF) and delete individual solves
- Modern Dark Theme: Easy on the eyes for long practice sessions
- Desktop Focused: Optimized for desktop use with keyboard controls
- Visual State Indicators: Clear feedback for timer states (ready, running, stopped)
- Keyboard Shortcuts: Efficient navigation and control
- Local Storage: Automatic save/restore of times and settings
- Export/Import: JSON-based backup and restore functionality
- Session Management: Clear all times with confirmation
- Bun (recommended) or Node.js 18+
- Modern web browser
-
Clone the repository
git clone https://github.com/TriForMine/rubiks-cube-timer.git cd rubiks-cube-timer
-
Install dependencies
bun install
-
Start the development server
bun run dev
-
Open your browser Navigate to http://localhost:3000
# Build the application
bun run build
# Start the production server
bun run start
-
Starting a Solve
- Press and hold the SPACEBAR
- The timer will show "HOLD" state (red indicator)
- Continue holding until you see "READY" state (yellow indicator)
- Release SPACEBAR to start the timer
-
Stopping the Timer
- Press SPACEBAR while the timer is running
- Your time will be automatically recorded
- A new scramble will be generated
Key | Action |
---|---|
SPACE |
Start/Stop timer |
N |
Generate new scramble |
DELETE |
Delete last time |
Note: The timer currently requires a physical keyboard and is optimized for desktop use. Mobile device support is planned for future releases.
- View Details: Click on any time in the list to expand details
- Add Penalties: Use the +2 or DNF buttons in expanded view
- Delete Times: Click the trash icon to remove individual times
- Export Data: Use Settings → Export Times to backup your data
- Import Data: Use Settings → Import Times to restore from backup
- Best: Your fastest solve time
- Mean: Average of all solve times
- Ao5: Average of 5 (best and worst times removed)
- Ao12: Average of 12 (best and worst times removed)
- Ao50: Average of 50 (best and worst times removed)
- Ao100: Average of 100 (best and worst times removed)
- Framework: Next.js 15 with App Router
- Language: TypeScript
- Styling: Tailwind CSS v4
- UI Components: shadcn/ui (Radix UI primitives)
- Icons: Lucide React
- Package Manager: Bun
- Runtime: React 19
- Performance: Rust WebAssembly (WASM) for cube simulation
src/
├── app/
│ ├── globals.css # Global styles and Tailwind config
│ ├── layout.tsx # Root layout component
│ └── page.tsx # Main timer page
├── components/
│ ├── ui/ # shadcn/ui components
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── dialog.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── tabs.tsx
│ │ └── badge.tsx
│ ├── Timer.tsx # Main timer display
│ ├── ScrambleDisplay.tsx # Scramble generator and display
│ ├── Cube3DViewer.tsx # 3D cube visualization
│ ├── TimesList.tsx # Solve history list
│ ├── Statistics.tsx # Statistics dashboard
│ └── Settings.tsx # Application settings
├── lib/
│ ├── utils.ts # Utility functions
│ ├── cube-wasm.ts # WASM module interface
│ ├── cube-3d-renderer.ts # Three.js 3D renderer
│ └── scramble.ts # Scramble generation logic
└── cube-wasm/ # Rust WASM module
├── src/ # Rust source code
├── pkg/ # Compiled WASM files (committed)
├── Cargo.toml # Rust package config
└── README.md # WASM module documentation
This application features a custom Rust WebAssembly module for optimal performance:
- Blazing Fast: Cube simulation runs at native speeds
- Zero-Copy Memory: Direct memory access between JS and WASM
- WCA Compliance: Official scramble generation algorithms
- Type Safety: Full TypeScript integration with WASM bindings
- Optimized Algorithms: Efficient cube state representation and move execution
- Smart Scrambling: Prevents invalid move sequences and ensures proper randomization
- Memory Efficient: Minimal memory footprint with zero-copy data access
- Cross-Platform: Compiled WASM files work across all browsers and platforms
The compiled WASM files (.wasm
, .js
, .d.ts
) are intentionally committed to the repository because:
- Deployment Compatibility: Cloudflare Pages and similar platforms don't support Rust compilation
- Build Reliability: Ensures consistent performance across all environments
- Zero Dependencies: No need for Rust toolchain in production builds
For more details, see the WASM module documentation.
The scramble generator creates WCA-compliant 3x3x3 cube scrambles:
- Standard Length: 20 moves (configurable 15-30)
- Valid Moves: R, L, U, D, F, B with modifiers (', 2)
- Smart Algorithm: Prevents invalid sequences and ensures randomness
- Visual Display: Moves grouped for easy reading
- 3D Visualization: Optional step-by-step 3D cube preview
- No consecutive moves on the same face (e.g., R R')
- No alternating opposite faces (e.g., R L R)
- Proper randomization using cryptographically secure methods
Times are stored in JSON format with the following structure:
{
"id": "1640995200000",
"time": 15420,
"scramble": "R U R' U' R' F R F' U2 R U' R'",
"date": "2023-12-31T23:59:59.999Z",
"penalty": "+2"
}
id
: Unique timestamp identifiertime
: Solve time in millisecondsscramble
: WCA scramble stringdate
: ISO 8601 timestamppenalty
: Optional penalty ("DNF" or "+2")
We welcome contributions from developers of all skill levels! Please see our Contributing Guidelines for detailed information on how to get started.
- Fork the repository on GitHub
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Make your changes following our coding standards
- Test your changes thoroughly
- Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
- Follow TypeScript and React best practices
- Use ESLint and Prettier for code formatting
- Write meaningful commit messages
- Test on multiple devices and browsers
- Maintain accessibility standards
- Read our Code of Conduct
For detailed contribution guidelines, development setup, and coding standards, please refer to CONTRIBUTING.md.
- Lazy Loading: Components loaded on demand
- Memoization: React.memo and useMemo for expensive calculations
- Local Storage: Efficient data persistence
- Optimized Rendering: Minimal re-renders during timer operation
- Tree Shaking: Only necessary code included in build
- Keyboard Navigation: Full keyboard support
- Screen Reader: ARIA labels and semantic HTML
- Color Contrast: WCAG 2.1 AA compliant
- Focus Indicators: Clear focus states
- Reduced Motion: Respects user preferences
- Chrome 90+ (desktop)
- Firefox 88+ (desktop)
- Safari 14+ (desktop)
- Edge 90+ (desktop)
Note: Requires physical keyboard for timer controls. Mobile browsers are not currently supported.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- ✅ Commercial use allowed
- ✅ Modification allowed
- ✅ Distribution allowed
- ✅ Patent use allowed
- ✅ Private use allowed
- ℹ️ License and copyright notice required
- ℹ️ State changes required
For the full license text, see LICENSE.
- Inspired by cstimer - the gold standard for online cube timers
- World Cube Association (WCA) for scramble algorithms and regulations
- The global speedcubing community for feedback and support
- All contributors who help make this project better
- Open source libraries and tools that make this project possible
If you discover a security vulnerability, please follow our Security Policy for responsible disclosure. Do not report security issues through public GitHub issues.
- Mobile touch controls and responsive interface
- Internationalization (i18n) and multiple language support
- Multiple puzzle support (2x2, 4x4, etc.)
- Advanced statistics and graphs
- Competition mode with inspection time
- Cloud synchronization
- Custom themes
- Session management
- Training modes (F2L, OLL, PLL)
- Sound effects and notifications
- Mobile app (React Native)
- Multiplayer racing
- Advanced scramble algorithms
- Competition timing features
If you encounter any issues, please create an issue on GitHub with:
- Steps to reproduce
- Expected behavior
- Actual behavior
- Browser and version
- Screenshots (if applicable)
Q: How accurate is the timer?
A: The timer uses performance.now()
for sub-millisecond accuracy and updates every 10ms during solving.
Q: Are the scrambles WCA official? A: Yes, the scrambles follow WCA regulations for 3x3x3 cubes with proper move notation and sequence validation.
Q: Can I use this offline? A: Yes, the app works offline after the initial load thanks to Next.js static optimization.
Q: Does this work on mobile devices? A: Currently, the timer requires a physical keyboard for proper operation and is optimized for desktop use. Mobile support is planned for future releases.
Q: How do I backup my times? A: Use the Export function in Settings to download a JSON file with all your data.
Q: Is my data private? A: Yes, all data is stored locally in your browser. Nothing is sent to external servers. See our Security Policy for more details.
Q: Can I contribute to this project? A: Absolutely! We welcome contributions. Please read our Contributing Guidelines and Code of Conduct to get started.
Happy Cubing! 🎲