Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dmaman86/shiftly/llms.txt

Use this file to discover all available pages before exploring further.

Shiftly is a React + TypeScript single-page application built with Vite. It is deployed to GitHub Pages under the /shiftly/ base path, which means the local dev server mirrors that sub-path at http://localhost:5173/shiftly. This guide walks you through every step needed to get a fully working local environment — from prerequisites to a running dev server.

Prerequisites

Before cloning the repository, make sure you have the following tools installed:
  • Node.js 18+ — required by the Vite toolchain and all dependencies.
  • Bun (recommended) — used in the predeploy and CI scripts. Install from bun.sh.
  • Git — to clone the repository.
Bun is the preferred package manager for this project. All predeploy and CI pipeline steps are written with bun run commands. You can still use npm for day-to-day development if Bun is not available.

Getting Started

1

Clone the repository

Clone the project from GitHub and enter the project directory:
git clone https://github.com/dmaman86/shiftly.git && cd shiftly
2

Install dependencies

Install all project dependencies. Bun is recommended for speed and consistency with the CI environment.
bun install
3

Start the development server

Launch the Vite development server with hot-module replacement enabled:
bun run dev
4

Open the app in your browser

Navigate to the app. Because the base URL is /shiftly/, the root path automatically redirects to the default route:
http://localhost:5173/shiftly
The app will redirect you to http://localhost:5173/shiftly/he/daily on first load.
The app uses language-based routing. The default language is Hebrew (RTL layout) at /he/daily. To switch to English (LTR), navigate to /en/daily:
http://localhost:5173/shiftly/en/daily
The language prefix is read from the URL path, and the layout direction (rtl/ltr) is applied automatically at the AppProviders level.

Available Scripts

All scripts are defined in package.json and can be run with bun run <script> or npm run <script>.
ScriptDescription
devStarts the Vite development server with HMR at http://localhost:5173/shiftly
buildCompiles and bundles the app for production into the dist/ directory
previewServes the production build locally for inspection before deployment
lintRuns ESLint across the entire project using the flat config
typecheckRuns tsc --project tsconfig.app.json --noEmit — type-checks src/ without emitting files
testRuns the Vitest test suite in watch mode (re-runs on file changes)
test:uiRuns Vitest with the browser-based UI explorer at http://localhost:51204/__vitest__/
test:coverageGenerates a V8 coverage report (text, JSON, HTML) under coverage/
test:ciRuns the full test suite once (vitest run) — used in CI pipelines
predeployAutomatically runs before deploy: executes typechecklinttest:cibuild
deployPublishes the dist/ directory to the gh-pages branch via gh-pages
The predeploy script is a lifecycle hook that runs automatically whenever you execute bun run deploy or npm run deploy. It sequentially runs typecheck, lint, test:ci, and build — all four must pass before the app is published to GitHub Pages. This guarantees that only type-correct, lint-clean, fully-tested builds are ever deployed.

Vite Configuration

The vite.config.ts file configures the build tool, dev server, path aliases, and Vitest test runner.

Key highlights

Base URL — The app is hosted at /shiftly/, which matches the GitHub Pages deployment path. This is required for all asset URLs to resolve correctly in production:
base: "/shiftly/",
Path alias — The @/ alias maps to the src/ directory, enabling clean imports across the codebase:
resolve: {
  alias: {
    "@": path.resolve(__dirname, "src"),
  },
},
React plugin — The official @vitejs/plugin-react plugin provides JSX transformation and Fast Refresh:
plugins: [react()],
Custom dev-server middleware — A small inline Vite plugin normalises the /shiftly/shiftly/ redirect so the router initialises correctly without a trailing slash:
{
  name: "redirect-base-no-slash",
  configureServer(server) {
    server.middlewares.use((req, _res, next) => {
      if (req.url === "/shiftly") {
        req.url = "/shiftly/";
      }
      next();
    });
  },
},
Chunking strategy — The production build splits vendor code into named chunks (vendor-react, vendor-redux, vendor-mui-core, vendor-mui-icons, vendor-mui-pickers, vendor-ui, vendor-utils, vendor-i18n) to optimise browser caching and keep individual file sizes manageable. The chunk size warning limit is raised to 600 kB. Test configuration — Vitest is configured directly inside vite.config.ts:
test: {
  globals: true,
  environment: "jsdom",
  setupFiles: "./src/test/setup.ts",
  css: true,
  exclude: ["node_modules", ".claude/**"],
  coverage: {
    provider: "v8",
    reporter: ["text", "json", "json-summary", "html"],
    exclude: ["node_modules/", "src/test/", "**/*.config.ts"],
  },
},

TypeScript Configuration

Shiftly uses two separate tsconfig files to keep application code and test code cleanly separated.

tsconfig.app.json

Covers only the application source code under src/, explicitly excluding src/test/:
{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "strict": true,
    "noEmit": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "baseUrl": ".",
    "paths": { "@/*": ["./src/*"] }
  },
  "include": ["./src"],
  "exclude": ["./src/test"]
}
The typecheck script targets this config, so test utilities and Vitest globals do not pollute the application’s type environment.

tsconfig.test.json

Covers the entire src/ tree (including tests) and adds Vitest, Node, and @testing-library/jest-dom to the types array:
{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "strict": true,
    "noEmit": true,
    "types": ["vitest/globals", "node", "@testing-library/jest-dom"],
    "baseUrl": ".",
    "paths": { "@/*": ["./src/*"] }
  },
  "include": ["./src/**/*"]
}
This config ensures test files have access to Vitest’s global describe, it, expect, and all jest-dom matchers without needing explicit imports.

Build docs developers (and LLMs) love