SuperAPI AI Directory

tech-stack

Coding & development

View repository

Updated 10-15 21:42

About this skill

FMC tech stack

Default stack for geo-heavy React SPAs at FixMyBerlin / FMC. Use for tech decisions when creating or changing an app — not as a deep dive into any one library.

Install sibling skills separately: bunx skills add FixMyBerlin/fixmyskills --skill <name> -a cursor -y

When to apply

  • Greenfield app scaffold (dependencies, tooling, folder layout)
  • Adding or renaming package.json scripts
  • Library or pattern choice (“should we use X?”)
  • Cross-cutting convention review on an existing app
  • Cursor MCP setup for Postgres schema inspection, agent DB queries, or browser exploration MCP

LLM resources

Load references/llm-resources.md only for the area the task touches.

Maps: load skill react-map-gl (and upstream React Map GL docs when the skill points there).

Specialized skills

Prefer installed skill names when present; otherwise fetch from git.

Area Skill GitHub
Rust/WASM geo rust-wasm-geo https://github.com/FixMyBerlin/fixmyskills/tree/main/skills/rust-wasm-geo
Maps (react-map-gl) react-map-gl https://github.com/FixMyBerlin/fixmyskills/tree/main/skills/react-map-gl
React TS patterns, useEffect discipline react-dev https://github.com/FixMyBerlin/fixmyskills/tree/main/skills/react-dev
TanStack Router (search, loaders, Query) tanstack-router-conventions https://github.com/FixMyBerlin/fixmyskills/tree/main/skills/tanstack-router-conventions
Router search params (UI routes) — https://github.com/FixMyBerlin/fixmyskills/blob/main/skills/tanstack-router-conventions/references/params-search-ui-routes.md
Router search serialization (pretty URLs) — https://github.com/FixMyBerlin/fixmyskills/blob/main/skills/tanstack-router-conventions/references/router-search-serialization.md
Router + Query loaders — https://github.com/FixMyBerlin/fixmyskills/blob/main/skills/tanstack-router-conventions/references/router-and-query.md
Devtools debug panel — https://github.com/FixMyBerlin/fixmyskills/blob/main/skills/tanstack-router-conventions/references/devtools.md
TanStack Start (boundaries, SSR, server) tanstack-start-conventions https://github.com/FixMyBerlin/fixmyskills/tree/main/skills/tanstack-start-conventions
App folder layout (Start) — https://github.com/FixMyBerlin/fixmyskills/blob/main/skills/tanstack-start-conventions/references/app-structure.md
URL state (TanStack Router apps) tanstack-router-conventions params-search-ui-routes.md
URL state (Next.js / legacy) nuqs https://github.com/FixMyBerlin/fixmyskills/tree/main/skills/nuqs
Client global state zustand-state-management https://github.com/FixMyBerlin/fixmyskills/tree/main/skills/zustand-state-management
Prisma schema naming, migrations prisma https://github.com/FixMyBerlin/fixmyskills/tree/main/skills/prisma
E2E / Playwright playwright-skill https://github.com/FixMyBerlin/fixmyskills/tree/main/skills/playwright-skill

Runtime and build

  • Runtime / package manager: Bun — install policy bun-install.md (≥ 1.3.14, global store, bun --bun for Vite, .nvmrc for Prisma/Playwright; Docker image install and Netlify function packaging)
  • Build: latest Vite (8+)
  • Lint / format: oxlint and oxfmt with fix flags; Prettier-compatible defaults:
    • class sorting, import sorting, package.json sorting
    • printWidth 100, semicolons asNeeded, single quotes
    • 'typescript/switch-exhaustiveness-check': 'error'
    • React Compiler: oxlint react plugin + 'react/unsupported-syntax': 'error'; Vite via viteReact({ compiler: true }) + oxc-transform-react (not Babel)
    • Templates: examples/oxfmt.config.mjs, examples/oxlint.config.mjs
    • Setup and per-project tuning: references/oxc-config.md
  • Client browser target: browserslist in package.json drives Vite client build.target and eslint-plugin-compat in oxlint — references/browser-target.md

React and TypeScript

  • UI: React 19
  • TypeScript (default): typescript@^7 (native port; 7.0 release). Typecheck with tsc --noEmit via bun run type-check. The workspace typescript package provides both CLI (tsc) and editor language service — do not add a separate compiler binary for type-check. Nightlies: typescript@next (not the retired @typescript/native-preview package).
  • Editor/CLI alignment: js/ts.tsdk.path must resolve to the same devDependencies.typescript install as tsc (package root, not lib/). Misalignment makes IDE diagnostics disagree with bun run type-check.
  • Scaffold (TS 7): package.json — devDependencies.typescript ^7, script "type-check": "tsc --noEmit" (add -p when using split tsconfigs); pin @typescript/typescript-darwin-arm64 / @typescript/typescript-linux-x64 in optionalDependencies at the same version when CI runs on a different platform than dev (the typescript package lists these as optional — extend for other platforms as needed). bunfig.toml — bun-install.md. Commit .vscode/settings.json (template: examples/vscode.settings.typescript.json.template) and recommend the TypeScript 7 extension in .vscode/extensions.json (examples/vscode.extensions.json.template).
  • Monorepos: when TypeScript lives in a package subfolder, prefix js/ts.tsdk.path to that package’s node_modules/typescript (e.g. app/node_modules/typescript — tilda-geo).
  • Cursor / VS Code: install TypeScript 7 (TypeScriptTeam.native-preview — marketplace ID unchanged). Enable via command palette TypeScript: Enable TypeScript 7 or the settings template. Copy examples/vscode.settings.typescript.json.template into .vscode/settings.json (merge with oxc keys from references/oxc-config.md). Toggle back with Disable TypeScript 7 Language Server when editor plugins still require TS 6 (Vue, Astro, Svelte, Angular templates — see release notes).
  • Cursor MCP (user-level): ~/.cursor/mcp.json only — examples/mcp.json.template. Postgres: references/cursor-mcp.md. Browser exploration: references/agent-browser-mcp.md. Never commit MCP config to a repo.
  • Cursor rules (app-level): copy examples/package-json-scripts.md.template → .cursor/rules/package-json-scripts.md on scaffold — references/package-json-scripts.md

Verify: node -e "console.log(require('typescript/package.json').version)", tsc --version, and bun run type-check — all 7.x. In the editor, confirm TypeScript 7 is enabled (status bar / command palette). Do not add typescript to repos that have no TS source (e.g. this skills monorepo).

  • React Compiler: on by default — see skill react-dev for memoization and typing conventions
  • GeoJSON: @types/geojson for all GeoJSON payloads
  • Dates / times: @date-fns/tz
  • Validation: Zod 4

tsconfig templates

Use two profiles — do not merge app and scripts into one config.

Profile Template Profile analogue
App (DOM, TanStack Start) examples/tsconfig.app.json total-typescript bundler/dom
Scripts (CLI, no DOM) examples/tsconfig.scripts.json total-typescript bundler/no-dom

Required type packages whenever compilerOptions.types includes bun-types / web — these names are npm packages, not built-in. Install as direct devDependencies (Knip and globalStore will not treat a transitive dep as yours — knip.md / bun-install.md):

  • @types/bun pinned to the Bun floor (1.3.14)
  • bun-types as a direct dep (^ that floor) — types looks up the package name bun-types; @types/bun alone is not enough
  • @types/web if the config lists "web" — setting types turns off automatic @types/* inclusion, so DOM globals disappear unless web is installed and listed

Scripts profile (types: ["bun-types"]) still needs both @types/bun and bun-types even with no DOM. Bun scripts should use Glob / Bun.file(); that is only type-safe after these deps — otherwise agents fall back to node:fs.

Copy and adapt on scaffold. Adjust paths to project layout (./src/* vs ./*). Add allowJs: true only when the repo still has .js files.

TanStack Start (app only): verbatimModuleSyntax: false — type-only imports can become empty runtime imports and leak server code into client bundles. See header comments in tsconfig.app.json.

Never install or extends @total-typescript/tsconfig — keep settings inlined with deviation comments.

Typecheck:

tsc --noEmit -p tsconfig.app.json && tsc --noEmit -p tsconfig.scripts.json

Single-config repos (e.g. one root tsconfig.json covering app + scripts) are acceptable; greenfield TanStack Start apps should prefer split configs.

Astro / single-config: keep extends: astro/tsconfigs/strict. Set types to ["bun-types", "web"]. Do not add vite/client (Astro client types come from .astro/types.d.ts). Scripts in the same tsconfig still need Bun types (same packages as above).

Optional root tsconfig.json with "references" to both child configs.

ES2025: target and lib stay in sync. lib adds typings only; new ES2025 runtime APIs in client bundles are not auto-polyfilled — use deliberately on the client; fine on server/Bun/scripts. Which browsers get that client bundle: references/browser-target.md.

Component typing, Compiler, oxlint React rules, and useEffect discipline: skill react-dev. Map camera, clicks, and layers: skill react-map-gl (not useEffect + map.on()).

Data and state

Need Choice
Server / async data TanStack Query — no raw useEffect fetch; Suspense where the router supports it
Forms (non-trivial) TanStack Form
Routing TanStack Router / Start
Shareable URL state (TanStack apps) Route validateSearch (Zod) — see tanstack-router-conventions → params-search-ui-routes.md
Shareable URL state (Next.js) nuqs — see skill nuqs
High-frequency URL updates @tanstack/react-pacer — see https://tanstack.com/pacer/latest
Global client state Zustand (tkdodo patterns) — skill zustand-state-management
Local UI state useState
Prisma schema / migrations skill prisma — naming, relation fields, migrate workflows

Loader + Query integration: router-and-query.md.

Styling and UI

  • CSS: Tailwind CSS, @tailwindcss/forms, @tailwindcss/typography
  • Class merging: tailwind-merge with twJoin, twMerge
  • Fonts: Fontsource imports
  • Accessibility: semantic HTML; keyboard-accessible map controls; do not rely on color alone

Maps and geo (JS)

Stack choices only — map component patterns, layers, events, URL viewport: skill react-map-gl.

Choice Default
Library react-map-gl/maplibre (not raw MapLibre in components)
Basemap OpenFreeMap; Maptiler if required
Coordinates WGS84, [lng, lat] at API boundaries; validate with Zod
Turf @turf/* per-function imports — not import * as turf
Feature editing @osm-editor-kit/react-map-gl-draw (controlled value / onChange, styles as layer styles); example: tilda-geo drawing. Used before, still a possible alternative: TerraDraw with maplibre-gl-terradraw

Rust / WASM geo

Turf vs WASM, crates, Vite wiring: skill rust-wasm-geo.

Dependency updates (Dependabot)

  • Schedule by project type — AskQuestion if unclear. FixMyCity: weekly Monday. Private OSS and Astro: first Friday of the month. Same template. Details: dependabot.md.
  • One open PR at a time per ecosystem (open-pull-requests-limit: 1).
  • Template: examples/dependabot.yml.template
  • Reviewing and merging PRs: skill review-dependabot (changelog triage, risk tiers, rebase merge)

CI (GitHub Actions)

  • PR dependency review: permissive allow-licenses (not deprecated deny-licenses); include AGPL-3.0 and AGPL-3.0-or-later when the project is AGPL — template: examples/ci.yml.template

Tests and quality

Need Skill / tool
Unit / component tests Vitest (always)
Cross-route, map, or auth flows playwright-skill
Pure logic / utils only Vitest — skip Playwright
Explicit deps / dead exports knip.md · verify scripts package-json-scripts.md

Quick decisions

flowchart TD
  start[Tech decision] --> maps{Maps involved?}
  maps -->|yes| reactMapGl[react-map-gl skill]
  maps -->|no| data{Server or URL state?}
  data -->|server| tanstackQuery[router-and-query.md]
  data -->|URL TanStack| validateSearch[params-search-ui-routes.md]
  data -->|URL Next/shared| nuqsSkill[nuqs skill]
  data -->|client global| zustandSkill[zustand-state-management]
  maps -->|slow geo compute| rustWasm[rust-wasm-geo skill]