Skip to content

ADR-0013: Learning platform frontend stack (Next.js 15 + shadcn/ui)

Guide

ADR-0013: Learning platform frontend stack (Next.js 15 + shadcn/ui)

  • Status: Accepted · Date: 2026-05-31 · Approved by: Kevin Wong (CPTO)
  • Signed by: Engineering Director
  • Related: ADR-0006 (intranet static portal, not superseded), ADR-0008 (Vercel deploy pattern)

Context

IDEA-0001 “Show the Work” specifies a retrieval-first learning platform — a surface distinct from the intranet (intranet/) where learners query scored chunk content, complete modules, and track progress. The intranet (ADR-0006, ADR-0008) is a static Astro portal for the Principal’s personal workspace and is not a suitable host for interactive, authenticated learner sessions.

Two questions were faced:

  1. Where does the platform live? The intranet directory and stack (Astro 6, static) are optimised for a read-only, single-user dashboard. Learner interactions — authentication, retrieval queries, progress persistence, real-time feedback — require a dynamic rendering model. Forcing these onto the static Astro surface would require significant non-idiomatic workarounds.

  2. What frontend stack? The default stack (CLAUDE.md) calls for Next.js 15 (App Router) + React 19 + Tailwind CSS v4 as the web application layer. shadcn/ui (new-york style) is the component system aligned with that stack. Astro-compatible component libraries exist but shadcn/ui is explicitly built for React and relies on Radix UI primitives that require a React runtime — it is not appropriate for the static Astro intranet.

The CPTO reviewed these constraints and made the stack selection. This ADR records that decision.

Decision

Build the learning platform as a Next.js 15 (App Router) + React 19 application under a new top-level directory platform/, styled with Tailwind CSS v4 and componentised with shadcn/ui (new-york style). Deploy to Vercel, following the established pattern from ADR-0008.

This creates two parallel product surfaces in the repository:

Surface Directory Stack Purpose
Intranet intranet/ Astro 6 + Tailwind v4 Principal’s personal workspace portal
Learning platform platform/ Next.js 15 + React 19 + Tailwind v4 + shadcn/ui IDEA-0001 learner surface

ADR-0006 is not superseded. The intranet remains the correct tool for a static, single-user, repo-driven dashboard. The two surfaces serve different audiences and interaction models and are expected to coexist indefinitely.

Rationale for Next.js 15 / App Router: server components reduce client-side JavaScript for content-heavy chunk pages; streaming and suspense boundaries suit retrieval-first UX where chunk results arrive asynchronously; the route handler pattern fits future API endpoints for the chunk ingestion pipeline and rubric scoring.

Rationale for shadcn/ui (new-york style): components are copied into the repo (not a runtime dependency), which aligns with the project’s preference for explicit, auditable code over opaque packages; the new-york style’s tighter visual density fits a learning interface where density and scannability matter; Radix UI accessibility primitives are production-proven for interactive components (modals, comboboxes, tabs).

Consequences

  • platform/ becomes a new deployable root alongside intranet/. Vercel configuration for platform/ follows the pattern from ADR-0008: GitHub- connected, Root Directory = platform/, framework detection = Next.js, npm run build.
  • shadcn/ui components are initialized via npx shadcn@latest init and added individually as needed; they live in platform/src/components/ui/.
  • Deferred — auth: learner authentication (sign-in, session, role-based access) is not decided here. When warranted, revisit with a dedicated ADR; leading candidates are Clerk and NextAuth as noted in the default stack.
  • Deferred — database: chunk storage and learner progress persistence are not decided here. ADR-0006 nominated Supabase as a future candidate; the retrieval-first platform will need a vector-capable store. Record the choice in a new ADR when the first retrieval route is built.
  • Deferred — first route: the initial page structure and routing conventions for platform/ are an Engineering task, not an architectural decision, and are not specified here.
  • The intranet (intranet/) is unaffected. No Astro configuration, no intranet/package.json, and no intranet route changes result from this decision.
  • If shadcn/ui’s new-york default colour tokens conflict with KLMS brand decisions made later, update platform/src/app/globals.css; the component copies in ui/ are already in-tree and can be adjusted freely.