Technical overview

Under the Hood

GardenLog is a full-stack application built and operated as a personal project. This page explains the architecture, technical choices, integrations, and the systems that support the public app.

How it's built, end to end

“The main systems behind the application, each with a focused responsibility.

Frontend

React 19 + Vite

Single-page app with drag-and-drop kanban (@dnd-kit), i18next localisation in English and German, and 25 vanilla CSS files — no CSS framework.

Backend

Node.js + Express 5

REST API with JWT auth, Joi request validation, a node-cron reminder scheduler, and a background worker that delivers events to PlantDB.

Database

PostgreSQL via Neon

Serverless Postgres. 26 tables covering users, plants, logs, zones, reminders, propagation, planner events, preferences, and the PlantDB outbox. Idempotent CREATE TABLE IF NOT EXISTS scripts — no migration framework.

Auth & validation

JWT + Joi

JWT session tokens are set in HTTP-only cookies. Passwords are securely hashed before storage. Every request body is validated with Joi before it reaches the database.

Images

Cloudinary

Uploaded photos are compressed client-side, stored in Cloudinary, and served from its CDN.

Reminders

node-cron + web-push

A scheduler checks for due reminders every minute and sends push notifications via web-push (VAPID). A service worker lets you complete a reminder straight from the notification.

PWA

Installable, offline-aware

GardenLog can be installed on supported mobile and desktop browsers. Its service worker supports push notifications and selected cached application resources.

PlantDB

Optional community sync

GardenLog can send anonymised observations to PlantDB, a separate community database, using a reliable delivery pattern — explained below.

Hosting

Railway + GitHub

Railway runs both the frontend and backend and deploys straight from the repository. Railway hosts the deployed application, with the source and deployment workflow managed through Github. Railway manages staging environments, and runs scheduled database backups.

Privacy

Minimal by default

Account, preference and gardening data needed to provide the features users enable. See the full breakdown below.

How PlantDB delivery works

A transactional outbox pattern, so a slow or temporarily unreachable PlantDB does not block the GardenLog request and queued events can be retried. So a temporary delivery failure does not discard the queued event.

When you opt in, creating or updating a plant or a log does two things within the same database transaction: it saves your record, and — if the plant has enough information and you haven't opted out for that plant — it queues an anonymised copy in an outbox table. A background worker polls that queue on a short interval and posts new events to the PlantDB API. If PlantDB is temporarily unreachable, nothing is lost: the event stays queued and is retried automatically on a later pass, up to a limited number of attempts. Your user identity is never part of the payload.

Browser

React PWA

GardenLog API

Express, JWT auth

Database

PostgreSQL (Neon)

Outbox queue

Written with the same transaction

Background worker

Polls and delivers asynchronously

PlantDB API

No user identity included

  • Eligible events are queued alongside the write that created them, so nothing is lost if delivery fails.
  • Delivery happens asynchronously — a background worker polls the queue and posts new events to the PlantDB API.
  • Failed deliveries are retried automatically, up to a limited number of attempts, before being marked as failed.
  • Your user identity is deliberately left out of every payload. Your GardenLog user ID and account details are deliberately excluded from every PlantDB payload.

Minimal by default

GardenLog stores a username, an email address, a securely hashed password, and the garden data you create — plants, zones, logs, reminders, propagation records, and preferences. There's no advertising, no selling of user data, no cross-site tracking.GardenLog does not use advertising or cross-site tracking and does not intentionally collect behavioural analytics beyond operational logging. PlantDB sharing is opt-in and excludes your user identity. See the privacy summary on the homepage.

Curious to see it running?

GardenLog is free, ad-free, and available as a web app on mobile and desktop.