Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

138 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MixMyCloud Logo

MixMyCloud

DIY e-liquid calculator — mix smarter, not harder.
A lightweight, offline-ready web app for crafting custom e-liquid recipes.

🔗 mixmy.cloud/en — try it live, no install or account needed  ·  French version

Vanilla JS Three.js Static

MixMyCloud interface — targets, ingredients, and live summary


Features

  • "MyMix" — build a recipe from scratch — target your desired outcome (nicotine, PG/VG ratio, water/vodka/PGA) and let the solver calculate the volumes, or enter volumes you already have and see the resulting recipe
  • "MixMyMix" — adapt a recipe you already have — describe your current mix and the mix you're aiming for, and the app works out exactly what to add
  • Multi-ingredient support — add as many flavor concentrates as needed, with individual PG base ratios
  • Nicotine base flexibility — supports PG, VG, or mixed nicotine bases
  • PDF, Markdown & JSON export — save and share your recipes
  • Fully bilingual — French / English interface
  • Fluid background — WebGL fluid simulation + Three.js volumetric smoke, GPU-optimized (30fps cap, Visibility API pause)
  • No installation, no account, no data sent anywhere — runs entirely in your browser

Running locally

Why a local server? The app uses ES modules (type="module") for Three.js. Browsers block these on the file:// protocol for security reasons — you must serve the project over HTTP(S), even locally.

HTTP or HTTPS? The page sets a Content-Security-Policy with upgrade-insecure-requests. Safari enforces this even on localhost and will fail to load over plain http://. Firefox exempts localhost and works fine over plain HTTP. Chromium-based browsers (Chrome/Edge) may behave either way depending on the version. The HTTPS method below works in every browser — use it if unsure. The plain-HTTP method is only a quick shortcut for Firefox.

macOS / Linux — HTTPS (recommended, works everywhere)

Python 3 and OpenSSL are pre-installed on macOS and most Linux distributions. A self-signed certificate and the serve-https.py launcher are already included in the repo (the certs/ folder is git-ignored; generate it once if missing — see below).

git clone https://github.com/Albabit/MixMyCloud.git
cd MixMyCloud
python3 serve-https.py          # serves on https://localhost:8080

Then open https://localhost:8080 in your browser. Press Ctrl+C to stop.

One-time trust step (for Safari/Chrome to accept the local certificate): double-click certs/localhost-cert.pem → in Keychain Access, set the localhost entry to Always Trust. Or, in a terminal:

sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain certs/localhost-cert.pem
Regenerate the certificate (only if certs/ is missing)
mkdir -p certs
openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout certs/localhost-key.pem -out certs/localhost-cert.pem \
  -days 825 -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1"

macOS / Linux — plain HTTP (Firefox only, quick shortcut)

python3 -m http.server 8080

Then open http://localhost:8080 in Firefox. ⚠️ This will not load correctly in Safari.


Windows — HTTPS (recommended, works in Chrome/Edge)

The included serve-https.py is cross-platform and runs the same way on Windows. You need Python 3 and OpenSSL (OpenSSL ships with Git for Windows — already installed if you used git clone).

git clone https://github.com/Albabit/MixMyCloud.git
cd MixMyCloud
python serve-https.py          # serves on https://localhost:8080

Then open https://localhost:8080. Press Ctrl+C to stop.

One-time trust step (so Chrome/Edge accept the local certificate): import certs\localhost-cert.pem into the current user's Trusted Root Certification Authorities store. From a terminal (no admin needed):

certutil -addstore -user Root certs\localhost-cert.pem

Or double-click certs\localhost-cert.pemInstall CertificateCurrent User → place it in Trusted Root Certification Authorities.

Chrome and Edge use the Windows certificate store, so the step above covers them. Firefox keeps its own store, but Firefox already loads the app fine over plain HTTP (see below).

Regenerate the certificate (only if certs\ is missing)

Run in Git Bash (OpenSSL on PATH):

mkdir -p certs
openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout certs/localhost-key.pem -out certs/localhost-cert.pem \
  -days 825 -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1"

Windows — plain HTTP (Firefox only, quick shortcut)

Option A — Python:

python -m http.server 8080

Option B — Node.js:

npx serve .

Option C — VS Code (easiest for non-developers):

  1. Install the Live Server extension
  2. Open the project folder in VS Code
  3. Right-click index.htmlOpen with Live Server

Then open the served URL in Firefox. ⚠️ Chrome/Edge may fail to load over plain HTTP — use the HTTPS method above for those.


Project structure

MixMyCloud/
├── index.html          # Single-page app entry point (French)
├── en/index.html        # English entry point — same body as index.html (see dev/sync-en.js)
├── style.css           # UI styling
├── favicon.ico          # Root favicon (browsers request this regardless of <link rel="icon">)
├── robots.txt / sitemap.xml  # Search engine indexing
├── .htaccess            # HTTPS/canonical-host redirect + cache headers
├── LICENSE              # All rights reserved
├── serve-https.py      # Local HTTPS dev server (works in every browser)
├── certs/              # Local HTTPS certificate (git-ignored — see "Running locally" above)
├── img/                # Logos & favicon source
├── js/
│   ├── app.js               # Core calculator logic & UI (IIFE)
│   ├── ing-row-category.js  # Ingredient-row category accent color
│   ├── vapor.js             # Three.js smoke background
│   ├── fluid.js             # WebGL fluid simulation config
│   ├── fluid-lib.js         # WebGL fluid engine (local fork of WebGLFluidEnhanced 0.8.0)
│   └── jspdf.umd.min.js     # Vendored jsPDF, used for native PDF export
└── dev/                # Dev-only tooling, not shipped with the app
    ├── dom-smoke.js          # Headless JSDOM smoke-test harness (npm run smoke)
    └── sync-en.js            # Keeps index.html's and en/index.html's <body> identical

Tech stack

Layer Technology
UI & logic Vanilla JavaScript (no framework)
3D smoke Three.js 0.160.1 via ES module CDN
Fluid sim WebGLFluidEnhanced 0.8.0 (de-minified local fork)
PDF export jsPDF — drawn natively (text/shapes), not a screenshot of the page, so it renders identically across browsers
Styling Pure CSS

Made with ☕ and curiosity — From France with love 🇫🇷

About

A lightweight, offline-ready web app for crafting custom e-liquid recipes.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages