Skip to content

Latest commit

Β 

History

411 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Logo

Vite React TypeScript License

This is the frontend half of LiteStack β€” the backend half is LiteEnd-Go, and the whole stack comes up from the meta-repo (see its README). It also runs on its own β€” see "Standalone use" below.

A modern, scalable, and developer-friendly frontend boilerplate powered by Vite, React 19, GraphQL, and TypeScript. Built with the Feature-Sliced Design methodology and pre-configured OIDC Authentication.

Overview

LiteFront is a lightweight and performant frontend boilerplate designed for building fast, efficient, and well-structured web applications. It integrates a modern toolchain to provide an exceptional developer experience (DX) right out of the box.

  • πŸš€ Performance: Fast development server and optimized builds thanks to Vite.
  • πŸ”’ Security: Enterprise-grade authentication via OpenID Connect (OIDC).
  • 🧩 Scalability: Feature-Sliced Design ensures your project stays organized and maintainable as it grows.
  • βœ… Reliability: Type-safety with TypeScript, code quality enforced by Biome, and pre-commit checks with Lefthook.
  • πŸ§ͺ Test-Ready: Unit testing with Vitest and End-to-End testing with Playwright are pre-configured.

Tech Stack

Category Technology
Core Vite, React 19, TypeScript
SSR / Routing TanStack Start + TanStack Router (SSR, type-safe)
Authentication react-oidc-context (OAuth 2.0 / OIDC)
Data Fetching GraphQL with URQL Client
State Management Zustand
Styling Tailwind CSS v4 + SCSS Modules
UI Components daisyUI (for Tailwind CSS)
Internationalization Paraglide JS (Type-safe)
Code Generation GraphQL Code Generator
Linting/Formatting Biome, Stylelint, Knip, Steiger
Git Hooks Lefthook
Testing Vitest (Unit), Playwright (E2E)
Component Dev Ladle (Storybook alternative)
Performance / DX React Scan (Performance debugging)
Deployment Docker β€” Node SSR server (Nitro node-server)

Architecture

This boilerplate uses Feature-Sliced Design (FSD), a methodology for structuring frontend applications. It helps to keep the codebase clean, scalable, and easy to navigate by organizing code into layers (shared, entities, features, widgets, pages, app).

Three directories under src/ sit outside the layers on purpose β€” generated/ (codegen output), graphql/ (its query documents) and routes/ (file-based routing); the seven files in src/ itself are entry points.

Key Features

  • Secure Authentication: Fully integrated OIDC/OAuth 2.0 flow with PKCE, automatic token renewal, and AuthGuard for protected routes.
  • Protected Routes Example: Includes a demo /account route that requires authentication and displays user profile data.
  • 🌍 Type-Safe I18n: Built-in internationalization powered by Paraglide JS, offering full type safety, tree-shaking, and small bundle size.
  • Automated Type Generation: npm run gen generates TypeScript types from your GraphQL schema.
  • Runtime Configuration: The public VITE_* values are read from the environment when the server boots (src/shared/config/env.ts), so one built image runs in any environment. A missing required variable stops the server at startup with the variable's name, instead of breaking a page later.
  • Server-Side Rendering: Public pages are server-rendered via TanStack Start (Nitro node-server) for fast first paint and SEO; auth-only routes opt out with ssr: false.
  • Production-Optimized: Multi-stage Dockerfile producing a small, self-contained Node SSR image (.output).
  • Image Optimization: Automatic image optimization at build time with vite-plugin-image-optimizer.
  • Dead Code & Dependency Analysis: Keeps the codebase clean with Knip by detecting unused files, exports, and dependencies.
  • Architectural Linting: Strict FSD boundaries enforced by Steiger.
  • Performance Debugging: Built-in React Scan for debugging performance and unexpected renders in development mode.
  • PWA Ready: Pre-configured Vite PWA plugin for transforming the app into a Progressive Web App.

Configuration

The application requires the following environment variables for the OIDC authentication to work correctly. Set them however you like β€” a .env file is one way, exported variables are another; the server reads them from its environment when it boots.

Variable Description Example
VITE_OIDC_AUTHORITY The URL of your OIDC provider (Logto, Auth0, Keycloak, etc.) https://your-app.logto.app/oidc
VITE_OIDC_CLIENT_ID The Client ID of your application registered in the provider abc123xyz...
VITE_OIDC_REDIRECT_URI The callback URL where the user is redirected after login http://localhost:3000/callback
VITE_OIDC_SCOPE The scopes to request openid profile offline_access
VITE_OIDC_API_RESOURCE API resource indicator. Sent on both the authorize and token requests so the access token is a JWT whose aud equals the backend's OIDC_AUDIENCE http://localhost:4000
VITE_GRAPHQL_API_URL URL of your GraphQL API http://localhost:4000/graphql
VITE_BASE_URL Base URL of the application (E2E base URL, and used to build OIDC redirect targets β€” an empty value breaks sign-out) http://localhost:3000
VITE_MOCK_AUTH Build-time. Bypasses real OIDC entirely (dev/E2E only β€” never ship it enabled) false
VITE_APP_VERSION Version string surfaced in the UI and Sentry releases build metadata
PORT The port the application will run on 3000
VITE_SENTRY_DSN Runtime. The DSN key for Sentry error tracking https://xxx@yyy.ingest.sentry.io/zzz
VITE_SENTRY_ORG Build-time. Sentry organization slug (source maps) your-org
VITE_SENTRY_PROJECT Build-time. Sentry project name (source maps) your-project
VITE_SENTRY_AUTH_TOKEN Build-time. Token for uploading source maps sntrys_...

Logto Provider Setup

The env vars only tell the app where the provider is β€” register the app in the Logto Console too:

  1. Create a Single Page App (Applications β†’ Create). PKCE-based, no client secret. Copy its App ID into VITE_OIDC_CLIENT_ID.
  2. Redirect URIs (app settings): sign-in http://localhost:3000/callback (= VITE_OIDC_REDIRECT_URI), post sign-out http://localhost:3000. Add production URLs when you deploy.
  3. Register an API Resource (Console β†’ API Resources β†’ Create). Set its API Identifier to exactly VITE_OIDC_API_RESOURCE (e.g. http://localhost:4000, no trailing slash), then enable the resource's Default API toggle. Without a resource-bound token Logto issues an opaque token the backend can't verify β†’ 401 Unauthorized.

Three values must match exactly: VITE_OIDC_API_RESOURCE (frontend) == OIDC_AUDIENCE (backend) == the API Identifier in Logto.

VITE_OIDC_AUTHORITY is the OIDC endpoint β€” the Logto base URL plus /oidc (e.g. https://auth.example.com/oidc). The frontend sends the resource on both the authorize and token requests (see src/features/auth/api/oidc-client.ts); sending it only on authorize yields an opaque token.

Custom Authentication

This boilerplate uses a facade pattern for authentication located in src/features/auth. This architecture decouples the application from the specific OIDC library, allowing you to replace it with any other method (e.g., custom JWT/Session based auth) easily.

To replace OIDC with your own logic:

  1. Open src/features/auth/index.ts.
  2. Remove react-oidc-context exports.
  3. Implement and export your own AuthProvider component and useAuth hook from this file.
  4. Update src/app/bootstrap/AppProviders.tsx (the isomorphic auth + GraphQL Wrap) to mount your provider and drop the getOidcConfig() injection if your new provider doesn't need it.

Scripts Overview

  • npm run start:dev: Starts the development server with Hot Module Replacement.
  • npm run build: Bundles the application for production.
  • npm run test:prod: Runs the unit/component tests once (Vitest). End-to-end tests are npm run test:e2e:prod; npm run test:all runs both.
  • npm run check: Runs all code quality checks in parallel: tsc, biome (in write mode β€” it fixes rather than fails), stylelint, knip, steiger, and the component trio check. This is the gate β€” never substitute lint + ts:check.
  • npm run verify:commit / verify:push: exactly what the git hooks run.
  • npm run lint:fsd: Manually runs FSD layer boundary checks with Steiger.
  • npm run storybook:serve: Starts the component playground (Ladle) for developing UI components.
  • npm run storybook:build: Builds the static storybook for deployment.
  • npm run gen: Generates TypeScript types for GraphQL operations.

Get Started

Inside LiteStack, scripts/setup.sh at the meta root does all of this. On its own β€” everything in Docker, nothing to install but Docker:

cp -n .env.example .env && docker compose up -d

From source:

  1. Install dependencies

    npm install
  2. Setup environment variables

    cp .env.example .env

    Important: Open .env and fill in your OIDC provider details (VITE_OIDC_AUTHORITY, VITE_OIDC_CLIENT_ID, etc.) or the app will not be able to authenticate users.

  3. GraphQL types are already generated and committed in src/generated/ β€” run npm run gen only after the backend schema changes.

  4. Run the development server

    npm run start:dev

Your app should now be running on the port specified in your .env file (default: http://localhost:3000).

Types Generation

Run npm run gen after every change to the GraphQL API Schema or after modifying any *.graphql files in the src/graphql directory. This command is crucial for maintaining type safety between your frontend and backend.

Testing

This boilerplate includes a complete testing infrastructure for both unit and end-to-end testing.

  • Unit/Component Tests: Written with Vitest and Testing Library for testing React components and Zustand stores.
  • E2E Tests: Run on Playwright with pre-configured Mock Auth β€” allows stable test runs without requiring a real OIDC provider.

Unit Tests

npm run test:prod

E2E Tests

# Run in headless mode
npm run test:e2e:prod

# Run with UI
npm run test:e2e:dev

Coverage

npm run test:cov

Error Monitoring

This application uses Sentry for production error tracking and performance monitoring. The integration includes automatic source map uploading during the build process via @sentry/vite-plugin.

To enable Sentry, configure the following environment variables:

VITE_SENTRY_DSN=your-sentry-dsn
VITE_SENTRY_ORG=your-sentry-org
VITE_SENTRY_PROJECT=your-sentry-project
VITE_SENTRY_AUTH_TOKEN=your-auth-token # Required only at build time

(Note: VITE_SENTRY_AUTH_TOKEN is a secret β€” set it in the build environment, never commit it.)

Standalone use

Outside LiteStack this repo stands alone. Inside it does not β€” frontend/ is a submodule pinned to a commit, so start from the meta-repo.

npx degit uxname/litefront my-app && cd my-app && npm install && cp .env.example .env && npm run start:dev

License

LiteFront is licensed under the MIT License.

Contributing

Contributions are welcome! Please feel free to open an issue or submit a pull request with your changes.

About

A Vite + GraphQL + Typescript frontend boilerplate using Feature-Sliced Design as project architecture methodology

Topics

Resources

Stars

27 stars

Watchers

2 watching

Forks

Used by

Contributors

Languages