NutriCompass is a comprehensive, evidence-based nutrition and supplement recommendation application. It helps users understand what nutrients, vitamins, minerals, herbs, and Ayurvedic plants might support their health goals β and how to use them responsibly.
- Features
- Screenshots
- Prerequisites
- Quick Start (Local Development)
- Project Structure
- Building for Production
- Deployment Options
- Environment Variables
- Firebase Setup (Optional Cloud Sync)
- Customization
- API Integration (Future)
- Contributing
- License
- Describe your health goals in natural language
- App interprets and identifies relevant body systems
- Smart matching to appropriate supplements
- Vitamins: A, B-Complex, C, D3, E, K2
- Minerals: Magnesium, Zinc, Iron, Selenium, Calcium
- Ayurvedic Herbs: Ashwagandha, Brahmi, Tulsi, Shatavari, Triphala, Guduchi, Shilajit
- Western Herbs: Rhodiola, Valerian, St. John's Wort, Milk Thistle
- Medicinal Mushrooms: Lion's Mane, Reishi, Cordyceps
- Amino Acids: L-Theanine, Glycine, NAC, Creatine, L-Citrulline
- Performance: Beta-Alanine, HMB, Beetroot Extract, BCAAs
- Strong Evidence: Multiple human clinical trials
- Moderate Evidence: Some clinical research
- Limited/Traditional: Primarily traditional use
- Compare forms (e.g., Magnesium Glycinate vs Citrate vs Oxide)
- Bioavailability ratings
- Absorption enhancers and blockers
- Best timing recommendations
- Smart search across all fields
- Quick filter presets (Beginner Essentials, Sleep Stack, Nootropics, etc.)
- Multi-dimensional filtering (type, evidence, goals, body systems)
- Three view modes (List, Grid, Compact)
- Personalized recommendations based on profile
- Personalized nutrient targets built from NIH Dietary Reference Intakes
- Priority indicators based on diet, age, and lifestyle
- Food-first guidance with supplement tie-ins
- Food-source tables with % NRV for vitamins and minerals (EU reference values)
- CIQUAL + EuroFIR food composition sources
- Research-based reference doses for nonβNRV compounds (e.g., melatonin, creatine, CoQ10)
- Search USDA FoodData Central and Open Food Facts with offline fallback caching
- Quick macro snapshots (calories, protein, carbs, fat)
- Build custom supplement stacks
- Automatic interaction/conflict detection
- Timing optimization
- Morning/Afternoon/Evening organization
- Curated stacks for common goals with synergy notes
- Daily check-ins for sleep, energy, mood, focus, and recovery
- Log supplements taken with notes and side-effect tracking
- Lab result tracking with smart insights for common markers
- Rolling summaries for adherence and average scores
- Optional user profile (age, diet, training style, health conditions)
- Tailored recommendations
- Lifestyle-aware suggestions
- BMI, BMR, and TDEE estimates from profile inputs
- "Why This, Not That?" comparisons
- Misinformation alerts
- Form guidance
- Safety education
- Drug interaction warnings
- Pregnancy/breastfeeding cautions
- Condition-specific warnings
- Cycling recommendations
The application features a clean, modern interface with:
- Natural language goal input
- Evidence-graded supplement cards
- Interactive stack builder
- Advanced filtering system
Before running NutriCompass, ensure you have the following installed:
-
Node.js (v18.0.0 or higher)
# Check version node --version # Install via nvm (recommended) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash nvm install 18 nvm use 18
-
npm (v9.0.0 or higher) or yarn (v1.22.0 or higher)
# Check npm version npm --version # Or install yarn npm install -g yarn
- Docker (for containerized deployment)
- Nginx or Apache (for static file serving)
- Git (for version control)
# If using git
git clone https://github.com/yourusername/nutricompass.git
cd nutricompass
# Or download and extract the ZIP file# Using npm
npm install
# Or using yarn
yarn install# Using npm
npm run dev
# Or using yarn
yarn devThe app will be available at:
http://localhost:5173
The development server features:
- β‘ Hot Module Replacement (HMR)
- π Auto-refresh on file changes
- π TypeScript error reporting
- π¨ Tailwind CSS JIT compilation
# Run ESLint to check for code quality issues
npm run lint
# Run ESLint and auto-fix issues
npm run lint:fix
# TypeScript type checking
npm run typechecknutricompass/
βββ public/ # Static assets
βββ src/
β βββ components/
β β βββ AdvancedBrowse.tsx # Advanced browse engine
β β βββ EducationalGuide.tsx # Educational content
β βββ constants/
β β βββ taxonomy.ts # Centralized goal/system taxonomy
β βββ data/
β β βββ curatedStacks.ts # Curated goal-based stacks
β β βββ nutrientRequirements.ts # Nutrient target guidance
β β βββ nutrientFoodSources.ts # Nutrient β food source helpers
β β βββ supplements.ts # Supplement database + nutrient food data
β βββ types/
β β βββ index.ts # TypeScript interfaces
β βββ utils/
β β βββ analyzer.ts # NLP goal analysis with negation handling
β β βββ normalization.ts # Text normalization helpers
β β βββ cn.ts # Class name helper
β βββ App.tsx # Main application
β βββ main.tsx # Entry point
β βββ index.css # Global styles + Tailwind
βββ index.html # HTML template
βββ package.json # Dependencies & scripts
βββ tsconfig.json # TypeScript config
βββ vite.config.ts # Vite config
βββ server.js # Express server for production
βββ Dockerfile # Docker configuration
βββ docker-compose.yml # Docker Compose configuration
βββ nginx.conf # Nginx configuration
βββ vercel.json # Vercel deployment config
βββ netlify.toml # Netlify deployment config
βββ README.md # This file
# Using npm
npm run build
# Or using yarn
yarn buildThis creates an optimized production build in the dist/ folder:
dist/
βββ index.html
βββ assets/
β βββ index-[hash].js # Bundled JavaScript
β βββ index-[hash].css # Bundled CSS
βββ ...
# Using npm
npm run preview
# Or using yarn
yarn previewThis starts a local server at http://localhost:4173 serving the production build.
Nginx is excellent for serving static files with high performance.
# Ubuntu/Debian
sudo apt update
sudo apt install nginx
# CentOS/RHEL
sudo yum install nginx
# macOS
brew install nginxCreate a configuration file /etc/nginx/sites-available/nutricompass:
server {
listen 80;
server_name your-domain.com www.your-domain.com;
# Root directory (adjust path as needed)
root /var/www/nutricompass/dist;
index index.html;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/javascript;
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# SPA fallback - serve index.html for all routes
location / {
try_files $uri $uri/ /index.html;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
}# Build the project
npm run build
# Copy dist to server
sudo mkdir -p /var/www/nutricompass
sudo cp -r dist/* /var/www/nutricompass/
# Enable site
sudo ln -s /etc/nginx/sites-available/nutricompass /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Restart Nginx
sudo systemctl restart nginx# Install Certbot
sudo apt install certbot python3-certbot-nginx
# Get certificate
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
# Auto-renewal is configured automatically# Ubuntu/Debian
sudo apt update
sudo apt install apache2
# Enable required modules
sudo a2enmod rewrite
sudo a2enmod headersCreate /etc/apache2/sites-available/nutricompass.conf:
<VirtualHost *:80>
ServerName your-domain.com
ServerAlias www.your-domain.com
DocumentRoot /var/www/nutricompass/dist
<Directory /var/www/nutricompass/dist>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
# SPA fallback
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</Directory>
# Compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
</IfModule>
# Caching
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
</IfModule>
# Security headers
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
</VirtualHost># Build and copy
npm run build
sudo mkdir -p /var/www/nutricompass
sudo cp -r dist/* /var/www/nutricompass/
# Enable site
sudo a2ensite nutricompass.conf
sudo systemctl restart apache2For environments where you want a Node.js server.
Create server.js in the project root:
const express = require('express');
const path = require('path');
const compression = require('compression');
const app = express();
const PORT = process.env.PORT || 3000;
// Enable gzip compression
app.use(compression());
// Serve static files from dist folder
app.use(express.static(path.join(__dirname, 'dist'), {
maxAge: '1y',
etag: false
}));
// SPA fallback - serve index.html for all routes
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});
app.listen(PORT, () => {
console.log(`πΏ NutriCompass running at http://localhost:${PORT}`);
});# Install production dependencies
npm install express compression
# Build the app
npm run build
# Start the server
node server.js
# Or use PM2 for production
npm install -g pm2
pm2 start server.js --name nutricompass
pm2 save
pm2 startupCreate Dockerfile in the project root:
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci
# Copy source files
COPY . .
# Build the app
RUN npm run build
# Production stage
FROM nginx:alpine
# Copy custom nginx config
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Copy built assets from builder
COPY --from=builder /app/dist /usr/share/nginx/html
# Expose port
EXPOSE 80
# Start nginx
CMD ["nginx", "-g", "daemon off;"]Create nginx.conf in the project root:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# Gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# SPA fallback
location / {
try_files $uri $uri/ /index.html;
}
}version: '3.8'
services:
nutricompass:
build: .
ports:
- "80:80"
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3# Build Docker image
docker build -t nutricompass .
# Run container
docker run -d -p 80:80 --name nutricompass nutricompass
# Or use docker-compose
docker-compose up -d
# View logs
docker logs -f nutricompass
# Stop container
docker stop nutricompassVercel offers the easiest deployment with automatic CI/CD.
# Install Vercel CLI
npm install -g vercel
# Login
vercel login
# Deploy (from project root)
vercel
# Deploy to production
vercel --prod- Push your code to GitHub
- Go to vercel.com
- Click "New Project"
- Import your GitHub repository
- Vercel auto-detects Vite and configures everything
- Click "Deploy"
{
"buildCommand": "npm run build",
"outputDirectory": "dist",
"framework": "vite",
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}# Install Netlify CLI
npm install -g netlify-cli
# Login
netlify login
# Build the project
npm run build
# Deploy draft
netlify deploy --dir=dist
# Deploy to production
netlify deploy --dir=dist --prod- Push code to GitHub
- Go to netlify.com
- Click "New site from Git"
- Connect your repository
- Set build command:
npm run build - Set publish directory:
dist - Click "Deploy site"
Create netlify.toml in project root:
[build]
command = "npm run build"
publish = "dist"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[[headers]]
for = "/assets/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"Update vite.config.ts:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
base: '/nutricompass/', // Your repo name
})Create .github/workflows/deploy.yml:
name: Deploy to GitHub Pages
on:
push:
branches: ['main']
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: 'pages'
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
env:
VITE_USDA_FDC_API_KEY: ${{ secrets.VITE_USDA_FDC_API_KEY }}
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: './dist'
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4Add a repository secret named VITE_USDA_FDC_API_KEY (Settings β Secrets and variables β Actions). Note: any VITE_ variable is bundled into client-side code and is publicly visible.
- Go to your repository Settings
- Navigate to Pages
- Source: "GitHub Actions"
- Push to main branch to trigger deployment
# Create bucket
aws s3 mb s3://nutricompass-app --region us-east-1
# Enable static website hosting
aws s3 website s3://nutricompass-app --index-document index.html --error-document index.html
# Build and sync
npm run build
aws s3 sync dist/ s3://nutricompass-app --delete{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::nutricompass-app/*"
}
]
}- Create CloudFront distribution
- Origin: S3 bucket website endpoint
- Create custom error response: 404 β /index.html (200)
- Enable HTTPS with AWS Certificate Manager
- Push code to GitHub
- Go to DigitalOcean App Platform
- Create new app from GitHub
- Select your repository
- Configure:
- Type: Static Site
- Build Command:
npm run build - Output Directory:
dist
- Click "Deploy"
NutriCompass runs fully offline by default. Cloud sync is optional and requires Firebase env vars. USDA FoodData Central search is optional. For GitHub Pages (static hosting), you can set VITE_USDA_FDC_API_KEY at build time (this makes the key public). To keep the key private, use a server proxy with USDA_FDC_API_KEY and set VITE_USDA_FDC_PROXY_URL.
VITE_FIREBASE_API_KEY=your_api_key
VITE_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your_project_id
VITE_FIREBASE_STORAGE_BUCKET=your_project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
VITE_FIREBASE_APP_ID=your_app_id
VITE_FIREBASE_MEASUREMENT_ID=your_measurement_id
VITE_USDA_FDC_API_KEY=your_usda_api_key
VITE_USDA_FDC_PROXY_URL=You can copy from .env.example and fill in your project values.
Set this on the server that runs server.js (never in client-side VITE_ vars). GitHub Pages cannot run server.js, so only use this if you deploy a separate backend/proxy.
USDA_FDC_API_KEY=your_usda_api_keyFor local development, you can run server.js with that variable set and add
VITE_USDA_FDC_PROXY_URL=http://localhost:3000 to your .env so the Vite app can reach the proxy.
const apiKey = import.meta.env.VITE_FIREBASE_API_KEY;For production deployments, set these in your hosting platform's environment settings.
Cloud sync is optional and only activates when Firebase env vars are present. Local mode uses localStorage/IndexedDB and works fully offline. A βSync to cloudβ toggle appears only when Firebase is configured.
- Enable Authentication β providers: Email/Password + Google (optional).
- Enable Firestore (in production mode).
- Add your GitHub Pages domain:
YOUR_USERNAME.github.io - Add local dev:
localhost
users/{uid}/profile (doc)
users/{uid}/settings (doc)
users/{uid}/stacks/{stackId} (collection)
users/{uid}/logs/{date} (collection, docId = YYYY-MM-DD)
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{uid}/{document=**} {
allow read, write: if request.auth != null && request.auth.uid == uid;
}
}
}
- Firebase Auth redirects must include the GitHub Pages base path.
- Add
https://YOUR_USERNAME.github.io/nutrient-recommendation-app/to Authorized domains. - Firebase CLI/Firebase Hosting is not required when deploying to GitHub Pages.
Edit src/data/supplements.ts:
export const supplements: Supplement[] = [
// ... existing supplements
{
id: 'new-supplement',
name: 'New Supplement Name',
type: 'herb', // vitamin, mineral, herb, amino-acid, etc.
category: 'Adaptogen',
description: 'Description here...',
benefits: ['Benefit 1', 'Benefit 2'],
dosage: '500mg daily',
timing: 'Morning with food',
evidence: 'moderate',
goals: ['energy', 'stress'],
bodySystems: ['nervous', 'endocrine'],
// ... other fields
}
];Food-source data lives in src/data/supplements.ts:
nutrientFoodMappingstores NRV/AI reference values and sourcesnutrientFoodSourceslists foods, amounts, and % NRV/Reference
If you add a new nutrient with food data, also ensure the supplement ID maps to the nutrient ID in src/data/nutrientFoodSources.ts.
Edit src/utils/goalAnalyzer.ts to add new goal keywords and body system mappings.
- Global styles:
src/index.css - Tailwind config:
tailwind.config.js - Component-specific: Inline Tailwind classes
The app is designed to support future API integration:
// Example API service
const SupplementAPI = {
async getRecommendations(goals: string[], profile: UserProfile) {
const response = await fetch(`${API_URL}/recommendations`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
body: JSON.stringify({ goals, profile })
});
return response.json();
},
async trackProgress(supplementId: string, metrics: TrackingData) {
// Track user progress with a supplement
}
};We welcome contributions! Here's how:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run linting:
npm run lint - Run type checking:
npm run typecheck - Build to verify:
npm run build - Commit:
git commit -m 'Add amazing feature' - Push:
git push origin feature/amazing-feature - Open a Pull Request
- Follow existing code style
- Add TypeScript types for new data
- Ensure evidence ratings are accurate
- Include safety information for supplements
- Test on multiple browsers
- Add more supplements to database
- Improve goal analysis NLP
- Add more form guidance data
- Translations/internationalization
- Accessibility improvements
- Mobile app version
- Backend API development
- User tracking system
This project is licensed under the MIT License - see the LICENSE file for details.
- Nutritional data compiled from peer-reviewed research
- Food composition references: CIQUAL and EuroFIR (for vitamins/minerals)
- Ayurvedic knowledge from traditional texts and modern research
- Built with React, Vite, TypeScript, and Tailwind CSS
NutriCompass is for educational purposes only.
- This app does not provide medical advice
- Always consult a healthcare professional before starting supplements
- Individual results may vary
- Not intended to diagnose, treat, cure, or prevent any disease
- Check for drug interactions with your doctor or pharmacist
Made with π for better health education