Skip to content
LumeCare project logo

LumeCare

Full-Stack EngineeringDevelune product · in build

In-house product — designed and built by Develune

Visit Live Site

Overview

LumeCare is a skincare brand built on a single premise: publish the numbers. Most brands name an active ingredient without saying how much of it is in the bottle. LumeCare prints the strength of every active and the full INCI on the product page. It is a Develune-owned product, not a client engagement — we designed the brand, the storefront and the API, and we are still building it.

The codebase is a pnpm monorepo: a Next.js App Router storefront and a NestJS REST API, with a shared package holding the types, enums and brand tokens both import — so a change to a product's shape or a brand colour cannot drift between the two. Prisma against MySQL is the single source of truth for the schema.

The Challenge

Ingredient transparency is easy to claim and hard to publish. Saying a serum 'contains niacinamide' costs nothing; printing the exact strength invites comparison and forecloses reformulating quietly. Building a storefront around that promise means the product data model has to treat the ingredient list as first-class published content rather than marketing copy — which is the opposite of how most e-commerce platforms model a product.

The Solution

We modelled formulas, actives and their strengths as structured data in Prisma rather than as free text in a description field, so every product page renders its numbers from the same source and cannot disagree with itself. The storefront is Next.js App Router; the API is a separate NestJS service so the catalogue is not welded to the presentation layer. Both apps and the database ship as containers deployed with Kamal.

Key Contributions

Ingredient Transparency as a Data Model

Formulas, actives and strengths are structured records, not prose. The product page, the comparison copy and the ingredient breakdown all render from the same rows, so the promise the brand makes is enforced by the schema rather than by whoever writes the copy.

Shared-Contract Monorepo

A shared workspace package holds the types, enums and brand tokens imported by both the storefront and the API, so the two cannot drift — a field renamed in one place fails the type-check in the other.

Brand and Storefront Design

The brand system, the logo, and the storefront design are Develune's own work — built to carry a page that leads with published percentages without reading like a spec sheet.

Tech Stack

Storefront

Next.js App RouterReactTypeScriptTailwind CSS

API & data

NestJSPrismaMySQL

Monorepo

pnpm workspacesShared types & brand tokens package

Infrastructure

DockerKamalLet's Encrypt

Challenges

1

Modelling ingredient strength as structured, publishable data instead of description copy, so a product page cannot claim one number and the label another

2

Keeping a Next.js storefront and a NestJS API in agreement without duplicating types — solved with a shared workspace package both import

3

Designing a brand system that reads as luxury while the page is dense with numbers, which is not what luxury skincare pages usually look like

Key Takeaways

  • Putting a brand promise in the schema, not the copy deck, is what stops it eroding as content gets edited
  • A shared types package between a Next.js front end and a separate API service costs little and removes an entire class of integration bug
  • Building our own product keeps us honest about the trade-offs we recommend to clients