@yugami/interaction
v0.3.3
Published
Create a new Yugami frontend — Next.js 16 + Tailwind v4 + @yugami/ui + RTK Query + Vitest. Single command: pnpm create @yugami/interaction
Maintainers
Readme
yugami-interaction
Create a new Yugami frontend in one command — Next.js 16 + Tailwind v4 +
@yugami/ui-react+ RTK Query + Apollo Client + Zod + Vitest. Opinionated,output: "export"(static) or--ssr(standalone server), BFF auth by default.
# Always use @latest to avoid stale pnpm dlx cache (esp. Windows)
pnpm dlx @yugami/interaction@latest my-app # recommended
npx @yugami/interaction@latest my-app
# With options:
pnpm dlx @yugami/interaction@latest my-app --description "My Yugami portal"
pnpm dlx @yugami/interaction@latest my-app --no-install -y
# SSR mode (route handlers + server components):
pnpm dlx @yugami/interaction@latest my-app --ssr --auth
cd my-app
cp .env.example .env.local # set NEXT_PUBLIC_API_BASE_URL
pnpm dev # http://localhost:3000Published as @yugami/interaction — lives in yugami-packages/packages/interaction and publishes via pnpm --filter @yugami/interaction publish --access public.
What you get
Scaffolded from the real yugami-ai-studio-ui + yugami-identity-ui stacks:
my-app/
├── app/ # Next.js App Router — ultra-thin pages
│ ├── (dashboard)/ # authenticated routes
│ │ ├── layout.tsx # SidebarProvider
│ │ ├── page.tsx # dashboard
│ │ ├── example/page.tsx # example feature (REST + GraphQL)
│ │ └── settings/page.tsx # settings
│ ├── auth/page.tsx # BFF login redirect
│ ├── globals.css # Tailwind v4 + @source + theme vars
│ ├── layout.tsx # fonts + Providers
│ └── provider.tsx # Redux → Apollo → Tooltip → Toaster
├── containers/ # ALL business logic
│ ├── layout/AppSidebar.tsx
│ ├── dashboard/index.tsx
│ ├── example/ # REST (RTK) + GraphQL (Apollo) tabs
│ ├── settings/SettingsComponent.tsx
│ └── shared/ConfirmDialog.tsx
├── hooks/use-yugami-form.ts # react-hook-form + zodResolver
├── store/ # Redux + RTK Query + Apollo Client
│ ├── config.ts # typed accessor → project-config.json
│ ├── api.ts # base createApi (single-flight 401)
│ ├── graphql.ts # global ApolloClient (mirror headers)
│ ├── index.ts
│ └── hooks.ts
├── project-config.json # project identity (appName/title/description/version)
├── scripts/lighthouse.mjs # Lighthouse perf check (pnpm perf / perf:build)
├── mocks/ # MSW (dev-only, NODE_ENV guard)
│ ├── db.ts, rest.ts, graphql.ts
│ ├── handlers.ts, browser.ts, server.ts
├── tests/ # Vitest — mirrors containers/ & store/
│ ├── setup.ts, vitest-setup.ts
│ ├── __mocks__/example.ts
│ ├── app/dashboard.test.tsx
│ └── containers/example/...
├── vitest.config.ts # 70% coverage gate
├── vitest-setup.ts # jest-dom + next/navigation mock
├── next.config.ts # output: "export" (static) or "standalone" (--ssr)
├── .env.example
├── .prettierrc
├── .husky/pre-push # lint → typecheck → test
├── CONSTITUTION.md # binding conventions
└── CHANGELOG.md
## SSR mode (--ssr)
Scaffold with `--ssr` to enable Next.js as a Node.js server (`output: "standalone"`):
```bash
pnpm dlx @yugami/interaction@latest my-app --ssrUnlocks:
- Route handlers —
app/api/*/route.tsrun server-side - Server components — fetch data directly from DB/internal APIs
- Server-only code —
lib/server-only/guarded byimport "server-only" - Docker-friendly —
.next/standalone/for small container images
When combined with --auth, route handlers can verify access tokens via
@yugami/identity-client's createJwksTokenValidator (JWKS). The browser
uses createYugamiClient (PKCE) for the OAuth flow — same library, two
runtimes.
Use
--ssrfor admin panels, BFFs, or any app that needs server-side logic. Default (no--ssr) is the standard Yugami static export — preferred for CDN-deployed customer-facing UIs.
## Stack
| Concern | Choice |
| -------------- | -------------------------------------------------------------------------- |
| Framework | Next.js 16 App Router — `output: \"export\"` (static) or `--ssr` (standalone) |
| UI | React 19 + `@yugami/ui-react` (65+ comps) + `@yugami/ui-icons` |
| Styling | Tailwind v4 (`@source` → ui-react dist) |
| Server state | RTK Query (`store/api.ts` + `injectEndpoints`) + Apollo Client (`store/graphql.ts`) |
| Client state | Redux Toolkit (`store/index.ts`) |
| Forms | React Hook Form + Zod + `@hookform/resolvers` |
| Testing | Vitest 4 + Testing Library + jsdom + MSW 2 (dev-only) |
| Linting | ESLint 9 + `eslint-config-next` |
| Type checking | TypeScript 5.9 (`tsc --noEmit`) |
| Auth | BFF (cookie-based, `credentials: "include"`) — optional `redirect` mode |
| CI | Husky pre-push: lint → typecheck → test-coverage |
## Scripts
```bash
pnpm dev # Next dev
pnpm build # Next build (static: out/ · SSR: .next/standalone/)
pnpm lint # eslint
pnpm typecheck # tsc --noEmit
pnpm test # lint + vitest run --coverage
pnpm test:watch # vitest
pnpm test:coverage# vitest run --coverage
pnpm perf # Lighthouse audit of dev server (reports/lighthouse/)
pnpm perf:build # Lighthouse audit of production build (out/ or .next/)
## Environment
```bash
# .env.local
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000/api/v1Mocking is controlled by project-config.json → useMock (ON by default in dev,
so the scaffold runs without a backend — no .env.local required).
Conventions (from CONSTITUTION.md)
app/pages are max 2 lines — re-export fromcontainers/.containers/<feature>/owns*.api.ts(injectEndpoints),*.model.ts(typed GraphQL ops),Component.tsx,index.tsx.store/api.tsdeclarestagTypes; features inject endpoints.store/graphql.tsis the global Apollo client — features use hooks, never create their own client.- Forms use
useYugamiForm(Zod). - Auth is opt-in:
--auth --auth-mode=pkce|redirect.pkce= standalone UI app via@yugami/identity-client(public client, no secret, tokens in sessionStorage);redirect= shared.yugami.incookie via Identity. BFF is a valid pattern when business requirements call for it. output: "export"(static) oroutput: "standalone"(SSR) — with--ssr, route handlers + server components ARE available. Without--ssr, no server runtime, no[param]segments, use?id=query params.- REST and GraphQL co-exist — pick one per feature, never mix in one file. Both are always available (see
containers/example/). - MSW is dev-only — guarded by
NODE_ENV === "development"— dead-code eliminated in production builds.
See CONSTITUTION.md in the generated app for the full binding conventions.
Publishing
pnpm --filter @yugami/interaction publish --access publicLicense
Proprietary — see LICENSE file.
