Muryo is a small full-stack demo project that integrates a dynamic "clutter" background (p5.js + matter-js) into a React front-end, alongside a simple product management API (Express + MongoDB) on the server.
This README summarizes how the repository is organized, how to run the project locally, key architectural details, and common troubleshooting steps.
- Framework: React (v19.2.0) with Create React App (react-scripts v5.0.1)
- Visuals / Physics: p5.js (v1.1.9, instance mode) and matter-js (v0.20.0)
- Styling: Plain CSS (global CSS files and component CSS)
- Animations: p5-driven rendering for the background + CSS keyframe transitions for UI
- Client build: Create React App (react-scripts) — development server and bundling
- Server: Node.js + Express (express v5.1.0)
- Database: MongoDB (access via Mongoose v8.20.1)
- Utilities: CORS, dotenv for env vars, nodemon for server auto-reload during development
- Linting / Formatting: ESLint (provided via react-scripts toolchain); add config as needed
- Deployment: Digital Ocean
- client/
- package.json
- public/
- index.html
- src/
- index.js
- index.css
- App.js
- pages/
- events/
- events.jsx
- events.css
- homepage/
- homepage.jsx
- homepage.css
- login/
- login.jsx
- login.css
- products/
- products.jsx
- products.css
- users/
- users.jsx
- users.css
- components/
- clutter_js/ (p5 + matter modular code)
- sketch.js // exports initBackground({ parent, P5, Matter }) -> API ({ newPalette, remove, getColors })
- scripts/
- textures.js // texture generators (bound to a p5 instance via bindTextures)
- m_grfx.js
- m_cloud.js
- m_ring.js
- m_sphere.js
- circ.js
- update.js // palette switching logic only
- icons/ (static SVG files)
- background.jsx // React wrapper that mounts/manages the p5 instance
- shuffle.jsx // Shuffle button component that triggers palette change
- DateDisplay.jsx
- manageColor.js
- ProtectedRoute.js
- sidebar/
- sidebar.jsx
- sidebar.css
- server/
- package.json
- server.js
- src/
- routes/products.js
- models/product.js
Prerequisites: Node.js (v16+ recommended) and a running MongoDB instance (local or Atlas).
- Start the server
cd server
npm install
# Create a .env file with MONGO_URI (e.g. MONGO_URI=mongodb://localhost:27017/muryo)
npm startBy default the server listens on port 5000 (check server/server.js for PORT).
- Start the client
cd client
npm install
npm startThe front-end dev server usually runs at http://localhost:3000.
- Open the app
Visit http://localhost:3000 in your browser and try the UI (homepage, product listing, add product).
-
The animated background is a p5 sketch running in instance mode and driven by matter-js physics. The sketch code is modularized under
client/src/components/clutter_js. -
The original website is here
-
sketch.jsprovides an initializerinitBackground({ parent, P5, Matter })that mounts a p5 canvas into a DOM container and returns a small API object exposing:newPalette()— switch to a new color palette and attempt to regenerate texturesremove()— remove the p5 instance and clean up runner/graphicsgetColors()— return current palette colors in hex
-
Texture generators in
textures.jsare designed to be bound to a p5 instance usingbindTextures(p, STATE). This avoids relying on a globalp5and allows safe instance-level graphics creation withp.createGraphics(). -
For coordinating colors between the sketch and React components there are a couple of options already in the repo:
window.__clutter_instance.getColors()andwindow.__clutter_getColors()for quick console inspection- a React
ColorContextthat can receive updates when the sketch palette changes (seebackground.jsxwhich calls the initializer and reads colors)
-
To avoid double-initializing p5 (React StrictMode or accidental remounts), the sketch includes a simple singleton guard (
window.__clutter_instance) and attempts to remove orphaned canvases on init.
The server exposes a simple products API implemented in server/src/routes/products.js:
GET /api/products— list all productsPOST /api/products— create a new product (JSON body with product fields)DELETE /api/products/:id— delete a product by id
Ensure your client uses the correct port when calling these endpoints (http://localhost:5000/api/products by default). If you see CORS or 403 errors, check server CORS configuration and the client URL.
-
CORS errors when client calls the server
- Verify
server.jsconfig includescors()or an explicit origin list that allowshttp://localhost:3000.
- Verify
-
"Cannot find module './icons/*.svg'" webpack error
- Ensure
client/src/components/sidebar/icons/exists and contains the required SVGs or change imports to use a supported icon library.
- Ensure
-
"A component is changing an uncontrolled input to be controlled"
- Make sure every form input's
valueprop corresponds to a key initialized on theformDataobject (avoidundefinedvalues). The products form expects keys likeimageURLanddescription.
- Make sure every form input's
-
Duplicate or overlapping canvases / multiple sketches
- Inspect the DOM for multiple
<canvas>elements (document.querySelectorAll('canvas')). The sketch uses a singleton guard and also tries to remove orphaneddefaultCanvas0elements. If multiple instances persist, ensureinitBackground()is called only once, or call the returnedremove()before re-initializing.
- Inspect the DOM for multiple
-
Palette change doesn't update textures
- Textures created with
p.createGraphics()are cached.newPalette()attempts to remove old graphics and clearpg_grfxto force regeneration. If you still see old colors, ensurenewPalette()runs before re-creating graphics or explicitly removes old graphics' canvases.
- Textures created with
-
Consider exposing a
forceNewoption forinitBackground({ forceNew: true })to deliberately recreate the p5 instance (useful during HMR). -
Add a tiny smoke test that mounts and unmounts
initBackgroundto catch runtime regressions in CI. -
Consolidate palette definitions into a single module (e.g.
manageColor.js) and keepupdate.jsas a simple trigger to switch palettes. -
Improve type-safety by adding TypeScript types for the public API of
initBackgroundand the color objects.
client/src/components/clutter_js/sketch.js— the main p5 initializer and sketch logicclient/src/components/clutter_js/scripts/textures.js— texture generator helpersclient/src/components/background.jsx— React wrapper that mounts the sketch and shares colors via contextserver/src/routes/products.js— product REST API