Welcome to Material Explorer! This application allows you to interactively create, customize, and visualize materials in 3D. Leveraging the power of React Three Fiber, it offers real-time feedback on changes to material properties such as color, metalness, and roughness. The app is designed to be responsive and user-friendly, ensuring a seamless experience across various devices and screen sizes.
- Live app (GitHub Pages): https://mikechaves.github.io/material-explorer
- Repository: https://github.com/mikechaves/material-explorer
- Docs & backlog: docs/README.md
- Added rapid-iteration editor tools: draft autosave/restore, duplicate material, randomize material, clear textures, and draft JSON import/export.
- Added concise Power Tools tooltips for better in-editor discoverability.
- Kept CI and quality gates green while reducing maintenance noise for this personal project.
- Upgraded core stack: React 19, Vite 7, TypeScript 5.9, Tailwind CSS 4, ESLint 9.
- Improved editor workflow: command palette, onboarding starter kit, draft unsaved state, undo/redo history, and section reset controls.
- Stronger quality/security defaults: CI-quality script chain, bundle budgets, Playwright coverage, and dependency overrides (including
jsonpath).
- PBR / Physical materials: color, metalness, roughness, emissive, clearcoat, transmission/IOR, opacity
- Texture maps: base color, normal (+ scale), roughness, metalness, AO (+ strength), emissive, alpha (+ cutoff), plus tiling (U/V)
- Live 3D preview: model picker, HDRI/environment picker, zoom/grid/background toggles, reset view, PNG snapshot, A/B compare
- Library UX: favorites, tags, search/sort, tag filter chips, bulk actions, manual drag-to-reorder
- In-app feedback: non-blocking toast notifications for import/export/share outcomes
- Power Tools: duplicate, randomize, clear textures, draft JSON import/export, autosave/restore
- Import/Export:
- JSON presets (single + whole library)
- GLB export per material and GLB export of the library (grid of preview spheres)
- Responsive layout: mobile drawer sidebar + editor stacks preview above controls
- Node.js (version 20.x or higher)
- npm (comes with Node.js)
To run Material Explorer locally, follow these steps:
-
Clone the repository:
git clone https://github.com/mikechaves/material-explorer.git
-
Navigate to the project directory:
cd material-explorer -
Install dependencies:
npm install
To start the development server:
npm run devnpm start is an alias for npm run dev.
The app opens at http://localhost:5173 and reloads on file changes.
Quick pre-PR checks:
npm run quality:ciFull local gate run (matches CI):
npm run quality:fullEquivalent expanded steps:
npm run check-format
npm run lint
npm run type-check
npm run test:ci
npm run build
npm run check:bundle
npm run test:e2e
npm run security:auditInstall Playwright browsers once (or after Playwright upgrades):
npx playwright install --with-deps chromiumThe repository runs these checks in GitHub Actions on pull requests and on pushes to main.
npm run buildThis command builds the app for production to the build folder. The build is minified and hashed for caching.
Material persistence defaults to local storage. To enable backend sync with local fallback, set:
VITE_MATERIALS_API_URL=https://your-api.example.com
VITE_MATERIALS_USER_SCOPE=user-123
# optional: if your API expects bearer auth
VITE_MATERIALS_AUTH_TOKEN=token-valueWhen set, the app uses:
GET /materials?scope=<scope>to hydrate the library on startupPUT /materials?scope=<scope>to persist updates
If the API is unavailable, the app continues using local storage. The sidebar will show a non-blocking sync warning when remote sync fails while local persistence still succeeds.
Local fallback is also scope-aware:
- default key:
materials - scoped key:
materials:<scope>
To forward web-vitals, unhandled errors, and sync-failure telemetry to your backend, set:
VITE_TELEMETRY_URL=https://your-observability.example.com/eventsTelemetry is best-effort and never blocks user actions.
Current telemetry events include:
web-vitalwindow.errorwindow.unhandledrejectionmaterials.save.*andmaterials.load.*sync failure pathspreview.first_enabledpreview.first_readytexture.upload.*outcomes
In development mode, use the bottom-right Telemetry button to inspect recent emitted events locally.
For local backend/sync iteration, run the built-in mock API:
npm run mock:apiThen point the app to it:
VITE_MATERIALS_API_URL=http://localhost:8787
VITE_MATERIALS_USER_SCOPE=local-user
VITE_TELEMETRY_URL=http://localhost:8787/eventsAvailable routes on the mock server:
GET /healthGET /materials?scope=<scope>PUT /materials?scope=<scope>POST /eventsGET /events
- Use the editor controls to set PBR parameters and textures.
- Click Save Material to add it to your library.
- Click Edit on a card in the sidebar to load it into the editor.
- Adjust properties and click Update Material.
- Click Delete on a card in the sidebar to remove it from your collection.
- Share link: copies a URL that encodes the material settings.
- “Share link” excludes textures.
- “Share + tex” attempts to include textures, but will refuse if the URL is too large.
- Export JSON: best for sharing materials with textures reliably.
- Export GLB: exports preview geometry with the material applied (portable glTF 2.0 binary).
- LocalStorage quota: textures are stored as data URLs inside saved material JSON; large images can exceed browser storage limits.
- GLB exports are previews: GLB contains preview geometry (sphere/grid), not an imported user mesh.
- React 19
- Vite
- Three.js
- React Three Fiber
- TypeScript
- Tailwind CSS 4
- Vitest
- Playwright
- ESLint 9 + Prettier
Contributions to Material Explorer are welcome! Please follow these steps:
- Fork the repository
- Create a new branch for your feature
- Make your changes
- Submit a pull request
Material Explorer is released under the MIT License. See the LICENSE file for more information.