--- title: "Node.js + Vanilla JS Lightweight Tools" aliases: [nodejs-proxy, vanilla-js, lightweight-tools] tags: [nodejs, vanilla-js, proxy, lightweight, no-build] sources: [01 Projects/3m-portal, 01 Projects/ferrero-ac-creator, 01 Projects/homepage] created: 2026-04-15 updated: 2026-04-15 --- # Node.js + Vanilla JS Lightweight Tools For simple client tools that don't need a frontend build step. Node.js serves static files and acts as a proxy for third-party APIs. ## Key Takeaways - Use when: no React needed, no TypeScript, no build pipeline - `server.js` does two things: serve static HTML/JS/CSS files + proxy `/api/*` to third-party APIs - No Docker — just `node server.js` or `npm start` - No transpilation, no bundling — open file in browser or hit localhost directly - This pattern is for simple client-facing portals and utility tools ## When to Use - Wrapping a third-party API that has CORS restrictions - Small client portals (translation tools, booking tools) - Rapid prototypes that don't need SSR or TypeScript ## Key Details ### server.js Structure ```js const http = require('http') const fs = require('fs') const path = require('path') const https = require('https') const server = http.createServer((req, res) => { if (req.url.startsWith('/api/')) { // Proxy to third-party API proxyRequest(req, res) } else { // Serve static files serveStatic(req, res) } }) server.listen(3000) ``` ### CORS Proxy Behavior (3M Portal) - Strips/rewrites `Location` headers on 301/302 → returns 401 (prevents auth redirect loops) - Injects CORS headers on all `/api` responses - Masks sensitive data (passwords) in logs ## Projects Using This Pattern - [[01 Projects/3m-portal/3M OMG Portal|3M OMG Portal]] — Node.js CORS proxy for One2Edit API (:3000) - [[01 Projects/ferrero-ac-creator/Ferrero AC Booking Tool|Ferrero AC Booking]] — Node.js server for Box API + CSV download (:3456) - [[01 Projects/homepage/Homepage Dashboard|Homepage Dashboard]] — Node.js static server for YAML-configured dashboard ## Comparison: When to Choose What | Need | Choose | |------|--------| | No CORS issues, pure static | Open `index.html` directly (Ferrero "Download CSV" mode) | | CORS proxy needed | `node server.js` | | Auth + complex logic | FastAPI (Python) | | SSR + complex routing | Next.js | ## Gotchas & Lessons - `sessionStorage` (not `localStorage`) for auth tokens — clears on browser close (3M Portal) - Always mask passwords in proxy logs - 301/302 from API = auth failure in One2Edit — convert to 401 at proxy level - These tools have no test suite — test manually ## Related - [[wiki/tech-patterns/one2edit-api|one2edit-api]] — uses this proxy pattern - [[wiki/tech-patterns/fastapi-python-docker|fastapi-python-docker]] — heavier alternative