Interactive 2D/3D graphing calculator with an equation solver, LaTeX input, and a virtual math keyboard. Installable as a PWA.
- 2D & 3D graphing — algebraic, trigonometric, parametric, polar, implicit, differential, calculus, series, inequality, slider, and points expressions
- Built-in templates — 31 quick-insert templates available through the command palette
- Equation solver — algebra, calculus, trigonometry, matrices, vectors, ODE, and statistics categories
- Graph overlays — tangent line, analysis overlay, interaction overlay, curvature overlay, and polar grid
- Advanced visualization — fractal exploration (Mandelbrot/Julia), slope fields, phase portraits, and table view
- Editor UX — folders, drag-and-drop reordering, sliders, color picker, regression options, CSV/TSV import
- Productivity — command palette, keyboard shortcuts overlay, dark/light theme, shareable
?e=<base64>URLs
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, Turbopack dev, React 19) |
| Language |
TypeScript (strict mode, @/* path aliases) |
| State |
Zustand — 4 atomic stores with zundo temporal middleware for undo/redo and zustand/persist for localStorage |
| Styling |
Tailwind CSS v4 with CSS custom properties for theming, next-themes for class-based dark mode |
| Math input |
MathLive — LaTeX editor (dynamically imported via next/dynamic) |
| Symbolic math | CortexJS Compute Engine — parsing, evaluation, compilation (dynamically imported) |
| 2D rendering | Mafs — SVG graph layer for axes, standard plots, and implicit contours via marching squares |
| 3D rendering | Three.js / React Three Fiber + Drei — GPU surface shaders with CPU fallback |
| Fractals | Custom WebGL2 fragment shaders (Mandelbrot, Julia) |
| Performance |
Web Workers (Comlink) — Offloading of heavy |
| Drag & drop | @dnd-kit for sortable expression reordering |
| PWA | Installable static PWA powered by @ducanh2912/next-pwa with generated Workbox service worker |
| Linting |
ESLint 9 flat config with eslint-config-next (core-web-vitals + TypeScript) |
-
Server Components by default —
'use client'only on interactive leaf components -
No business logic in components — all math, evaluation, and parsing lives in
lib/ -
Web Workers for Math Evaluation — CPU-intensive math loops (implicit curves, Runge-Kutta ODE integration, 3D grids) are compiled (
ceCompile) and executed entirely inside web workers usingComlinkto prevent main thread blocking. Simple$O(N)$ operations remain synchronous to avoid IPC latency. - Dynamic imports for heavy libraries (MathLive, Three.js, Compute Engine) to keep the initial bundle small
- WebGL2 shaders for performance-critical rendering: fractal overlays and 3D surface materials
- State split by concern — expression, graph, solver, and UI stores keep subscriptions focused
CSS custom properties defined in globals.css drive both light and dark palettes. Tailwind v4's @custom-variant dark maps to the .dark class set by next-themes. MathLive keyboard and Mafs graph colors are overridden to match via the same token set. An 8-color graph palette (indigo, rose, amber, emerald, sky, violet, orange, teal) rotates across expressions.
app/ Routes, layouts, metadata, PWA manifest
components/
ui/ Buttons, tabs, command palette, theme toggle
graph/ Graph viewport, 2D/3D renderers, overlays, table view, plot components
editor/ Expression list, math field, sliders, color picker, data import
solver/ Solver panel, input, solution display
layout/ Toolbar, sidebar, mobile sheet, shortcuts overlay
lib/
math/ Parser, evaluator, solver, analysis, ODE, regression, statistics,
matrix/vector ops, differential geometry, worker pool
graph/ WebGL utils, curve/fractal/implicit/surface shaders, grid utils
latex/ LaTeX → Compute Engine converter
hooks/ use-expressions, use-solver, use-keyboard-shortcuts, use-touch-gestures, …
stores/ Zustand stores (expression, graph, solver, UI)
providers/ ThemeProvider (next-themes)
types/ Shared TypeScript interfaces
public/ Static assets, icons, MathLive fonts
- Bun (recommended) or Node.js ≥ 18
bun install
bun devOpen http://localhost:3000.
The dev server uses Turbopack. Service worker generation is disabled in development and generated by next-pwa for production builds.
npm install
npm run dev| Command | Description |
|---|---|
bun run dev |
Start dev server (Turbopack) |
bun run build |
Production static export build (webpack + next-pwa SW generation) |
bun run start |
Serve production build |
bun run lint |
ESLint (flat config) |
docker build -t grapher .
docker run --rm -p 3000:80 grapherThen open http://localhost:4003.
Private.