Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 37 additions & 5 deletions commands/new-tool.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: Scaffold a new PolicyEngine interactive tool (Next.js 14 + Tailwind 4 + ui-kit theme + embedding boilerplate)
description: Scaffold a new PolicyEngine interactive tool (Next.js 16.2 + React 19.2 + Tailwind 4.2 + ui-kit theme + embedding boilerplate)
---

# New interactive tool scaffold
Expand All @@ -20,13 +20,16 @@ Ask the user for:
## Step 2: Create the project

```bash
# Create Next.js 14 + Tailwind project
bunx create-next-app@14 TOOL_NAME --js --app --tailwind --eslint --no-src-dir --import-alias "@/*"
# Create Next.js 16.2 + Tailwind project
bunx create-next-app@latest TOOL_NAME --js --app --tailwind --eslint --no-src-dir --import-alias "@/*"
cd TOOL_NAME

# Install dependencies
bun add @policyengine/ui-kit recharts
# Install dependencies matching canonical stack
bun add @policyengine/ui-kit@^0.9 recharts
bun add -D vitest

# Ensure React 19.2 and Next 16.2 are installed
bun add next@^16.2 react@^19.2 react-dom@^19.2
```

Copy the favicon:
Expand All @@ -40,6 +43,35 @@ If using code highlighting:
bun add prism-react-renderer
```

Configure ESLint with native flat config (Next 16 removed `next lint` support):
```bash
bun add -D eslint @next/eslint-plugin-next eslint-config-prettier
```

Create `eslint.config.mjs`:
```js
import nextPlugin from "@next/eslint-plugin-next";

export default [
{
plugins: { "@next/next": nextPlugin },
rules: {
...nextPlugin.configs.recommended.rules,
...nextPlugin.configs["core-web-vitals"].rules,
},
},
];
```

Add to `package.json` scripts:
```json
{
"scripts": {
"lint": "eslint ."
}
}
```

## Step 3: Generate project files

Create the following files with the content specified below. Replace `TOOL_NAME`, `TOOL_TITLE`, `DESCRIPTION`, and `COUNTRY_ID` with actual values.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,21 @@ How to build standalone React apps (calculators, dashboards, visualizations) tha

## Stack

**Next.js 14 + Tailwind 4 + Recharts** for all tools (embeddable and standalone).
**PolicyEngine canonical stack** (as of 2025):
- **Next.js 16.2+** (App Router)
- **React 19.2+**
- **Tailwind CSS 4.2+** with `@policyengine/ui-kit` theme
- **Recharts** for charts

| Component | Choice |
|-----------|--------|
| Framework | Next.js 14 (App Router) |
| CSS | Tailwind 4 with `@policyengine/ui-kit` theme |
| Framework | Next.js ^16.2 (App Router) |
| React | React ^19.2 |
| CSS | Tailwind CSS ^4.2 with `@policyengine/ui-kit ^0.9` theme |
| Charts | Recharts |
| Code highlighting | Prism React Renderer |
| Testing | Vitest |
| Linting | ESLint with native flat config (eslint.config.mjs) |
| Deploy | Vercel under `policy-engine` scope |
| Package manager | `bun` (not npm) |

Expand Down Expand Up @@ -690,9 +696,10 @@ Test API responses against Python fixtures for numerical accuracy. See `PolicyEn

## Checklist for new tools

- [ ] Next.js 14 + Tailwind 4 scaffold
- [ ] `@policyengine/ui-kit` installed (`bun add @policyengine/ui-kit`)
- [ ] Next.js ^16.2 + React ^19.2 + Tailwind CSS ^4.2 scaffold
- [ ] `@policyengine/ui-kit ^0.9` installed (`bun add @policyengine/ui-kit`)
- [ ] `@import "@policyengine/ui-kit/theme.css"` in `globals.css`
- [ ] ESLint with native flat config (`eslint.config.mjs`, NOT FlatCompat)
- [ ] Inter font loaded via Google Fonts CDN
- [ ] **Use Tailwind classes from ui-kit theme** — no hardcoded hex colors
- [ ] **Zero hardcoded font names** — all fonts via `var(--font-sans)`
Expand Down