An interactive explorer for the United Nations System, making all UN entities, their leadership, and resources easily discoverable.
This project provides a visual, searchable interface to navigate the UN System Chart. Users can explore entities by principal organ, search by name, and access comprehensive information about each organization.
- Interactive Filtering: Filter entities by UN Principal Organ (General Assembly, Security Council, etc.)
- Full-Text Search: Search across entity name and aliases
- Detailed Entity Cards: View descriptions, leadership, mandates, and organizational links
- Responsive Design: Optimized for desktop, tablet, and mobile devices
- Static Site: Deployed to GitHub Pages for fast, reliable access
- https://www.un.org/delegate/page/un-system-chart
- https://www.un.org/un80-initiative/shifting-paradigms-1
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, output: "export") |
| Language | TypeScript 5, React 19 |
| Styling | Tailwind CSS v4 |
| UI primitives | shadcn/ui (Radix UI) |
| Icons | lucide-react |
| Font | Roboto (via next/font/google) |
| Package manager | pnpm (workspaces) |
| Data source | Airtable API |
| Data pipeline | Python (uv) — pandas, python-dotenv |
| Deployment | GitHub Pages (static) |
├── src/
│ ├── app/ # Next.js app router pages
│ ├── components/ # React components
│ │ └── ui/ # shadcn/ui base components (don't edit directly)
│ ├── lib/
│ │ ├── constants.ts # All configuration and settings
│ │ ├── entities.ts # Entity data loading and filtering
│ │ └── utils.ts # Helper functions
│ └── types/
│ └── entity.ts # TypeScript type definitions
├── public/
│ ├── un-entities.json # Processed entity data
│ └── images/ # Logos and headshots
├── python/ # Data fetching and processing scripts
├── data/ # Raw and processed data files
└── docs/ # Project documentation
Key Files:
src/lib/constants.ts- All configuration and settingssrc/lib/entities.ts- Entity data loading and filteringsrc/lib/utils.ts- Helper functionssrc/types/entity.ts- TypeScript type definitionssrc/app/globals.css- Global styles and theme colors
- Fetch:
python/01-fetch_from_airtable.pyretrieves entity data from Airtable - Process:
python/02-process_entities_data.pycleans and enriches data → outputspublic/un-entities.json - Load:
src/lib/entities.tsimports JSON at build time (no runtime API calls) - Render: Components consume pre-filtered entity arrays
PostgreSQL ingestion (
04-push_to_postgres.py) has been moved to thedatabasebranch. Themainbranch only handles the website and its data pipeline (Airtable → JSON).
- Global Configuration: All settings centralized in
src/lib/constants.ts - Component Composition: shadcn/ui base components in
components/ui/, custom compositions insrc/components/ - Type Safety: Comprehensive TypeScript types for all entity data
- Static Generation: All pages pre-rendered for optimal performance
- Utility-First: Reusable helper functions in
src/lib/utils.ts
-
Install Dependencies
pnpm install
-
Run Development Server
pnpm dev
The application will be available at
http://localhost:3000. -
Build for Production
pnpm build
Outputs a static export to
out/. Note: the build currently also runs a password-protection step (scripts/encrypt-site.js) for pre-release staging — this will be removed before public launch. -
Type check / Lint / Format
pnpm typecheck pnpm lint pnpm format
Entity data is fetched from Airtable and processed with Python scripts. Never edit public/un-entities.json manually — always regenerate via scripts.
You can run the data update process in VS Code using the built-in task:
- Press
Cmd+Shift+P(Mac) orCtrl+Shift+P(Windows/Linux) - Type "Tasks: Run Task"
- Select "Update Data"
Or run manually:
./update_data.shThis runs scripts 01 and 02 in sequence (Airtable fetch → process → public/un-entities.json).
| Script | Input | Output |
|---|---|---|
01-fetch_from_airtable.py |
Airtable API | data/input/input_entities.csv |
02-process_entities_data.py |
data/input/input_entities.csv |
public/un-entities.json, public/un-entities.csv |
03-download_headshots.py |
entity data | public/images/headshots/ |
Script 03 is optional and runs separately:
uv run python/03-download_headshots.py [--force]- Uses
uvfor package management — never run scripts with plainpython - Run scripts with:
uv run python/<script>.py - Install packages with:
uv add <package>
- Daily Data Fetch: Automated data updates at 00:00 UTC
- Continuous Deploy: Automatic deployment to GitHub Pages on push to main
pnpm lint
pnpm typecheckpnpm outdated
pnpm update
npx shadcn@latest diff # check for shadcn/ui component updatespnpm formatGlobal styles and Tailwind CSS configuration are in src/app/globals.css:
- Custom color palette (UN System colors)
- CSS custom properties for runtime color access
- Animation keyframes
- Global utility styles
We welcome contributions! Please see our Contributing Guide for detailed information on how to get started.
- Package manager: Use
pnpm. Never usenpmoryarn. - Tailwind CSS v4: Use Tailwind utility classes. Custom theme tokens (e.g.,
bg-un-blue) are defined insrc/app/globals.cssunder@theme. - Colors: Always use CSS variable tokens — never hardcode hex values in components.
- Components: Keep
components/ui/files unchanged; compose on top insrc/components/. - Configuration: Add all display/behaviour settings to
src/lib/constants.ts. - Utilities: Place helper functions in
src/lib/utils.ts. - Static-First: No server-side logic. Everything must work as a static export on GitHub Pages.