MSF React Template¶
@msflib/react-template scaffolds a new Next.js app pre-wired with the MSFLib stack and a standard folder architecture, so you start building your feature instead of wiring up providers and config.
Quick Start¶
0. One-time setup: GitHub Packages access¶
The template and all @msflib/* modules are published to GitHub Packages. Add this to your ~/.npmrc (once per machine), using a GitHub personal access token with the read:packages scope:
@msflib:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN
1. Scaffold a new app¶
npx @msflib/react-template@latest my-app
(create-msf-app is only the local bin name once this package is installed — npx create-msf-app on its own will 404, since that alias isn't published separately. Use the command above.)
Use @msflib/react-template, not @kodehauz/react-template
@kodehauz/react-template is the old, unmaintained package. Apps generated from it import APIs that no longer exist in the current msflib modules (for example tenantHookDecorator, which is now workspaceHookDecorator) and fail on pnpm dev. Always scaffold with the command above.
You'll be asked a few questions as it runs — see The prompts, explained below if you're not sure what to answer.
2. Dependencies install automatically¶
The CLI runs pnpm install for you (and a second pnpm add pass for multi-tenancy/optional packages if you selected any) — no extra step needed.
3. Run it¶
cd my-app
pnpm dev
Open http://localhost:3000.
What you get by default¶
- Next.js (App Router)
- Tailwind CSS (
@tailwindcss/postcss) - Material UI (
@mui/material,@emotion/react,@emotion/styled) - TanStack Query
@msflib/react-components- Route groups already set up:
(public),(auth),(protected)underapp/
The prompts, explained¶
| Prompt | What it means |
|---|---|
| Scaffold with GitHub workflows? | Copies .github/workflows into your new project (CI, publish, etc.). Say no for a quick hackathon throwaway project. |
| Reusable workflows repository (org/repo) | Only asked if you said yes above — the org/repo whose reusable workflow files your copied workflows should point at. |
| Is this a multi-tenant project? | If yes, installs @msflib/core + @msflib/react-shared + @msflib/react-workspace and sets NEXT_PUBLIC_WORKSPACE_MODE=multi in your env files. Say no for a single-tenant hackathon app unless multi-tenancy is actually part of what you're building. |
| How should tenancy be resolved? | Only asked if multi-tenant. Path-based scopes requests like /tenant/dashboard; header-based sends an X-Tenant-ID-style header instead. This sets NEXT_PUBLIC_WORKSPACE_STRATEGY, which lib/application.config.ts uses to pick workspaceHookDecorator('path' \| 'header'). |
| Select optional msflib modules | Multiselect from @msflib/react-profile, @msflib/react-notification, @msflib/react-support, @msflib/react-certificate (plus @msflib/react-workspace, unless you enabled multi-tenancy above — it's then installed automatically). Pick only what your feature actually needs — each one adds a provider you'll wire up next. |
After scaffolding¶
- Read
docs/IMPLEMENTATION_GUIDE.mdin your new project before writing code. It's copied in automatically and defines the architecture conventions this scaffold expects — folder placement, file naming, routing, forms (FormBuilder), tables (TableWidget), and theming. If you're using Claude Code,AGENTS.md/CLAUDE.mdare also copied in and point at it automatically. - If you selected optional modules, the CLI prints the exact imports and JSX to paste into
app/Provider.tsx— copy that in to wire up each provider. - For each module's full API reference (props, hooks, exports), see that module's page in the
@msflib/react-modulesdocs site — this scaffold just installs them, it doesn't change their API.
Project structure¶
app/ # Next.js App Router — (public), (auth), (protected) route groups
components/ # Global, reusable components (AppButton, AppContainer, ...)
dynamics/ # Client-only components, dynamically imported (FormBuilder, TableWidget, ...)
styles/ # Shared style objects (<name>.styles.ts)
data/ # Shared static/mock data (<entity>.data.ts)
columns/ # All table column definitions (<entity>.column.ts)
api/ # API layer per feature
hooks/ # TanStack Query hooks per feature
types/ # TypeScript types per feature
constant/ # Route constants and other shared constants
context/ # React context providers
theme/ # MUI theme + design tokens
utils/ # Shared utility functions
Route-specific code lives with its route: components in <route>/components/, and forms in <route>/data/form/ (<entity>.form.ts + <entity>.layout.tsx). See docs/IMPLEMENTATION_GUIDE.md in a scaffolded project for the full rationale behind this structure and where new files should go.
Troubleshooting¶
| Symptom | Cause and fix |
|---|---|
Export tenantHookDecorator doesn't exist in target module on pnpm dev |
The app was generated with the old @kodehauz/react-template. Regenerate it with npx @msflib/react-template@latest my-app. |
404 Not Found or 401 Unauthorized when installing @msflib/* |
GitHub Packages isn't configured. Complete step 0 above and check your token has read:packages. |
| npx runs an older template version | npx cached an old copy. Pin the latest with @latest, as in the command above. |