Repository files navigation

React.js Template

Starter template for React apps: FSD, TypeScript, Vite. Minimal dependencies, production-ready build and Docker deploy.

Stack

  • React 19 + TypeScript (strict)
  • Vite 8 + @vitejs/plugin-react — dev server and build
  • TanStack Router (+ devtools in dev) — routing (app/router: root-route, routes, shared NotFound / ErrorInterception defaults)
  • TanStack Query — server state and cache
  • Zustand — client state (in dependencies; wire stores in slices when needed)
  • i18next + react-i18next — i18n (app/providers/i18n-provider, useTranslation() in UI)
  • Valibot — validation (env, component props, API shapes)
  • Ky — HTTP client
  • SASS/SCSS + LightningCSS — styles (CSS pipeline)
  • Jest + Testing Library — tests
  • ESLint + Stylelint + Steiger (FSD) + Prettier + Commitlint + Husky — lint and commits
  • Docker + NGINX — deploy

Structure (FSD)

src/
├── app/
│ ├── layouts/ # e.g. root-layout/ (+ co-located *.schema.ts)
│ ├── providers/ # i18n-provider, query-client-provider, router-provider (kebab-case folders)
│ ├── router/ # root-route, routes, router factory
│ ├── locales/ # app-wide copy (en.json, ru.json, …)
│ └── styles/ # global SCSS entry and tokens
├── pages/ # route screens (kebab-case slices: home, not-found, error-interception, …)
├── widgets/ # cross-page blocks (e.g. navigation — header/footer)
├── features/ # user-facing flows (empty stubs ready for slices)
├── entities/ # domain pieces (empty stubs ready for slices)
└── shared/ # UI kit, api, config (validated env), lib, assets/locales

Imports only “down”: app → pages → widgets → features → entities → shared.

Slices under pages/, widgets/, entities/, and features/ use kebab-case folder names. Each slice has model/ (schemas, optional locales/ for copy, optional constants/store). Typical layout: ui/<slice>/<slice>.tsx, model/schemas/<slice>.schema.ts, optional model/locales/en.json (and other languages), and optional model/constants.ts / model/store.ts. The slice root index.ts is the public API for that slice. In app/ and shared/ui, schemas sit next to the .tsx file (no model/ under shared/ui). Domain HTTP + TanStack Query for entities/features lives in slice api/ when you add it — see AGENTS.md and .cursor/rules/api-contracts.mdc.

Internationalization (i18n)

  • Slices (pages, widgets, features, entities): put locale files in model/locales/ (en.json, ru.json, …), next to model/schemas/ — not a separate i18n/ at the slice root.
  • Shared kit copy: shared/assets/locales/. App-wide defaults: app/locales/.
  • i18n-bootstrap.ts globs those paths (plus app/*/model/locales for any future app subfolders with model), deep-merges per language, registers under i18next’s default translation namespace. In UI: useTranslation() once, dot keys (t("navigation.header.home"), …). Prefer kebab-case top-level keys in each JSON file (navigation, home, …) — see AGENTS.md and .cursor/rules/fsd-i18n.mdc.

Where to put code: layer questions

Before adding code, ask yourself in order:

  1. App — is this app init, routing, providers, global styles, or app-wide config?
  2. Pages — is this a full page (screen) for one route/URL?
  3. Widgets — is this a large self-contained UI block used on multiple pages or one of several such blocks on one page?
  4. Features — is this a user action with business value, reused in different places (form, action button, flow)?
  5. Entities — is this a business entity from the domain (model, entity representation without binding to one action)?
  6. Shared — is the code not business-bound: utils, UI kit, API client, config, i18n?

The first match defines the layer. If none fit — clarify boundaries (don’t bloat entities; non-reused code can stay on the page).

Requirements

  • Node.js ≥ 24.12
  • pnpm (recommended)

Install and run

git clone <repo-url>cd reactjs-template
pnpm install
pnpm run dev

The app will open at the URL from the output.

Scripts

CommandDescription
pnpm run devDev server with HMR (--host)
pnpm run buildProduction build (runs check first via prebuild)
pnpm run build:compressBuild + gzip/brotli for static assets
pnpm run build:analyzeBuild + bundle size report
pnpm run servePreview production build locally
pnpm run checkTypecheck + lint + tests
pnpm run testJest
pnpm run lintESLint + Stylelint + Steiger (FSD)
pnpm run lint:eslintESLint only (with autofix)
pnpm run lint:stylesStylelint for css / sass / scss
pnpm run lint:fsdSteiger FSD boundaries
pnpm run formatPrettier (code and listed formats)
pnpm run deployDeploy dist to GitHub Pages

Environment variables

Copy .env.example to .env and adjust if needed. Values are validated at startup with Valibot in src/shared/config/env.ts; invalid configuration throws before the app renders.

  • VITE_API_URL — base API URL (must be a valid URL)
  • VITE_I18N_DEBUGtrue or false — i18n debug logging
  • VITE_I18N_FALLBACK_LNG — fallback language code
  • VITE_I18N_STORAGE_KEY — key for persisting language in storage

Docker

docker build -t reactjs-template .
docker run -p 80:80 reactjs-template

Build uses build:compress; static assets are served via NGINX (config in nginx.conf).

Code standards

  • Strict typing, no any
  • FSD: layer boundaries, import direction, Steiger in CI/local
  • Component props: Valibot schemas + explicit ComponentNameProps (see AGENTS.md and .cursor/rules/)
  • Prefer arrow functions, SOLID and KISS
  • No comments or dead code in prod

Detailed rules in .cursor/rules/ and AGENTS.md.

Commitlint

Commits are checked with Conventional Commits (Husky + commitlint). Format:

<type>(<scope>): <subject>
  • type: feat, fix, docs, style, refactor, perf, test, chore, ci, build.
  • scope (optional): area of change, e.g. auth, header, deps.
  • subject: short description in imperative mood, no period at end; up to 72 chars.

Examples: feat(auth): add login form, fix(api): handle 404, chore(deps): update vite.

Contacts

License

Template is free to use, modify and distribute.

About

This template is designed for developers who want to quickly set up a React.js project with minimal hassle.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

React.js Template

Starter template for React apps: FSD, TypeScript, Vite. Minimal dependencies, production-ready build and Docker deploy.

Stack

  • React 19 + TypeScript (strict)
  • Vite 8 + @vitejs/plugin-react — dev server and build
  • TanStack Router (+ devtools in dev) — routing (app/router: root-route, routes, shared NotFound / ErrorInterception defaults)
  • TanStack Query — server state and cache
  • Zustand — client state (in dependencies; wire stores in slices when needed)
  • i18next + react-i18next — i18n (app/providers/i18n-provider, useTranslation() in UI)
  • Valibot — validation (env, component props, API shapes)
  • Ky — HTTP client
  • SASS/SCSS + LightningCSS — styles (CSS pipeline)
  • Jest + Testing Library — tests
  • ESLint + Stylelint + Steiger (FSD) + Prettier + Commitlint + Husky — lint and commits
  • Docker + NGINX — deploy

Structure (FSD)

src/
├── app/
│ ├── layouts/ # e.g. root-layout/ (+ co-located *.schema.ts)
│ ├── providers/ # i18n-provider, query-client-provider, router-provider (kebab-case folders)
│ ├── router/ # root-route, routes, router factory
│ ├── locales/ # app-wide copy (en.json, ru.json, …)
│ └── styles/ # global SCSS entry and tokens
├── pages/ # route screens (kebab-case slices: home, not-found, error-interception, …)
├── widgets/ # cross-page blocks (e.g. navigation — header/footer)
├── features/ # user-facing flows (empty stubs ready for slices)
├── entities/ # domain pieces (empty stubs ready for slices)
└── shared/ # UI kit, api, config (validated env), lib, assets/locales

Imports only “down”: app → pages → widgets → features → entities → shared.

Slices under pages/, widgets/, entities/, and features/ use kebab-case folder names. Each slice has model/ (schemas, optional locales/ for copy, optional constants/store). Typical layout: ui/<slice>/<slice>.tsx, model/schemas/<slice>.schema.ts, optional model/locales/en.json (and other languages), and optional model/constants.ts / model/store.ts. The slice root index.ts is the public API for that slice. In app/ and shared/ui, schemas sit next to the .tsx file (no model/ under shared/ui). Domain HTTP + TanStack Query for entities/features lives in slice api/ when you add it — see AGENTS.md and .cursor/rules/api-contracts.mdc.

Internationalization (i18n)

  • Slices (pages, widgets, features, entities): put locale files in model/locales/ (en.json, ru.json, …), next to model/schemas/ — not a separate i18n/ at the slice root.
  • Shared kit copy: shared/assets/locales/. App-wide defaults: app/locales/.
  • i18n-bootstrap.ts globs those paths (plus app/*/model/locales for any future app subfolders with model), deep-merges per language, registers under i18next’s default translation namespace. In UI: useTranslation() once, dot keys (t("navigation.header.home"), …). Prefer kebab-case top-level keys in each JSON file (navigation, home, …) — see AGENTS.md and .cursor/rules/fsd-i18n.mdc.

Where to put code: layer questions

Before adding code, ask yourself in order:

  1. App — is this app init, routing, providers, global styles, or app-wide config?
  2. Pages — is this a full page (screen) for one route/URL?
  3. Widgets — is this a large self-contained UI block used on multiple pages or one of several such blocks on one page?
  4. Features — is this a user action with business value, reused in different places (form, action button, flow)?
  5. Entities — is this a business entity from the domain (model, entity representation without binding to one action)?
  6. Shared — is the code not business-bound: utils, UI kit, API client, config, i18n?

The first match defines the layer. If none fit — clarify boundaries (don’t bloat entities; non-reused code can stay on the page).

Requirements

  • Node.js ≥ 24.12
  • pnpm (recommended)

Install and run

git clone <repo-url>cd reactjs-template
pnpm install
pnpm run dev

The app will open at the URL from the output.

Scripts

CommandDescription
pnpm run devDev server with HMR (--host)
pnpm run buildProduction build (runs check first via prebuild)
pnpm run build:compressBuild + gzip/brotli for static assets
pnpm run build:analyzeBuild + bundle size report
pnpm run servePreview production build locally
pnpm run checkTypecheck + lint + tests
pnpm run testJest
pnpm run lintESLint + Stylelint + Steiger (FSD)
pnpm run lint:eslintESLint only (with autofix)
pnpm run lint:stylesStylelint for css / sass / scss
pnpm run lint:fsdSteiger FSD boundaries
pnpm run formatPrettier (code and listed formats)
pnpm run deployDeploy dist to GitHub Pages

Environment variables

Copy .env.example to .env and adjust if needed. Values are validated at startup with Valibot in src/shared/config/env.ts; invalid configuration throws before the app renders.

  • VITE_API_URL — base API URL (must be a valid URL)
  • VITE_I18N_DEBUGtrue or false — i18n debug logging
  • VITE_I18N_FALLBACK_LNG — fallback language code
  • VITE_I18N_STORAGE_KEY — key for persisting language in storage

Docker

docker build -t reactjs-template .
docker run -p 80:80 reactjs-template

Build uses build:compress; static assets are served via NGINX (config in nginx.conf).

Code standards

  • Strict typing, no any
  • FSD: layer boundaries, import direction, Steiger in CI/local
  • Component props: Valibot schemas + explicit ComponentNameProps (see AGENTS.md and .cursor/rules/)
  • Prefer arrow functions, SOLID and KISS
  • No comments or dead code in prod

Detailed rules in .cursor/rules/ and AGENTS.md.

Commitlint

Commits are checked with Conventional Commits (Husky + commitlint). Format:

<type>(<scope>): <subject>
  • type: feat, fix, docs, style, refactor, perf, test, chore, ci, build.
  • scope (optional): area of change, e.g. auth, header, deps.
  • subject: short description in imperative mood, no period at end; up to 72 chars.

Examples: feat(auth): add login form, fix(api): handle 404, chore(deps): update vite.

Contacts

License

Template is free to use, modify and distribute.

About

This template is designed for developers who want to quickly set up a React.js project with minimal hassle.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

React.js Template

Starter template for React apps: FSD, TypeScript, Vite. Minimal dependencies, production-ready build and Docker deploy.

Stack

  • React 19 + TypeScript (strict)
  • Vite 8 + @vitejs/plugin-react — dev server and build
  • TanStack Router (+ devtools in dev) — routing (app/router: root-route, routes, shared NotFound / ErrorInterception defaults)
  • TanStack Query — server state and cache
  • Zustand — client state (in dependencies; wire stores in slices when needed)
  • i18next + react-i18next — i18n (app/providers/i18n-provider, useTranslation() in UI)
  • Valibot — validation (env, component props, API shapes)
  • Ky — HTTP client
  • SASS/SCSS + LightningCSS — styles (CSS pipeline)
  • Jest + Testing Library — tests
  • ESLint + Stylelint + Steiger (FSD) + Prettier + Commitlint + Husky — lint and commits
  • Docker + NGINX — deploy

Structure (FSD)

src/
├── app/
│ ├── layouts/ # e.g. root-layout/ (+ co-located *.schema.ts)
│ ├── providers/ # i18n-provider, query-client-provider, router-provider (kebab-case folders)
│ ├── router/ # root-route, routes, router factory
│ ├── locales/ # app-wide copy (en.json, ru.json, …)
│ └── styles/ # global SCSS entry and tokens
├── pages/ # route screens (kebab-case slices: home, not-found, error-interception, …)
├── widgets/ # cross-page blocks (e.g. navigation — header/footer)
├── features/ # user-facing flows (empty stubs ready for slices)
├── entities/ # domain pieces (empty stubs ready for slices)
└── shared/ # UI kit, api, config (validated env), lib, assets/locales

Imports only “down”: app → pages → widgets → features → entities → shared.

Slices under pages/, widgets/, entities/, and features/ use kebab-case folder names. Each slice has model/ (schemas, optional locales/ for copy, optional constants/store). Typical layout: ui/<slice>/<slice>.tsx, model/schemas/<slice>.schema.ts, optional model/locales/en.json (and other languages), and optional model/constants.ts / model/store.ts. The slice root index.ts is the public API for that slice. In app/ and shared/ui, schemas sit next to the .tsx file (no model/ under shared/ui). Domain HTTP + TanStack Query for entities/features lives in slice api/ when you add it — see AGENTS.md and .cursor/rules/api-contracts.mdc.

Internationalization (i18n)

  • Slices (pages, widgets, features, entities): put locale files in model/locales/ (en.json, ru.json, …), next to model/schemas/ — not a separate i18n/ at the slice root.
  • Shared kit copy: shared/assets/locales/. App-wide defaults: app/locales/.
  • i18n-bootstrap.ts globs those paths (plus app/*/model/locales for any future app subfolders with model), deep-merges per language, registers under i18next’s default translation namespace. In UI: useTranslation() once, dot keys (t("navigation.header.home"), …). Prefer kebab-case top-level keys in each JSON file (navigation, home, …) — see AGENTS.md and .cursor/rules/fsd-i18n.mdc.

Where to put code: layer questions

Before adding code, ask yourself in order:

  1. App — is this app init, routing, providers, global styles, or app-wide config?
  2. Pages — is this a full page (screen) for one route/URL?
  3. Widgets — is this a large self-contained UI block used on multiple pages or one of several such blocks on one page?
  4. Features — is this a user action with business value, reused in different places (form, action button, flow)?
  5. Entities — is this a business entity from the domain (model, entity representation without binding to one action)?
  6. Shared — is the code not business-bound: utils, UI kit, API client, config, i18n?

The first match defines the layer. If none fit — clarify boundaries (don’t bloat entities; non-reused code can stay on the page).

Requirements

  • Node.js ≥ 24.12
  • pnpm (recommended)

Install and run

git clone <repo-url>cd reactjs-template
pnpm install
pnpm run dev

The app will open at the URL from the output.

Scripts

CommandDescription
pnpm run devDev server with HMR (--host)
pnpm run buildProduction build (runs check first via prebuild)
pnpm run build:compressBuild + gzip/brotli for static assets
pnpm run build:analyzeBuild + bundle size report
pnpm run servePreview production build locally
pnpm run checkTypecheck + lint + tests
pnpm run testJest
pnpm run lintESLint + Stylelint + Steiger (FSD)
pnpm run lint:eslintESLint only (with autofix)
pnpm run lint:stylesStylelint for css / sass / scss
pnpm run lint:fsdSteiger FSD boundaries
pnpm run formatPrettier (code and listed formats)
pnpm run deployDeploy dist to GitHub Pages

Environment variables

Copy .env.example to .env and adjust if needed. Values are validated at startup with Valibot in src/shared/config/env.ts; invalid configuration throws before the app renders.

  • VITE_API_URL — base API URL (must be a valid URL)
  • VITE_I18N_DEBUGtrue or false — i18n debug logging
  • VITE_I18N_FALLBACK_LNG — fallback language code
  • VITE_I18N_STORAGE_KEY — key for persisting language in storage

Docker

docker build -t reactjs-template .
docker run -p 80:80 reactjs-template

Build uses build:compress; static assets are served via NGINX (config in nginx.conf).

Code standards

  • Strict typing, no any
  • FSD: layer boundaries, import direction, Steiger in CI/local
  • Component props: Valibot schemas + explicit ComponentNameProps (see AGENTS.md and .cursor/rules/)
  • Prefer arrow functions, SOLID and KISS
  • No comments or dead code in prod

Detailed rules in .cursor/rules/ and AGENTS.md.

Commitlint

Commits are checked with Conventional Commits (Husky + commitlint). Format:

<type>(<scope>): <subject>
  • type: feat, fix, docs, style, refactor, perf, test, chore, ci, build.
  • scope (optional): area of change, e.g. auth, header, deps.
  • subject: short description in imperative mood, no period at end; up to 72 chars.

Examples: feat(auth): add login form, fix(api): handle 404, chore(deps): update vite.

Contacts

License

Template is free to use, modify and distribute.

About

This template is designed for developers who want to quickly set up a React.js project with minimal hassle.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

React.js Template

Starter template for React apps: FSD, TypeScript, Vite. Minimal dependencies, production-ready build and Docker deploy.

Stack

  • React 19 + TypeScript (strict)
  • Vite 8 + @vitejs/plugin-react — dev server and build
  • TanStack Router (+ devtools in dev) — routing (app/router: root-route, routes, shared NotFound / ErrorInterception defaults)
  • TanStack Query — server state and cache
  • Zustand — client state (in dependencies; wire stores in slices when needed)
  • i18next + react-i18next — i18n (app/providers/i18n-provider, useTranslation() in UI)
  • Valibot — validation (env, component props, API shapes)
  • Ky — HTTP client
  • SASS/SCSS + LightningCSS — styles (CSS pipeline)
  • Jest + Testing Library — tests
  • ESLint + Stylelint + Steiger (FSD) + Prettier + Commitlint + Husky — lint and commits
  • Docker + NGINX — deploy

Structure (FSD)

src/
├── app/
│ ├── layouts/ # e.g. root-layout/ (+ co-located *.schema.ts)
│ ├── providers/ # i18n-provider, query-client-provider, router-provider (kebab-case folders)
│ ├── router/ # root-route, routes, router factory
│ ├── locales/ # app-wide copy (en.json, ru.json, …)
│ └── styles/ # global SCSS entry and tokens
├── pages/ # route screens (kebab-case slices: home, not-found, error-interception, …)
├── widgets/ # cross-page blocks (e.g. navigation — header/footer)
├── features/ # user-facing flows (empty stubs ready for slices)
├── entities/ # domain pieces (empty stubs ready for slices)
└── shared/ # UI kit, api, config (validated env), lib, assets/locales

Imports only “down”: app → pages → widgets → features → entities → shared.

Slices under pages/, widgets/, entities/, and features/ use kebab-case folder names. Each slice has model/ (schemas, optional locales/ for copy, optional constants/store). Typical layout: ui/<slice>/<slice>.tsx, model/schemas/<slice>.schema.ts, optional model/locales/en.json (and other languages), and optional model/constants.ts / model/store.ts. The slice root index.ts is the public API for that slice. In app/ and shared/ui, schemas sit next to the .tsx file (no model/ under shared/ui). Domain HTTP + TanStack Query for entities/features lives in slice api/ when you add it — see AGENTS.md and .cursor/rules/api-contracts.mdc.

Internationalization (i18n)

  • Slices (pages, widgets, features, entities): put locale files in model/locales/ (en.json, ru.json, …), next to model/schemas/ — not a separate i18n/ at the slice root.
  • Shared kit copy: shared/assets/locales/. App-wide defaults: app/locales/.
  • i18n-bootstrap.ts globs those paths (plus app/*/model/locales for any future app subfolders with model), deep-merges per language, registers under i18next’s default translation namespace. In UI: useTranslation() once, dot keys (t("navigation.header.home"), …). Prefer kebab-case top-level keys in each JSON file (navigation, home, …) — see AGENTS.md and .cursor/rules/fsd-i18n.mdc.

Where to put code: layer questions

Before adding code, ask yourself in order:

  1. App — is this app init, routing, providers, global styles, or app-wide config?
  2. Pages — is this a full page (screen) for one route/URL?
  3. Widgets — is this a large self-contained UI block used on multiple pages or one of several such blocks on one page?
  4. Features — is this a user action with business value, reused in different places (form, action button, flow)?
  5. Entities — is this a business entity from the domain (model, entity representation without binding to one action)?
  6. Shared — is the code not business-bound: utils, UI kit, API client, config, i18n?

The first match defines the layer. If none fit — clarify boundaries (don’t bloat entities; non-reused code can stay on the page).

Requirements

  • Node.js ≥ 24.12
  • pnpm (recommended)

Install and run

git clone <repo-url>cd reactjs-template
pnpm install
pnpm run dev

The app will open at the URL from the output.

Scripts

CommandDescription
pnpm run devDev server with HMR (--host)
pnpm run buildProduction build (runs check first via prebuild)
pnpm run build:compressBuild + gzip/brotli for static assets
pnpm run build:analyzeBuild + bundle size report
pnpm run servePreview production build locally
pnpm run checkTypecheck + lint + tests
pnpm run testJest
pnpm run lintESLint + Stylelint + Steiger (FSD)
pnpm run lint:eslintESLint only (with autofix)
pnpm run lint:stylesStylelint for css / sass / scss
pnpm run lint:fsdSteiger FSD boundaries
pnpm run formatPrettier (code and listed formats)
pnpm run deployDeploy dist to GitHub Pages

Environment variables

Copy .env.example to .env and adjust if needed. Values are validated at startup with Valibot in src/shared/config/env.ts; invalid configuration throws before the app renders.

  • VITE_API_URL — base API URL (must be a valid URL)
  • VITE_I18N_DEBUGtrue or false — i18n debug logging
  • VITE_I18N_FALLBACK_LNG — fallback language code
  • VITE_I18N_STORAGE_KEY — key for persisting language in storage

Docker

docker build -t reactjs-template .
docker run -p 80:80 reactjs-template

Build uses build:compress; static assets are served via NGINX (config in nginx.conf).

Code standards

  • Strict typing, no any
  • FSD: layer boundaries, import direction, Steiger in CI/local
  • Component props: Valibot schemas + explicit ComponentNameProps (see AGENTS.md and .cursor/rules/)
  • Prefer arrow functions, SOLID and KISS
  • No comments or dead code in prod

Detailed rules in .cursor/rules/ and AGENTS.md.

Commitlint

Commits are checked with Conventional Commits (Husky + commitlint). Format:

<type>(<scope>): <subject>
  • type: feat, fix, docs, style, refactor, perf, test, chore, ci, build.
  • scope (optional): area of change, e.g. auth, header, deps.
  • subject: short description in imperative mood, no period at end; up to 72 chars.

Examples: feat(auth): add login form, fix(api): handle 404, chore(deps): update vite.

Contacts

License

Template is free to use, modify and distribute.

About

This template is designed for developers who want to quickly set up a React.js project with minimal hassle.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

React.js Template

Starter template for React apps: FSD, TypeScript, Vite. Minimal dependencies, production-ready build and Docker deploy.

Stack

  • React 19 + TypeScript (strict)
  • Vite 8 + @vitejs/plugin-react — dev server and build
  • TanStack Router (+ devtools in dev) — routing (app/router: root-route, routes, shared NotFound / ErrorInterception defaults)
  • TanStack Query — server state and cache
  • Zustand — client state (in dependencies; wire stores in slices when needed)
  • i18next + react-i18next — i18n (app/providers/i18n-provider, useTranslation() in UI)
  • Valibot — validation (env, component props, API shapes)
  • Ky — HTTP client
  • SASS/SCSS + LightningCSS — styles (CSS pipeline)
  • Jest + Testing Library — tests
  • ESLint + Stylelint + Steiger (FSD) + Prettier + Commitlint + Husky — lint and commits
  • Docker + NGINX — deploy

Structure (FSD)

src/
├── app/
│ ├── layouts/ # e.g. root-layout/ (+ co-located *.schema.ts)
│ ├── providers/ # i18n-provider, query-client-provider, router-provider (kebab-case folders)
│ ├── router/ # root-route, routes, router factory
│ ├── locales/ # app-wide copy (en.json, ru.json, …)
│ └── styles/ # global SCSS entry and tokens
├── pages/ # route screens (kebab-case slices: home, not-found, error-interception, …)
├── widgets/ # cross-page blocks (e.g. navigation — header/footer)
├── features/ # user-facing flows (empty stubs ready for slices)
├── entities/ # domain pieces (empty stubs ready for slices)
└── shared/ # UI kit, api, config (validated env), lib, assets/locales

Imports only “down”: app → pages → widgets → features → entities → shared.

Slices under pages/, widgets/, entities/, and features/ use kebab-case folder names. Each slice has model/ (schemas, optional locales/ for copy, optional constants/store). Typical layout: ui/<slice>/<slice>.tsx, model/schemas/<slice>.schema.ts, optional model/locales/en.json (and other languages), and optional model/constants.ts / model/store.ts. The slice root index.ts is the public API for that slice. In app/ and shared/ui, schemas sit next to the .tsx file (no model/ under shared/ui). Domain HTTP + TanStack Query for entities/features lives in slice api/ when you add it — see AGENTS.md and .cursor/rules/api-contracts.mdc.

Internationalization (i18n)

  • Slices (pages, widgets, features, entities): put locale files in model/locales/ (en.json, ru.json, …), next to model/schemas/ — not a separate i18n/ at the slice root.
  • Shared kit copy: shared/assets/locales/. App-wide defaults: app/locales/.
  • i18n-bootstrap.ts globs those paths (plus app/*/model/locales for any future app subfolders with model), deep-merges per language, registers under i18next’s default translation namespace. In UI: useTranslation() once, dot keys (t("navigation.header.home"), …). Prefer kebab-case top-level keys in each JSON file (navigation, home, …) — see AGENTS.md and .cursor/rules/fsd-i18n.mdc.

Where to put code: layer questions

Before adding code, ask yourself in order:

  1. App — is this app init, routing, providers, global styles, or app-wide config?
  2. Pages — is this a full page (screen) for one route/URL?
  3. Widgets — is this a large self-contained UI block used on multiple pages or one of several such blocks on one page?
  4. Features — is this a user action with business value, reused in different places (form, action button, flow)?
  5. Entities — is this a business entity from the domain (model, entity representation without binding to one action)?
  6. Shared — is the code not business-bound: utils, UI kit, API client, config, i18n?

The first match defines the layer. If none fit — clarify boundaries (don’t bloat entities; non-reused code can stay on the page).

Requirements

  • Node.js ≥ 24.12
  • pnpm (recommended)

Install and run

git clone <repo-url>cd reactjs-template
pnpm install
pnpm run dev

The app will open at the URL from the output.

Scripts

CommandDescription
pnpm run devDev server with HMR (--host)
pnpm run buildProduction build (runs check first via prebuild)
pnpm run build:compressBuild + gzip/brotli for static assets
pnpm run build:analyzeBuild + bundle size report
pnpm run servePreview production build locally
pnpm run checkTypecheck + lint + tests
pnpm run testJest
pnpm run lintESLint + Stylelint + Steiger (FSD)
pnpm run lint:eslintESLint only (with autofix)
pnpm run lint:stylesStylelint for css / sass / scss
pnpm run lint:fsdSteiger FSD boundaries
pnpm run formatPrettier (code and listed formats)
pnpm run deployDeploy dist to GitHub Pages

Environment variables

Copy .env.example to .env and adjust if needed. Values are validated at startup with Valibot in src/shared/config/env.ts; invalid configuration throws before the app renders.

  • VITE_API_URL — base API URL (must be a valid URL)
  • VITE_I18N_DEBUGtrue or false — i18n debug logging
  • VITE_I18N_FALLBACK_LNG — fallback language code
  • VITE_I18N_STORAGE_KEY — key for persisting language in storage

Docker

docker build -t reactjs-template .
docker run -p 80:80 reactjs-template

Build uses build:compress; static assets are served via NGINX (config in nginx.conf).

Code standards

  • Strict typing, no any
  • FSD: layer boundaries, import direction, Steiger in CI/local
  • Component props: Valibot schemas + explicit ComponentNameProps (see AGENTS.md and .cursor/rules/)
  • Prefer arrow functions, SOLID and KISS
  • No comments or dead code in prod

Detailed rules in .cursor/rules/ and AGENTS.md.

Commitlint

Commits are checked with Conventional Commits (Husky + commitlint). Format:

<type>(<scope>): <subject>
  • type: feat, fix, docs, style, refactor, perf, test, chore, ci, build.
  • scope (optional): area of change, e.g. auth, header, deps.
  • subject: short description in imperative mood, no period at end; up to 72 chars.

Examples: feat(auth): add login form, fix(api): handle 404, chore(deps): update vite.

Contacts

License

Template is free to use, modify and distribute.

About

This template is designed for developers who want to quickly set up a React.js project with minimal hassle.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

React.js Template

Starter template for React apps: FSD, TypeScript, Vite. Minimal dependencies, production-ready build and Docker deploy.

Stack

  • React 19 + TypeScript (strict)
  • Vite 8 + @vitejs/plugin-react — dev server and build
  • TanStack Router (+ devtools in dev) — routing (app/router: root-route, routes, shared NotFound / ErrorInterception defaults)
  • TanStack Query — server state and cache
  • Zustand — client state (in dependencies; wire stores in slices when needed)
  • i18next + react-i18next — i18n (app/providers/i18n-provider, useTranslation() in UI)
  • Valibot — validation (env, component props, API shapes)
  • Ky — HTTP client
  • SASS/SCSS + LightningCSS — styles (CSS pipeline)
  • Jest + Testing Library — tests
  • ESLint + Stylelint + Steiger (FSD) + Prettier + Commitlint + Husky — lint and commits
  • Docker + NGINX — deploy

Structure (FSD)

src/
├── app/
│ ├── layouts/ # e.g. root-layout/ (+ co-located *.schema.ts)
│ ├── providers/ # i18n-provider, query-client-provider, router-provider (kebab-case folders)
│ ├── router/ # root-route, routes, router factory
│ ├── locales/ # app-wide copy (en.json, ru.json, …)
│ └── styles/ # global SCSS entry and tokens
├── pages/ # route screens (kebab-case slices: home, not-found, error-interception, …)
├── widgets/ # cross-page blocks (e.g. navigation — header/footer)
├── features/ # user-facing flows (empty stubs ready for slices)
├── entities/ # domain pieces (empty stubs ready for slices)
└── shared/ # UI kit, api, config (validated env), lib, assets/locales

Imports only “down”: app → pages → widgets → features → entities → shared.

Slices under pages/, widgets/, entities/, and features/ use kebab-case folder names. Each slice has model/ (schemas, optional locales/ for copy, optional constants/store). Typical layout: ui/<slice>/<slice>.tsx, model/schemas/<slice>.schema.ts, optional model/locales/en.json (and other languages), and optional model/constants.ts / model/store.ts. The slice root index.ts is the public API for that slice. In app/ and shared/ui, schemas sit next to the .tsx file (no model/ under shared/ui). Domain HTTP + TanStack Query for entities/features lives in slice api/ when you add it — see AGENTS.md and .cursor/rules/api-contracts.mdc.

Internationalization (i18n)

  • Slices (pages, widgets, features, entities): put locale files in model/locales/ (en.json, ru.json, …), next to model/schemas/ — not a separate i18n/ at the slice root.
  • Shared kit copy: shared/assets/locales/. App-wide defaults: app/locales/.
  • i18n-bootstrap.ts globs those paths (plus app/*/model/locales for any future app subfolders with model), deep-merges per language, registers under i18next’s default translation namespace. In UI: useTranslation() once, dot keys (t("navigation.header.home"), …). Prefer kebab-case top-level keys in each JSON file (navigation, home, …) — see AGENTS.md and .cursor/rules/fsd-i18n.mdc.

Where to put code: layer questions

Before adding code, ask yourself in order:

  1. App — is this app init, routing, providers, global styles, or app-wide config?
  2. Pages — is this a full page (screen) for one route/URL?
  3. Widgets — is this a large self-contained UI block used on multiple pages or one of several such blocks on one page?
  4. Features — is this a user action with business value, reused in different places (form, action button, flow)?
  5. Entities — is this a business entity from the domain (model, entity representation without binding to one action)?
  6. Shared — is the code not business-bound: utils, UI kit, API client, config, i18n?

The first match defines the layer. If none fit — clarify boundaries (don’t bloat entities; non-reused code can stay on the page).

Requirements

  • Node.js ≥ 24.12
  • pnpm (recommended)

Install and run

git clone <repo-url>cd reactjs-template
pnpm install
pnpm run dev

The app will open at the URL from the output.

Scripts

CommandDescription
pnpm run devDev server with HMR (--host)
pnpm run buildProduction build (runs check first via prebuild)
pnpm run build:compressBuild + gzip/brotli for static assets
pnpm run build:analyzeBuild + bundle size report
pnpm run servePreview production build locally
pnpm run checkTypecheck + lint + tests
pnpm run testJest
pnpm run lintESLint + Stylelint + Steiger (FSD)
pnpm run lint:eslintESLint only (with autofix)
pnpm run lint:stylesStylelint for css / sass / scss
pnpm run lint:fsdSteiger FSD boundaries
pnpm run formatPrettier (code and listed formats)
pnpm run deployDeploy dist to GitHub Pages

Environment variables

Copy .env.example to .env and adjust if needed. Values are validated at startup with Valibot in src/shared/config/env.ts; invalid configuration throws before the app renders.

  • VITE_API_URL — base API URL (must be a valid URL)
  • VITE_I18N_DEBUGtrue or false — i18n debug logging
  • VITE_I18N_FALLBACK_LNG — fallback language code
  • VITE_I18N_STORAGE_KEY — key for persisting language in storage

Docker

docker build -t reactjs-template .
docker run -p 80:80 reactjs-template

Build uses build:compress; static assets are served via NGINX (config in nginx.conf).

Code standards

  • Strict typing, no any
  • FSD: layer boundaries, import direction, Steiger in CI/local
  • Component props: Valibot schemas + explicit ComponentNameProps (see AGENTS.md and .cursor/rules/)
  • Prefer arrow functions, SOLID and KISS
  • No comments or dead code in prod

Detailed rules in .cursor/rules/ and AGENTS.md.

Commitlint

Commits are checked with Conventional Commits (Husky + commitlint). Format:

<type>(<scope>): <subject>
  • type: feat, fix, docs, style, refactor, perf, test, chore, ci, build.
  • scope (optional): area of change, e.g. auth, header, deps.
  • subject: short description in imperative mood, no period at end; up to 72 chars.

Examples: feat(auth): add login form, fix(api): handle 404, chore(deps): update vite.

Contacts

License

Template is free to use, modify and distribute.

About

This template is designed for developers who want to quickly set up a React.js project with minimal hassle.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

React.js Template

Starter template for React apps: FSD, TypeScript, Vite. Minimal dependencies, production-ready build and Docker deploy.

Stack

  • React 19 + TypeScript (strict)
  • Vite 8 + @vitejs/plugin-react — dev server and build
  • TanStack Router (+ devtools in dev) — routing (app/router: root-route, routes, shared NotFound / ErrorInterception defaults)
  • TanStack Query — server state and cache
  • Zustand — client state (in dependencies; wire stores in slices when needed)
  • i18next + react-i18next — i18n (app/providers/i18n-provider, useTranslation() in UI)
  • Valibot — validation (env, component props, API shapes)
  • Ky — HTTP client
  • SASS/SCSS + LightningCSS — styles (CSS pipeline)
  • Jest + Testing Library — tests
  • ESLint + Stylelint + Steiger (FSD) + Prettier + Commitlint + Husky — lint and commits
  • Docker + NGINX — deploy

Structure (FSD)

src/
├── app/
│ ├── layouts/ # e.g. root-layout/ (+ co-located *.schema.ts)
│ ├── providers/ # i18n-provider, query-client-provider, router-provider (kebab-case folders)
│ ├── router/ # root-route, routes, router factory
│ ├── locales/ # app-wide copy (en.json, ru.json, …)
│ └── styles/ # global SCSS entry and tokens
├── pages/ # route screens (kebab-case slices: home, not-found, error-interception, …)
├── widgets/ # cross-page blocks (e.g. navigation — header/footer)
├── features/ # user-facing flows (empty stubs ready for slices)
├── entities/ # domain pieces (empty stubs ready for slices)
└── shared/ # UI kit, api, config (validated env), lib, assets/locales

Imports only “down”: app → pages → widgets → features → entities → shared.

Slices under pages/, widgets/, entities/, and features/ use kebab-case folder names. Each slice has model/ (schemas, optional locales/ for copy, optional constants/store). Typical layout: ui/<slice>/<slice>.tsx, model/schemas/<slice>.schema.ts, optional model/locales/en.json (and other languages), and optional model/constants.ts / model/store.ts. The slice root index.ts is the public API for that slice. In app/ and shared/ui, schemas sit next to the .tsx file (no model/ under shared/ui). Domain HTTP + TanStack Query for entities/features lives in slice api/ when you add it — see AGENTS.md and .cursor/rules/api-contracts.mdc.

Internationalization (i18n)

  • Slices (pages, widgets, features, entities): put locale files in model/locales/ (en.json, ru.json, …), next to model/schemas/ — not a separate i18n/ at the slice root.
  • Shared kit copy: shared/assets/locales/. App-wide defaults: app/locales/.
  • i18n-bootstrap.ts globs those paths (plus app/*/model/locales for any future app subfolders with model), deep-merges per language, registers under i18next’s default translation namespace. In UI: useTranslation() once, dot keys (t("navigation.header.home"), …). Prefer kebab-case top-level keys in each JSON file (navigation, home, …) — see AGENTS.md and .cursor/rules/fsd-i18n.mdc.

Where to put code: layer questions

Before adding code, ask yourself in order:

  1. App — is this app init, routing, providers, global styles, or app-wide config?
  2. Pages — is this a full page (screen) for one route/URL?
  3. Widgets — is this a large self-contained UI block used on multiple pages or one of several such blocks on one page?
  4. Features — is this a user action with business value, reused in different places (form, action button, flow)?
  5. Entities — is this a business entity from the domain (model, entity representation without binding to one action)?
  6. Shared — is the code not business-bound: utils, UI kit, API client, config, i18n?

The first match defines the layer. If none fit — clarify boundaries (don’t bloat entities; non-reused code can stay on the page).

Requirements

  • Node.js ≥ 24.12
  • pnpm (recommended)

Install and run

git clone <repo-url>cd reactjs-template
pnpm install
pnpm run dev

The app will open at the URL from the output.

Scripts

CommandDescription
pnpm run devDev server with HMR (--host)
pnpm run buildProduction build (runs check first via prebuild)
pnpm run build:compressBuild + gzip/brotli for static assets
pnpm run build:analyzeBuild + bundle size report
pnpm run servePreview production build locally
pnpm run checkTypecheck + lint + tests
pnpm run testJest
pnpm run lintESLint + Stylelint + Steiger (FSD)
pnpm run lint:eslintESLint only (with autofix)
pnpm run lint:stylesStylelint for css / sass / scss
pnpm run lint:fsdSteiger FSD boundaries
pnpm run formatPrettier (code and listed formats)
pnpm run deployDeploy dist to GitHub Pages

Environment variables

Copy .env.example to .env and adjust if needed. Values are validated at startup with Valibot in src/shared/config/env.ts; invalid configuration throws before the app renders.

  • VITE_API_URL — base API URL (must be a valid URL)
  • VITE_I18N_DEBUGtrue or false — i18n debug logging
  • VITE_I18N_FALLBACK_LNG — fallback language code
  • VITE_I18N_STORAGE_KEY — key for persisting language in storage

Docker

docker build -t reactjs-template .
docker run -p 80:80 reactjs-template

Build uses build:compress; static assets are served via NGINX (config in nginx.conf).

Code standards

  • Strict typing, no any
  • FSD: layer boundaries, import direction, Steiger in CI/local
  • Component props: Valibot schemas + explicit ComponentNameProps (see AGENTS.md and .cursor/rules/)
  • Prefer arrow functions, SOLID and KISS
  • No comments or dead code in prod

Detailed rules in .cursor/rules/ and AGENTS.md.

Commitlint

Commits are checked with Conventional Commits (Husky + commitlint). Format:

<type>(<scope>): <subject>
  • type: feat, fix, docs, style, refactor, perf, test, chore, ci, build.
  • scope (optional): area of change, e.g. auth, header, deps.
  • subject: short description in imperative mood, no period at end; up to 72 chars.

Examples: feat(auth): add login form, fix(api): handle 404, chore(deps): update vite.

Contacts

License

Template is free to use, modify and distribute.

About

This template is designed for developers who want to quickly set up a React.js project with minimal hassle.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

React.js Template

Starter template for React apps: FSD, TypeScript, Vite. Minimal dependencies, production-ready build and Docker deploy.

Stack

  • React 19 + TypeScript (strict)
  • Vite 8 + @vitejs/plugin-react — dev server and build
  • TanStack Router (+ devtools in dev) — routing (app/router: root-route, routes, shared NotFound / ErrorInterception defaults)
  • TanStack Query — server state and cache
  • Zustand — client state (in dependencies; wire stores in slices when needed)
  • i18next + react-i18next — i18n (app/providers/i18n-provider, useTranslation() in UI)
  • Valibot — validation (env, component props, API shapes)
  • Ky — HTTP client
  • SASS/SCSS + LightningCSS — styles (CSS pipeline)
  • Jest + Testing Library — tests
  • ESLint + Stylelint + Steiger (FSD) + Prettier + Commitlint + Husky — lint and commits
  • Docker + NGINX — deploy

Structure (FSD)

src/
├── app/
│ ├── layouts/ # e.g. root-layout/ (+ co-located *.schema.ts)
│ ├── providers/ # i18n-provider, query-client-provider, router-provider (kebab-case folders)
│ ├── router/ # root-route, routes, router factory
│ ├── locales/ # app-wide copy (en.json, ru.json, …)
│ └── styles/ # global SCSS entry and tokens
├── pages/ # route screens (kebab-case slices: home, not-found, error-interception, …)
├── widgets/ # cross-page blocks (e.g. navigation — header/footer)
├── features/ # user-facing flows (empty stubs ready for slices)
├── entities/ # domain pieces (empty stubs ready for slices)
└── shared/ # UI kit, api, config (validated env), lib, assets/locales

Imports only “down”: app → pages → widgets → features → entities → shared.

Slices under pages/, widgets/, entities/, and features/ use kebab-case folder names. Each slice has model/ (schemas, optional locales/ for copy, optional constants/store). Typical layout: ui/<slice>/<slice>.tsx, model/schemas/<slice>.schema.ts, optional model/locales/en.json (and other languages), and optional model/constants.ts / model/store.ts. The slice root index.ts is the public API for that slice. In app/ and shared/ui, schemas sit next to the .tsx file (no model/ under shared/ui). Domain HTTP + TanStack Query for entities/features lives in slice api/ when you add it — see AGENTS.md and .cursor/rules/api-contracts.mdc.

Internationalization (i18n)

  • Slices (pages, widgets, features, entities): put locale files in model/locales/ (en.json, ru.json, …), next to model/schemas/ — not a separate i18n/ at the slice root.
  • Shared kit copy: shared/assets/locales/. App-wide defaults: app/locales/.
  • i18n-bootstrap.ts globs those paths (plus app/*/model/locales for any future app subfolders with model), deep-merges per language, registers under i18next’s default translation namespace. In UI: useTranslation() once, dot keys (t("navigation.header.home"), …). Prefer kebab-case top-level keys in each JSON file (navigation, home, …) — see AGENTS.md and .cursor/rules/fsd-i18n.mdc.

Where to put code: layer questions

Before adding code, ask yourself in order:

  1. App — is this app init, routing, providers, global styles, or app-wide config?
  2. Pages — is this a full page (screen) for one route/URL?
  3. Widgets — is this a large self-contained UI block used on multiple pages or one of several such blocks on one page?
  4. Features — is this a user action with business value, reused in different places (form, action button, flow)?
  5. Entities — is this a business entity from the domain (model, entity representation without binding to one action)?
  6. Shared — is the code not business-bound: utils, UI kit, API client, config, i18n?

The first match defines the layer. If none fit — clarify boundaries (don’t bloat entities; non-reused code can stay on the page).

Requirements

  • Node.js ≥ 24.12
  • pnpm (recommended)

Install and run

git clone <repo-url>cd reactjs-template
pnpm install
pnpm run dev

The app will open at the URL from the output.

Scripts

CommandDescription
pnpm run devDev server with HMR (--host)
pnpm run buildProduction build (runs check first via prebuild)
pnpm run build:compressBuild + gzip/brotli for static assets
pnpm run build:analyzeBuild + bundle size report
pnpm run servePreview production build locally
pnpm run checkTypecheck + lint + tests
pnpm run testJest
pnpm run lintESLint + Stylelint + Steiger (FSD)
pnpm run lint:eslintESLint only (with autofix)
pnpm run lint:stylesStylelint for css / sass / scss
pnpm run lint:fsdSteiger FSD boundaries
pnpm run formatPrettier (code and listed formats)
pnpm run deployDeploy dist to GitHub Pages

Environment variables

Copy .env.example to .env and adjust if needed. Values are validated at startup with Valibot in src/shared/config/env.ts; invalid configuration throws before the app renders.

  • VITE_API_URL — base API URL (must be a valid URL)
  • VITE_I18N_DEBUGtrue or false — i18n debug logging
  • VITE_I18N_FALLBACK_LNG — fallback language code
  • VITE_I18N_STORAGE_KEY — key for persisting language in storage

Docker

docker build -t reactjs-template .
docker run -p 80:80 reactjs-template

Build uses build:compress; static assets are served via NGINX (config in nginx.conf).

Code standards

  • Strict typing, no any
  • FSD: layer boundaries, import direction, Steiger in CI/local
  • Component props: Valibot schemas + explicit ComponentNameProps (see AGENTS.md and .cursor/rules/)
  • Prefer arrow functions, SOLID and KISS
  • No comments or dead code in prod

Detailed rules in .cursor/rules/ and AGENTS.md.

Commitlint

Commits are checked with Conventional Commits (Husky + commitlint). Format:

<type>(<scope>): <subject>
  • type: feat, fix, docs, style, refactor, perf, test, chore, ci, build.
  • scope (optional): area of change, e.g. auth, header, deps.
  • subject: short description in imperative mood, no period at end; up to 72 chars.

Examples: feat(auth): add login form, fix(api): handle 404, chore(deps): update vite.

Contacts

License

Template is free to use, modify and distribute.

About

This template is designed for developers who want to quickly set up a React.js project with minimal hassle.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages