Back to Explore

DisplacedForest/ferment

TypeScript1 contributorsMIT
View on GitHub

Summary

Ferment is a self-hosted, Docker-deployable fermentation tracking app for home winemakers, brewers, and mead makers. It logs gravity readings from smart hydrometers (Tilt, iSpindel), manages multi-phase fermentation protocols with configurable completion criteria, and integrates with Home Assistant via MQTT and webhooks. It's a Next.js 15 app with SQLite backend, not a SaaS — you run it on your own hardware.

Great for

home fermenters or IoT hobbyists who want to self-host a fermentation logger with smart hydrometer integration and Home Assistant automation — or TypeScript/Next.js developers looking for a real-world full-stack project with hardware device integration

Easy wins

  • +Add unit tests for the phase-engine.ts and alert-detection.ts logic — these are pure functions with no UI dependency and currently have zero test coverage
  • +The queries.ts getBatches() builds raw SQL IN clauses manually with sql.join() instead of using Drizzle's inArray() operator — refactor to use the proper ORM abstraction and reduce the duplicated pattern across ~6 queries
  • +Add a screenshot/demo GIF to the README (currently just a commented-out placeholder) — would significantly increase project visibility
  • +The HydrometerManager component fires un-awaited fetch calls in handleToggleActive and handleDelete with no error handling — add try/catch and user feedback

Red flags

  • !Zero tests across the entire codebase — the phase engine, alert detection, and reading bucketing logic are non-trivial and completely untested
  • !Single commit history (commit_count: 1) suggests this was pushed as a bulk initial commit — no incremental development history to review contributor intent or design evolution
  • !API authentication is opt-in (FERMENT_API_KEY unset = open API by default) — documented, but a risky default for a self-hosted tool that might be port-forwarded
  • !No rate limiting mentioned or visible in the API routes, which matters for the hydrometer ingest endpoint that could receive high-frequency POSTs

Code quality

decent

The architecture is well-thought-out: clean separation between db/schema, lib/business logic, and components. The phase engine and reference-data modules are solid TypeScript with real domain modeling. However, queries.ts has a recurring pattern of manual SQL IN-clause construction (sql.join(batchIds.map(...))) that bypasses Drizzle's inArray() helper — this is fragile and inconsistent with ORM usage elsewhere. Error handling in settings components is thin: handleToggleActive and handleDelete in HydrometerManager do bare awaited fetches with no .catch() or user-facing error states. The StepProtocol wizard component is very long (~500+ lines) and manages significant drag-and-drop state that could be extracted.

What makes it unique

There are existing open-source fermentation trackers (Fermentrack, Brewfather's self-hosted alternatives, BrewPi), but Ferment's specific combination of Next.js App Router architecture, Drizzle+SQLite simplicity, and Home Assistant MQTT auto-discovery as a first-class feature is reasonably differentiated. It's not reinventing the wheel, but it's a cleaner, more modern tech stack than most incumbents and targets a slightly different self-hosting audience (Docker one-liner vs. Raspberry Pi image flashers).

Scores

Collab
5
Activity
2

Barrier to entry

medium

The project has a CONTRIBUTING.md, CI, Dockerfile, and clean folder structure, but zero tests, a single 1-commit history, no labeled issues, no good-first-issue tags, and no community — a contributor would need to self-direct entirely.

Skills needed

TypeScript (React + Next.js App Router)Drizzle ORM and SQLiteREST API design (Next.js Route Handlers)Tailwind CSS / shadcn/ui for UI contributionsDocker for deployment/testingBasic fermentation knowledge helpful but not required