Skip to content

datopian/portaljs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3,203 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PortalJS

PortalJS

The AI-native framework for building data portals.
Describe the portal you want β€” your agent helps you choose an architecture, scaffolds it, and loads your data.

Docs Β· Discussions Β· Report a bug

Join our Discord server MIT License


Quickstart

Build one with your AI assistant β€” the recommended path. Install the skills once, then create portals from any directory (not inside this repo):

# 1. Install the PortalJS skills (once) β€” into ~/.claude/commands
curl -fsSL https://raw.githubusercontent.com/datopian/portaljs/main/scripts/install-portaljs-skills.sh | bash

Then, from a fresh working directory, in a Claude Code session:

/new-portal   "Auckland Council open data portal"
/add-dataset  ./data/air-quality.csv

/new-portal fetches the latest template and scaffolds the three surfaces; /add-dataset loads your data; /architect picks an architecture first if you're unsure; /connect-ckan points it at a CKAN backend. (Install details + all skills β†’)

Or build by hand β€” plain Next.js, no AI, no lock-in:

npx tiged datopian/portaljs/examples/portaljs-catalog my-portal
cd my-portal && npm install && npm run dev      # β†’ http://localhost:3000

You get Home, a Catalog (/search), and a dataset Showcase (/@<namespace>/<slug>) over sample data. Add your own CSV/JSON to datasets.json and it renders automatically.

⭐ If it's useful, a star helps others find it.

Why PortalJS

Building a data portal has always meant more than a website. You have to decide where the data lives, how it's versioned, how people search it, how it's served, and how it's governed β€” and then wire a frontend on top. Teams either over-build on a heavy data warehouse they don't need, or under-build on a pile of scripts that doesn't scale.

PortalJS is an open-source, agentic skills framework that helps data teams build, develop, and ship data portals β€” and the data infrastructure underneath them. It isn't only a frontend. The skills do two jobs:

  • Advise β€” given what you're building, what your data is, and what it's for, they recommend an architecture: storage, compute, catalog, access, hosting, metadata.
  • Build β€” they scaffold that stack as plain, editable Next.js code with no lock-in.

It is opinionated but open: the recommended modern path is git + object storage (Cloudflare R2) + Parquet + DuckLake + DuckDB β€” an open lakehouse instead of a classic warehouse β€” but a traditional datastore (CKAN, a warehouse) stays a first-class option when you need it. You always own plain code.

Built and maintained in the open by Datopian and the PortalJS community.

Architecture at a glance

        πŸ§‘  you describe what you want to build
        β”‚
        β–Ό
╭─ πŸ€–  AGENTIC SKILLS ──────────────────────────────────  decide + build
β”‚   /architect Β· /new-portal Β· /add-dataset Β· /add-chart Β· /add-map …
╰─  generates plain, editable Next.js code β€” no lock-in
        β”‚
        β–Ό
╭─ πŸ–₯️  SURFACES ────────────────────────────────────────  what users see
β”‚   🏠 Home /      πŸ”Ž Catalog /search      πŸ“Š Showcase /@ns/slug
╰─  read data through one DataProvider contract
        β”‚
        β–Ό
╭─ πŸ”Œ  PROVIDERS ───────────────────────────────────────  pluggable backends
β”‚   πŸ“ staticΒ·git     🐘 CKAN     πŸ”­ OpenMetadata     πŸ—‚οΈ git-LFS + R2
╰─  swap the source without touching a page
        β”‚
        β–Ό
πŸ“¦  STORAGE + COMPUTE  β€”  choose your point on the spectrum:

      flat files  ─▢  Git-LFS + R2  ─▢  Parquet + DuckLake + πŸ¦† DuckDB  ─▢  warehouse / CKAN
      simplest                          ⭐ open lakehouse (default)            heaviest

☁️  Substrate  β€”  Cloudflare R2 (storage) Β· Workers (runtime) Β· D1 (catalog) Β· Pages (static)
     object storage stays S3-compatible β€” R2 is the default, never a lock-in

Three surfaces. Every data portal is built from three: a Home page that explains it and offers search, a Catalog (/search) to discover datasets, and a Showcase (/@<namespace>/<slug>) to explore one dataset β€” metadata, preview, download/API, and charts/maps. (Core concepts β†’)

One seam. The surfaces read data only through a DataProvider, so the source β€” static files today, a CKAN or lakehouse backend tomorrow β€” can change without touching a page.

See ROADMAP.md for the full model and the architecture decision framework for how /architect turns your needs into a stack.

Build a portal with your AI assistant

PortalJS ships Claude Code skills that turn a brief into a working portal.

Setup

The skills live in this repo under .claude/commands/. The quickest way to try them is from a clone:

git clone https://github.com/datopian/portaljs
cd portaljs
claude

Claude Code auto-discovers the slash commands from .claude/commands/ β€” no install step. Type / in the session to see them.

Install anywhere: the skills and template are also packaged as a Claude Code plugin and can be installed into ~/.claude/commands/ so you can run them from any project. See .claude/INSTALL.md.

Use

If you're not sure how to set up your portal, start with the advisor, then build:

/architect    we have ~200 public CSVs, updated quarterly, and must publish DCAT-AP
/new-portal   "Auckland Council open data portal"
/add-dataset  ./data/air-quality.csv
/add-dataset  https://example.com/parks.geojson

The skills are interactive β€” if your brief is thin, they interview you in short rounds rather than erroring. /architect recommends a stack and hands off; /new-portal scaffolds the three surfaces; /add-dataset appends to the datasets.json manifest and the showcase renders automatically at /@<namespace>/<slug>. Run npm run dev and you have a portal.

Prefer to build by hand? Clone the canonical template β€” the skills are a convenience, not a requirement:

npx tiged datopian/portaljs/examples/portaljs-catalog my-portal

Available skills

Skill What it does
/architect Recommend an architecture (storage/compute/catalog/access/hosting/metadata) from your needs, then hand off β€” the advisory entry point
/new-portal Scaffold a new portal (Home + Catalog + Showcase) from a brief
/add-dataset Add a CSV, TSV, JSON, or GeoJSON dataset β€” appends to the manifest; its showcase renders automatically
/add-chart Add a chart to a dataset's showcase Views section
/add-map Render GeoJSON on an interactive map in the showcase
/connect-ckan Feed the catalog and showcases from a CKAN backend
/deploy Deploy to Cloudflare Pages, Vercel, or static hosting
/check-data-quality Audit a dataset for quality issues (schema, nulls, types)

More skill families β€” metadata schemas (Frictionless/DCAT), more backends (OpenMetadata, git-LFS+R2), a DuckDB data layer, and access control β€” are on the roadmap. Write your own β€” see .claude/AUTHORING.md.

What's in this repo

.claude/commands/    the agentic skills (slash commands)
examples/            reference portals β€” portaljs-catalog is the canonical template
packages/
  core/              layout/UI components            (@portaljs/core)
  ckan/              CKAN catalog UI + React          (@portaljs/ckan)
  ckan-api-client-js/ pure CKAN API client            (@portaljs/ckan-api-client-js)
site/                portaljs.com β€” the marketing site + docs
ROADMAP.md           direction, the four contracts, sequencing

The canonical template, examples/portaljs-catalog, is where the three surfaces and the DataProvider seam live β€” read it before building.

What makes it different

  • 🌱 Open source, MIT, no lock-in β€” every skill emits plain Next.js you can fork and own.
  • 🧭 Advisory, not just generative β€” /architect helps you decide the infrastructure, not only scaffold a UI.
  • πŸ¦† Open lakehouse by default β€” git + R2 + Parquet + DuckLake + DuckDB over a heavy warehouse, with DuckDB as the query engine. A datastore/warehouse stays a supported choice.
  • ☁️ Cloudflare-first, portable β€” R2 / Workers / D1 / Pages as the default substrate, but object storage stays S3-compatible.
  • 🧩 Decoupled, any backend β€” one DataProvider contract in front of CKAN, DKAN, OpenMetadata, DataHub, GitHub, Frictionless, plain files β€” or your own.
  • 🎨 Bring your own stack β€” adopt the template or lift the skills and the three-surface model into an app you already have.

Examples

Reference implementations live in examples/:

Example Backend
portaljs-catalog Canonical template β€” Home + Catalog + Showcase over a static manifest
portaljs-template Minimal single-page starter
ckan Β· ckan-ssg CKAN
github-backed-catalog GitHub
dataset-frictionless Frictionless Data Package
fivethirtyeight Β· openspending Β· turing Real-world portals

Community & support

Contributing

PortalJS is built in the open and we welcome contributions of all sizes β€” new skills, examples, docs, and fixes. See CONTRIBUTING.md to get started, and read ROADMAP.md and VISION.md for where the project is headed.

License

MIT Β© Datopian