Editing by hand
PortalJS is AI-native, not AI-only. Every skill emits plain, editable code — so anything a skill does, you can also do by hand, and you can skip the agent entirely if you prefer. This page is the reference for working on the project directly.
Prerequisites
- Node.js >= 22
- Familiarity with Next.js and Tailwind helps, but isn't required.
1. Get the template
Scaffold the canonical catalog template with the create-portaljs CLI — it copies the
template, substitutes your project name, and sets the namespace mode:
npm create portaljs@latest my-portal
cd my-portal
npm install # (the CLI offers to do this for you)
npm run dev
Open http://localhost:3000. You now have a running portal —
a home page (/), a search catalog at /search, and per-dataset showcase pages — with
a few sample datasets.
Bare copy, no prompts
To grab just the files with no scaffolding prompts, use
tiged (a maintaineddegitfork that reliably
extracts the subdirectory):npx tiged datopian/portaljs/examples/portaljs-catalog my-portal.
Just a landing page?
If you only want a single home page with no catalog or dataset pages, use the
minimal variantexamples/portaljs-templateinstead and build up from there. See
Templates.
2. Add a dataset
Datasets are driven by a datasets.json manifest — there's no per-dataset page file
to write. Drop your file into /public/data/:
cp ~/Downloads/population.csv public/data/population.csv
Then append an entry to datasets.json:
{
"slug": "population",
"name": "Population by area",
"description": "Resident population by area.",
"file": "population.csv",
"format": "csv",
"namespace": "reference"
}
That's it — the dataset now renders at /@reference/population through the
existing pages/[owner]/[slug].tsx showcase route, and shows up in the /search
catalog. The showcase previews the file with the Table component (in
components/Table.tsx), which fetches the CSV in the browser with papaparse and
renders it with @tanstack/react-table — no server code needed, since Next.js serves
/public/ statically.
Every dataset carries a namespace. A portal uses one namespace mode —
theme (group by subject) or owner (group by publisher) — set via NAMESPACE_TYPE
in lib/datasets.ts. It only changes the showcase's metadata label; the URL is always
/@<namespace>/<slug>. See Core concepts for why dataset URLs
start with @.
3. Add charts, maps, and backends
Everything the skills do, you can do by hand:
- Charts —
npm install rechartsand add a chart as a view in the dataset's showcase (pages/[owner]/[slug].tsx). - Maps —
npm install react-leaflet leafletand render a GeoJSON file as a view in the showcase. - CKAN — build a catalog against the CKAN REST API with a tiny server-side
fetchclient (no dependency);/portaljs-connect-ckangenerates it for you. See CKAN integration.
For the conventions these follow — import paths, data loading, page structure —
read the CLAUDE.md
development guide in the repo.
4. Deploy
The template is a standard Next.js app. Deploy it to Vercel:
npx vercel
…or export a static build (next build) and host the out/ directory anywhere.
Where to go next
- Core concepts — the ideas behind the template and the skills.
- Quickstart — let the skills do the typing.