Skip to main content

ADR 002: Frontend Tech Stack

Date: 2025-08-15

Status: Proposed

Decision Makers: @cathrinTruchan @kaischwetz @cr0ssing

Context

In order to set up the data management portal frontend, we need to evaluate which libraries we need to use to build a maintainable and scalable architecture. The focus is to use libraries that are well-maintained, performant, lightweight, supported by Next.js and a native-first approach (if React provides a feature for core area like state management, we stick to the native API). The component library decision is outsourced in a separate ADR.

Checked Architecture Principles

  • Model-centric data flow: Not applicable
  • Distributed architecture with unified user experience: None - no explicit distributed architecture
  • Modular design: Full - feature-driven and component-driven architecture promote strong modularity
  • Integration capability through defined interfaces: Full - axios as API client provides integration capability
  • Open source as the default: Full - all libraries and tools are open source
  • Cloud-native architecture: Full - all libraries and Next.js as framework are able to run in a cloud-native environment
  • Prefer standard solutions over custom development: Full - focus on well-known, maintained libraries and React / Next.js native APIs
  • Self-contained deployment: Full - Next.js can provide self-contained deployment with independent bundling of its consumed libraries (standalone deployment support)
  • Technological consistency to ensure maintainability: Full - stack is coherent around React ecosystem and popular complementary tools
  • Multi-tenancy: Full - the software can be developed with multi-tenancy support with the stated libraries as base
  • Security by design: Partial - Auth.js provides strong auth/security features; other security concerns depend on implementation, React as such is also secure by design

Decision

Build the architecture with the chosen libraries and design pattern.

State management

Internationalization

Routing & File structure

  • classic file and folder-based routing provided by Next.js natively with App Router
  • feature-driven architecture and component-driven architecture (design pattern)
    • using feature-driven architecture for full features while using component-driven architecture for the UX layer with shadcn to provide shared components

API client

Authentication

Testing

Form Handling

General Tooling

  • Code style with Prettier
  • Runtime validation with zod
    • Validates data based on a schema to ensure data integrity

Consequences

Replacing the chosen libraries would lead to considerable effort when it comes to migrating from one solution to another. Some libraries like Vitest can be drop-in replaced with Jest since the API is mostly the same but that's not the case for the majority.

Alternatives

If a library is no longer available, we could migrate to the following alternatives for the core areas:

Internationalization

Some popular alternatives are Lingui, react-intl by FormatJS and react-intl-universal.

API client

The native fetch API which all browsers have built-in is the best alternative here.

Authentication

better-auth is a good alternative for Auth.js It does offer stateless JWT authentication as well as support for Keycloak SSO.

Testing

The best E2E alternative is Cypress. It also offers great developer experience, real-time debugging, automatic waits etc. For unit testing is Jest the second best fit. Since Vitest adapted the API from Jest, it is a drop-in replacement library.

Form Handling

Formik is popular and intuitive, has extensive docs, supports controlled/uncontrolled inputs and offers schema validation via Yup.

General Tooling

Yup is an alternative for Zod when it comes to schema validation. It also offers a chainable API, popular in React forms (Formik), sync/async validation, custom error messages, internationalization. For code style, ESLint can be used beside its functionality as linter but also BiomeJS which is an alternative for ESLint and Prettier and stands out for its fast linting.

See also