SkillAgentSearch skills...

Norish

Norish - A realtime, self-hosted recipe app for families & friends

Install / Use

/learn @norish-recipes/Norish
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<p align="center"> <img src="./.github/assets/mockup-norish.png" width="100%" alt="Norish mockup" /> </p> <p align="center"> <a href="https://github.com/norish-recipes/Norish/blob/main/LICENSE"><img src="https://img.shields.io/github/license/norish-recipes/Norish?style=for-the-badge" alt="License" /></a> <a href="https://github.com/norish-recipes/Norish/actions"><img src="https://img.shields.io/github/actions/workflow/status/norish-recipes/Norish/release-build.yml?style=for-the-badge&logo=github" alt="Build Status" /></a> <a href="https://hub.docker.com/r/norishapp/norish"><img src="https://img.shields.io/docker/pulls/norishapp/norish?style=for-the-badge&logo=docker" alt="Docker Pulls" /></a> <a href="https://hub.docker.com/r/norishapp/norish"><img src="https://img.shields.io/docker/image-size/norishapp/norish?style=for-the-badge&logo=docker" alt="Docker Image Size" /></a> <a href="https://buymeacoffee.com/mikevanes"><img src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black" alt="Buy Me a Coffee" /></a> </p>

Norish

Norish is a real-time, household-first recipe app for planning meals, sharing groceries, and cooking together.

Table of Contents


Vision

The vision for Norish is a shared recipe app built for friends, families, and households that want to share a recipe catalogue.

The name comes from Nora (our dog) + dish. Coincidentally, it also sounds like "nourish".


Why Norish

Norish started because we wanted a cooking app that felt intuitive and easy to use. The existing apps we tested sadly did not meet our requirements in ease of use and aestethics.

Norish is intentionally minimal. It focuses on practical day-to-day use.


Core Features

  • Easy recipe import from URL, with AI fallback if configured.
  • Video recipe import from YouTube Shorts, Instagram Reels, TikTok, and more (requires AI provider).
  • Image recipe import from screenshots/photos of recipes (requires AI provider).
  • Nutritional information generation (requires AI provider).
  • Allergy detection and warnings for recipe ingredients (detection requires AI provider).
  • Unit conversion metric <-> US (requires AI provider).
  • Recurring groceries via NLP or manual setup.
  • Real-time sync of recipes, groceries, and meal planning data.
  • Households with shared groceries and planning.
  • CalDAV sync for calendar integration.
  • Mobile-first design with light/dark mode support.
  • Authentication options: OIDC, OAuth providers, and first-time password auth fallback.
  • Admin settings UI for runtime configuration.
  • Permission policies for recipe visibility/edit/delete scopes.
  • Internationalization (i18n) currently supporting EN, NL, DE, FR, ES, RU, KO, PL, and DA

Note: AI feature speed can vary by provider, model, and region.


Deploying

Minimal Docker Compose

For a full template, see docker-compose.example.yml.

services:
  norish:
    image: norishapp/norish:latest
    container_name: norish-app
    restart: always
    ports:
      - "3000:3000"
    user: "1000:1000"
    volumes:
      - norish_data:/app/uploads
    environment:
      AUTH_URL: http://norish.example.com
      DATABASE_URL: postgres://postgres:norish@db:5432/norish
      MASTER_KEY: <32-byte-base64-key> # openssl rand -base64 32
      CHROME_WS_ENDPOINT: ws://chrome-headless:3000
      REDIS_URL: redis://redis:6379
      UPLOADS_DIR: /app/uploads

      # Optional
      # NEXT_PUBLIC_LOG_LEVEL: info
      # TRUSTED_ORIGINS: http://192.168.1.100:3000,https://norish.example.com
      # YT_DLP_BIN_DIR: /app/bin

      # First-user auth setup (choose one)
      # OIDC_NAME: NoraId
      # OIDC_ISSUER: https://auth.example.com
      # OIDC_CLIENT_ID: <client-id>
      # OIDC_CLIENT_SECRET: <client-secret>
      # OIDC_WELLKNOWN: https://auth.example.com/.well-known/openid-configuration
      # GITHUB_CLIENT_ID: <github-client-id>
      # GITHUB_CLIENT_SECRET: <github-client-secret>
      # GOOGLE_CLIENT_ID: <google-client-id>
      # GOOGLE_CLIENT_SECRET: <google-client-secret>
    healthcheck:
      test:
        [
          "CMD-SHELL",
          'node -e "require(''http'').get(''http://localhost:3000/api/health'', r => process.exit(r.statusCode===200?0:1))"',
        ]
      interval: 1m
      timeout: 15s
      retries: 3
      start_period: 1m
    depends_on:
      - db
      - redis

  db:
    image: postgres:17-alpine
    container_name: norish-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: norish
      POSTGRES_DB: norish
    volumes:
      - db_data:/var/lib/postgresql/data

  chrome-headless:
    image: zenika/alpine-chrome:latest
    container_name: chrome-headless
    restart: unless-stopped
    command:
      - "--no-sandbox"
      - "--disable-gpu"
      - "--disable-dev-shm-usage"
      - "--remote-debugging-address=0.0.0.0"
      - "--remote-debugging-port=3000"
      - "--headless"

  redis:
    image: redis:8.4.0
    container_name: norish-redis
    restart: unless-stopped
    volumes:
      - redis_data:/data

volumes:
  db_data:
  norish_data:
  redis_data:

First-User Setup

The first user to sign in becomes server owner + server admin. After first sign-in:

  • User registration is disabled automatically.
  • Ongoing server settings are managed in Settings -> Admin.

Admin Settings

Server owners/admins can manage:

  • Registration policy.
  • Permission policies for recipe view/edit/delete.
  • Auth providers (OIDC, GitHub, Google).
  • OIDC claim mapping for admin role assignment + household auto-join.
  • Content detection settings (units, content indicators, recurrence config).
  • AI + video processing settings.
  • System scheduler and server restart actions.

Environment Variables

env-config-server.ts is the source of truth for runtime env vars.

Required by schema

| Variable | Description | Example | | -------------- | ------------------------------------------- | ------------------------------------- | | DATABASE_URL | PostgreSQL connection string | postgres://user:pass@db:5432/norish | | MASTER_KEY | 32+ character key for encryption derivation | openssl rand -base64 32 |

Optional: compose DATABASE_URL from parts

By default, set DATABASE_URL directly.

If DATABASE_URL is not set, Norish composes it from optional component vars. Use this only if you intentionally prefer split variables over a single URL.

For local development, the default setup is still a direct URL in .env.local, typically: DATABASE_URL=postgres://postgres:norish@localhost:5432/norish

When no component vars are set, the fallback URL is: postgresql://postgres:norish@localhost:5432/norish

| Variable | Description | Default | | ------------------- | ----------------- | ----------- | | DATABASE_HOST | PostgreSQL host | localhost | | DATABASE_PORT | PostgreSQL port | 5432 | | DATABASE | Database name | norish | | DATABASE_USER | Database username | postgres | | DATABASE_PASSWORD | Database password | norish |

Commonly set in production

| Variable | Description | Typical value | | -------------------- | ---------------------------------------------- | ---------------------------- | | AUTH_URL | Public URL used for callbacks and links | https://norish.example.com | | CHROME_WS_ENDPOINT | Playwright CDP WebSocket endpoint for scraping | ws://chrome-headless:3000 | | REDIS_URL | Redis connection URL for events and jobs | redis://redis:6379 |

Optional general Runtime

| Variable | Description | Default | | --------------------- | ------------------------------------------ | ------------------------------------------------- | | NODE_ENV | Runtime environment | development | | HOST | Server bind address | 0.0.0.0 | | PORT | Server port | 3000 | | AUTH_URL

View on GitHub
GitHub Stars886
CategoryDevelopment
Updated2h ago
Forks64

Languages

TypeScript

Security Score

100/100

Audited on Mar 28, 2026

No findings