Inside Prism v2: A Closed PR Queue, A 2.0.0-alpha.1 Manifest, And Seven Exports Subpaths
Lightweight, robust, elegant syntax highlighting.
At a glance
- What is it?
- Prism is a browser syntax highlighting library and a spin-off from Dabblet, now on a v2 default branch whose manifest reads 2.0.0-alpha.1. Only security relevant pull requests are being accepted, the contributing notes rule out npm install, and the exports map is the API contract.
- Who is it for?
- Prism suits teams that want readable, editable grammars in the browser, but treat the v2 line as unstable and the 1.x line as settled. Before committing, check that the language you need is registered in components.json, confirm your bundler only asks for the subpaths the exports map lists, and do not plan around upstream pull requests landing while only security relevant ones are accepted.
- 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 1 day ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- PrismJS/prism13,068 ★ · +26
| Repository | 2026-09-22 | 2026-11-14 |
|---|---|---|
| PrismJS/prism | 13k | 13.1k |
26 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
prism.js is generated, so patching it accomplishes nothing
Start with the rule that surprises newcomers: prism.js is not a source file. It is the version of Prism that the Prism website itself uses, and it is built automatically. The Prism v1 contributing notes go further and tell you to limit changes to the unminified files in the components/ folder, because prism.js and every minified file are produced by the build system. The top-level entries back this up: the root holds .editorconfig, .jsdoc.json, CHANGELOG.md, MAINTAINERS.md, SECURITY.md, CNAME, _headers, benchmark/, composer.json, package-lock.json, scripts/, src/, tests/, and tsconfig.json, with no hand-edited bundle among them. What a contributor cannot do is fix a bug by editing prism.js and expect the change to survive. The consequence is concrete. The next build overwrites it, and a reviewer looking only at the generated file sees no intent, so the real edit has to live in components/ and pass through the build.
Only security relevant pull requests get merged until v2 is further along
The first fact to know about contributing is that the door is nearly shut. The project states it is currently working on Prism v2 and will only accept security relevant PRs for the time being. Pull requests will be accepted again once work on v2 is sufficiently advanced, and that reopening gets announced on the Discussions page and mentioned in the roadmap discussion. The default branch reflects the same shift: it is v2. For anyone evaluating the project, the meaning is precise. A new language definition, a new plugin, or a refactor of the core cannot land upstream right now, and a pull request that is not security relevant will sit unmerged no matter how small it is. Consequence: a grammar you need upstream has no current path, so plan to own it yourself, and do not assume a queued contribution will be in your release.
The 1.x line stopped at v1.30.0 while the manifest reads 2.0.0-alpha.1
Two version lines have to be held at once. The tagged releases are v1.30.0 dated 2025-03-10, v1.29.0 dated 2022-08-23, and v1.28.0 dated 2022-04-17, which leaves a gap of more than two and a half years between v1.29.0 and v1.30.0. The manifest on the v2 branch carries a different number entirely: version 2.0.0-alpha.1. An alpha marker says the module shape can still change, and nothing in the tree promises otherwise. The repository is not archived and its last push is dated 2026-10-15, so the branch itself is moving while the published 1.x line is not. What a reader cannot do is assume the default branch and the version npm hands you are the same thing. Consequence: they are two different stories, and an alpha should be read as an unsettled API rather than a preview of a finished one.
npm ci, not npm install, or minified output stops being comparable
The build instructions are unusually specific about the install step. You are told to use npm ci and not npm install, because npm install causes non deterministic builds. With dependencies present you run one command, npm run build, which the manifest defines as node scripts/build.js and wires into prepack so a publish triggers the same work. The contributing notes describe gulp as the tool that minifies the files and builds prism.js, and the manifest carries a separate benchmark script running node benchmark/benchmark.js. What a contributor cannot do is treat npm install as an equivalent shortcut. Consequence: a local minified file that differs from the committed one becomes unreadable as a change, because the diff no longer tells you whether the difference came from your edit or from dependency resolution. package-lock.json sits at the root, so the fix is available if you follow the instruction before you build.
The Node floor is stated twice and the two numbers disagree
Contributing needs software, and the Prism v1 contributing notes state Node.js >= 10.x together with npm >= 6.x. The manifest says something stricter: engines declares node >= 18. Those two numbers do not agree, and a reader has to decide which governs. The separate claim that Prism will run on almost any browser and Node.js version describes consuming the library, not building it, so it does not settle the conflict for a contributor. What the project cannot do is offer one authoritative floor while both numbers stand. Consequence: someone on Node 16 satisfies the contributing notes, writes a grammar, and then meets the engine requirement at install time, which is the expensive way to find out. Read the engines field against your actual version before planning any contribution.
A language missing from components.json never reaches the download page
Registering a language is a three step obligation, and skipping the first step still produces output that looks fine locally. Add the new language definition or plugin to components.json, rebuild by running npm run build, and only then does it become available on the download build page. New languages also need tests and an example in the examples/ folder. A second clause reaches further: if you contribute a new language definition, you are responsible for handling bug reports about that language definition. What an author cannot do is register a grammar privately and expect users to find it. Consequence: a grammar that never reaches components.json is invisible to everyone building from the download page, and once it is registered you have taken on its bug reports, a commitment the review guidance does nothing to reduce.
The exports map is the whole API surface, and it is a short list
The exports field is the clearest statement of what v2 is meant to be, and it is worth reading line by line. The root subpath exposes types at ./types/index.d.ts, import at ./dist/index.js, and require at ./dist/cjs/index.js, so an ES module import and a CommonJS require resolve to different files with the same declared types. Beside it sit ./shared.js, a wildcard for ./languages/*.js, a wildcard for ./plugins/*.js, and three more subpaths: ./plugins/*.css, ./themes/*.css, and ./components.json. Language types resolve to ./types/languages/*.d.ts while plugin types resolve to the nested ./types/plugins/*/*.d.ts. The package is type module and declares its stylesheet as dist/themes/prism.css. What a consumer cannot do is deep import a file outside those patterns. Consequence: a path that resolves on disk can still be refused by Node's exports resolution, so this list is the contract, not a suggestion.
Themes live in a different repository than languages do
One split is easy to miss when planning a site. New language definitions and plugins stay in this repository, but the contributing notes route themes somewhere else entirely: go to prism-themes if you want to add a new theme, and the root page for more themes points at that same project. The package itself still exports ./themes/*.css and declares dist/themes/prism.css as its stylesheet, so some themes ship here while new ones go to prism-themes. Consequence for a site shipping Prism: a theme from prism-themes and your grammar come from two sources, and the theme you pinned may not match the markup a newer language definition produces.
Editorial conclusion
Prism suits teams that want readable, editable grammars in the browser, but treat the v2 line as unstable and the 1.x line as settled. Before committing, check that the language you need is registered in components.json, confirm your bundler only asks for the subpaths the exports map lists, and do not plan around upstream pull requests landing while only security relevant ones are accepted.
Frequently asked questions
What is prism software used for?
Prism is a syntax highlighting library for the browser, and a spin-off project from Dabblet. Its own site is prismjs.com, and the documentation for extending it, including how to create a new language definition, is published on the same domain.
Is prism free to use?
The repository carries an MIT LICENSE file at its root, and the package is published on npm under the name prismjs. The project README states no separate licensing terms beyond that, so the LICENSE file is the place to read the actual grant.
How can I use prism?
Prism will run on almost any browser and Node.js version. There is a download build page on the project site for picking languages, and the extending documentation covers creating a new language definition and adding it to components.json.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/prismjs-prism)Star history chart for your README
[](https://hysenlabs.com/projects/prismjs-prism)Was this useful?