Skip to content

vegify/vegify.app

Repository files navigation

vegify.app

A micronutrition tracker for plant-based cooking. Recipes nest (a recipe is an ingredient), and per-100g nutrients roll up through the graph, so you see the micronutrition of a dish, not just its calories. Recipes are user-generated and public by default; ownership gates editing, not reading.

Architecture

Two clients over one backend, rendering one shared set of screens: each client is a thin data/routing adapter, never a re-implementation.

  • apps/web: a stateless TanStack Start (React) SSR shell. Holds no database: it calls vegify-server over HTTP for all auth and content. Deploys as a scale-to-zero Lambda behind CloudFront with client assets on S3.
  • apps/desktop: a local-first Tauri 2 (Rust) app. Full offline CRUD against a local libSQL cache through the shared vegify-core DAL, syncing to the server when online. The local store is a cache; the server is the authority.
  • services/api: an Axum service that is the standing source of truth (libSQL on EBS). Owns authentication (self-hosted opaque sessions) and the content API.

vegify began as a framework bake-off (Next.js vs TanStack Start, plus two Rust SSR spikes). TanStack Start on Bun won the web slot; the retired shells live only in history. Full methodology and numbers: docs/benchmark.md.

Repo layout

Path What
apps/web TanStack Start SSR shell (Vite). Stateless; calls the backend over HTTP.
apps/desktop Tauri 2 desktop. Local-first; offline CRUD via vegify-core, syncs to the server.
services/api Axum backend, the source of truth. Auth + content API over libSQL.
crates/vegify-core Shared Rust DAL, consumed by both the desktop and the server.
packages/db Drizzle schema + seed (libSQL/SQLite). Schema stays portable to Postgres.
packages/ui Shared components and the one set of screens both clients render.
packages/tokens Design tokens → Tailwind v4 @theme CSS.
infra AWS CDK. AWS only: no Vercel, no Cloudflare.
docs/design Personas, site map (the app's IA), inline-edit contract, Figma import reference.

Quickstart

Prerequisites: Node 22 + pnpm, a Rust toolchain (for the desktop and server), and Bun (the web's production runtime).

pnpm install
pnpm --filter @vegify/tokens build   # design tokens → theme.css (run once / after token changes)
pnpm db:push                         # create .data/vegify.db from the Drizzle schema
pnpm db:seed                         # sample data (Biga + Neapolitan pizza dough)

Run the pieces:

cargo run -p vegify-server           # the backend (auth + content API)
pnpm dev                             # web (:47307) + desktop, against that backend

The web is stateless and reaches the backend at VEGIFY_API_URL (default http://localhost:8787). Build and serve it on Bun the way production does:

pnpm --filter web build:aws          # build + assemble the Lambda bundle
pnpm --filter web start:bun          # serve the build on Bun (PORT, VEGIFY_API_URL via env)

The desktop bakes its backend URL at build time from VEGIFY_API_URL; a runtime VEGIFY_AUTH_URL overrides it for local development.

Database

Local dev uses a SQLite file at .data/vegify.db; no daemon. Production is self-hosted libSQL (sqld); set DATABASE_URL (and DATABASE_AUTH_TOKEN if used), same client. The schema stays portable to Postgres if the project ever outgrows SQLite-class infra.

A recipe carries an as_ingredient_id row (name, creator, serving/batch amounts) so recipes can nest: the seed's pizza dough consumes its Biga. ingredient_nutrient holds the per-100g values that make micronutrition the core.

Deploy

Production ships only through CI, AWS-only via CDK: merging to main is what ships. The deploy workflow cuts a vX.Y.Z tag + GitHub Release in-job (patch per shipping merge; [skip release] in the PR title suppresses it; just release minor|major for bigger bumps), then runs the ordered cascade — server (path-gated, /health-gated) → web ∥ desktop. No release PRs, no bots merging anything; versions are git-tag-derived and no committed version field is authoritative. The tree carries no account-specific values and there are no env files: deploy decisions live in your account's SSM Parameter Store (just init <domains> records them; just config shows them), and everything else is derived (zone lookup, DNS-validated cert), wired cross-stack (backend + ingest origins), or generated in-account (the origin-verify secret). See docs/self-host.md for the full path.

GitHub-side config shrinks to one repository variableAWS_ACCOUNT_ID (the workflows construct the fixed-name OIDC role ARNs from it) — plus VEGIFY_APPLE_TEAM_ID (variable) and the VEGIFY_PROVISION_PROFILE_B64 secret only if you publish the desktop app.

CDK stacks: VegifyVpc, VegifyServer, VegifyWebStart, VegifyClientLogs, VegifyCi. With nothing configured at all, cdk synth still succeeds against inert placeholders.

Design

The living design is a private Figma file; binary archives stay out of the repo (.sketch/.fig/.psd are gitignored by policy). What's diffable lives here:

License

vegify.app is source-available, not open source. It is released under the PolyForm Noncommercial License 1.0.0: use, modify, and share it freely for any noncommercial purpose; commercial use is reserved to the copyright holder. See CONTRIBUTING.md for how contributions are licensed back to the project.

About

Micronutrition tracking + recipe sharing for plant-based cooking. Rust/Axum API, TanStack Start web, Tauri desktop + iOS sharing one screen set. Source-available (PolyForm NC).

Topics

Resources

License

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors