PortalJS: an agentic skills framework that scaffolds Next.js data portals
🌀 AI-native framework for building data portals. Scaffold a full portal from a brief and load datasets in minutes with agentic skills — any backend (CKAN, GitHub, Frictionless).
At a glance
- What is it?
- PortalJS pairs Claude Code skills with a three-surface Next.js template and a swappable DataProvider seam, letting a brief become a running catalog. It is opinionated about the default stack and thin on hosted-backend detail.
- Who is it for?
- Adopt PortalJS if your team already runs Claude Code and wants a Next.js portal over files, R2 or CKAN without hand-wiring a catalog. Skip it if you need a non-Claude agent path, a fully documented provider contract, or a hosted portal today, since the README shows only static and CKAN examples end to end.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem PortalJS targets: a portal is a stack decision, not a page
The README frames the difficulty plainly: building a data portal means deciding where data lives, how it is versioned, how people search it, how it is served and how it is governed, then wiring a frontend on top. The stated failure modes are over-building on a warehouse that is not needed, or under-building on scripts that do not scale. PortalJS answers both by shipping an opinionated default (git plus object storage plus Parquet, queried with DuckDB) while keeping the frontend as plain, editable Next.js. The audience is data teams, not frontend specialists: the skills are expected to advise on architecture from a brief and then generate the code. If you already have a catalog backend and only need a theme, this is more machinery than the job requires.
Three surfaces, one DataProvider seam
Every portal the framework produces is built from the same three surfaces: a Home page that explains the portal and offers search, a Catalog at /search for discovery, and a Showcase at /@<namespace>/<slug> for a single dataset, holding metadata, preview, download or API access, and charts or maps. The architectural claim is that these surfaces read data only through a DataProvider, so the source can change without touching a page. That seam is the part worth inspecting first in any generated project, because it is what determines how much work a backend swap actually costs. The README lists static and git, CKAN, OpenMetadata, and git-LFS with R2 as provider options, but it does not document the interface itself, so the shape of the contract has to be read from the generated code.
How the skills decide and build
The agentic layer is a set of Claude Code skills, installed once into the personal scope so they are available from any directory. The README names five: /portaljs-architect for stack selection, /portaljs-new-portal to scaffold the three surfaces, /portaljs-add-dataset and /portaljs-add-resource to load data, /portaljs-connect-ckan to point the portal at a CKAN backend, and /portaljs-deploy to ship it. The split of labour is explicit: the architect skill turns what you are building, what your data is and what it is for into a recommendation covering storage, compute, catalog, access, hosting and metadata, and the build skills emit plain Next.js. Because the output is ordinary code rather than a runtime you depend on, the skills are a starting point you can discard. That is the strongest design decision in the repository, and it is also why the skills' quality matters less than the code they leave behind.
Getting a portal running: two commands and a datasets file
The documented quickstart needs Node 22 or later and nothing else. Run npm create portaljs@latest my-portal, then cd my-portal and npm run dev, which serves on http://localhost:3000 over sample data. To add your own data, the README says to put CSV or JSON into datasets.json and it renders automatically. If you would rather skip the AI layer, the bare template is fetched with npx tiged datopian/portaljs/examples/portaljs-catalog my-portal, followed by npm install and npm run dev, and it produces the same three surfaces. The skill route starts with a curl command that pipes scripts/install-portaljs-skills.sh from the repository's main branch into bash, after which you restart Claude Code and invoke the slash commands. That install script is fetched from main rather than a tagged release, which is worth noting if you pin dependencies elsewhere.
Where the storage spectrum actually lands
The README presents storage and compute as a spectrum rather than a single answer: flat files at the simplest end, then git-LFS with R2, then Parquet on R2 queried with DuckDB, then a warehouse or CKAN at the heaviest. The default recommendation sits at the Parquet-on-R2 point, described as an open lakehouse, with DuckLake suggested for living, incremental tables. The substrate named underneath is Cloudflare's: R2 for storage, Workers for runtime, D1 for the catalog and Pages for static hosting, with the explicit caveat that object storage stays S3-compatible and R2 is a default rather than a lock-in. The trade-off is that the default path assumes you are willing to run a lakehouse-style setup and accept Cloudflare as the deployment target; the README does not describe an equivalent default for teams already committed to a different cloud.
Limitations the material makes visible
The agentic path is Claude Code specific. The install script places commands in ~/.claude/commands, and the README mentions a versioned plugin or running from a clone as alternatives, but no other agent host appears. If your team does not use Claude Code, the value proposition narrows to the bare Next.js template. The provider story is also unevenly documented: CKAN gets a dedicated skill and a named provider, OpenMetadata is listed in the architecture diagram, and Socrata, DKAN, Dataverse, OpenDataSoft and DataHub appear only as repository topics, with no described integration in the README text. Treat the topic list as a signpost, not a support matrix. Finally, the README is truncated in the supplied material, so the sections on charts, maps and deployment are only visible as skill names; anything about their behaviour would be guesswork.
Compared with a plain Next.js catalog template
The obvious alternative is the bare template the project itself ships, fetched with npx tiged datopian/portaljs/examples/portaljs-catalog. The difference is not the output, since both routes produce Home, /search and /@<namespace>/<slug> over sample data. The difference is where the decisions happen. The bare template leaves architecture, dataset loading and backend wiring to you, with datasets.json as the only documented entry point for data. The skills route moves those decisions into a conversation and emits the code afterwards, which helps when the stack choice is genuinely open and hurts when you already know the answer, because you pay for an agent session to reach the same scaffold. Neither route hides a runtime: both end in editable Next.js files that you own.
Maintenance, licensing and what to verify
PortalJS is MIT licensed, which permits commercial use and modification, though the repository also ships a license file referenced by the badge; read that file rather than relying on the badge text, and take legal advice if your organisation restricts attribution or redistribution terms. The release cadence visible in the material is concentrated on the create-portaljs package, with 0.4.0 and 0.5.0 landing on the same day in June 2026 and 0.6.0 following a few days later, which suggests the scaffolder is moving faster than any documented provider contract. Since the skills install from the main branch, an upgrade can change your tooling without a version bump you chose. Verify three things before adopting: the generated DataProvider interface, whether the CKAN provider maps your instance's fields, and whether the install script can be pinned to a tag in your environment.
Editorial conclusion
Adopt PortalJS if your team already runs Claude Code and wants a Next.js portal over files, R2 or CKAN without hand-wiring a catalog. Skip it if you need a non-Claude agent path, a fully documented provider contract, or a hosted portal today, since the README shows only static and CKAN examples end to end. Before committing, run npm create portaljs@latest and read the generated DataProvider interface, then confirm the CKAN provider's field mapping against your own instance.
Community notes