# ngx-markdown gives Angular templates markdown, maths and diagrams

> ngx-markdown is an Angular library that renders markdown in a template by combining marked for parsing with Prism.js for highlighting, KaTeX for maths, Mermaid for diagrams, an emoji set and Clipboard.js for code blocks. Marked and Prism are installed by you, and every extra plugin is wired through angular.json by hand.

**jfcere/ngx-markdown** — Angular markdown component/directive/pipe/service to parse static, dynamic or remote content to HTML with syntax highlight and more...

- Repository: https://github.com/jfcere/ngx-markdown
- Website: https://jfcere.github.io/ngx-markdown
- Stars: 1,196 · Forks: 184
- Language: TypeScript
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/jfcere-ngx-markdown

## Six libraries behind one Angular component

ngx-markdown is described as an Angular library that combines a set of projects, and the list is the feature list.

Marked does the work of parsing markdown to HTML. Prism.js provides language syntax highlighting. Emoji-Toolkit provides emoji support. KaTeX renders math expressions. Mermaid handles diagrams and chart visualisation. Clipboard.js copies code blocks to the clipboard.

The important design decision is how those pieces relate to the library. Marked and Prism are not bundled. The install instructions ask you to add the library and the marked library to your package.json yourself, and the syntax highlight section is explicitly marked optional, with a note to skip it if you are not planning to use it. So the package is a thin Angular integration layer, and the heavy lifting is done by libraries you choose the versions of.

That has an upside and a downside. The upside is that upgrading marked or Prism is a dependency bump rather than a library migration, and an application that only needs plain markdown with no highlighting ships a smaller bundle. The downside is that the setup is manual, and a lot of the documentation is about files you have to add to angular.json yourself.

The audience is an Angular developer who needs to display markdown inside a template, in a documentation view, in a help screen, or wherever content arrives as markdown rather than as a component. The project publishes to npm as ngx-markdown, hosts a live demo, and provides a StackBlitz for trying it without a local setup, and the author is Jean-Francois Cere.

## marked is a dependency you install yourself

The installation section is short, and the version constraint is worth copying exactly rather than approximating.

```bash
npm install ngx-markdown marked@^18.0.0 --save
```

The caret on the major version of marked is the important part, since it tells you which generation of the parser the library was built against. The npm package is ngx-markdown, and the library version in the manifest is 22.1.0 with a MIT licence.

What the library gives you on top of marked is the Angular surface: a component and a directive you can drop into a template, a pipe and a service, as the repository description puts it, a component/directive/pipe/service to parse static, dynamic or remote content to HTML with syntax highlight and more.

The three input modes matter, because they correspond to three different problems. Static content is written inline in the template through transclusion, which is the case where the markdown is part of the source. Dynamic content is bound through the data property, which is the case where you have the string in a component field. Remote content is loaded from a path through the src property, which is the case where the markdown lives in a file that is fetched.

That last mode is the one with consequences. A src bound to a remote document means the application fetches markdown and renders it, which is a common requirement for documentation pages and a common source of trouble, because the content then originates outside your codebase.

## Prism is wired in by hand, and each plugin adds two more files

The syntax highlight section is the longest part of the documentation, and the reason is that there is no bundler magic: Prism works by having its core script and its language definitions loaded as separate files, and the application has to include them.

Prism itself is installed as an optional dependency:

```bash
npm install prismjs@^1.30.0 --save
```

Then three kinds of file have to be added to the application: the Prism core library at node_modules/prismjs/prism.js, a highlight CSS theme from the node_modules/prismjs/themes directory, and the syntax files for the languages you want, from node_modules/prismjs/components. The Angular CLI example shows it as a diff to angular.json, with the theme added to styles and the core and language files added to scripts:

```diff
"styles": [
  "styles.css",
+ "node_modules/prismjs/themes/prism-okaidia.css"
],
"scripts": [
+ "node_modules/prismjs/prism.js",
+ "node_modules/prismjs/components/prism-csharp.min.js", # c-sharp language syntax
+ "node_modules/prismjs/components/prism-css.min.js" # css language syntax
]
```

Themes come from inside the Prism package, from its themes directory, and the documentation points at community theme collections for more.

Each plugin follows the same pattern, and each adds a CSS file and a script file. The line numbers plugin needs prism-line-numbers.css and prism-line-numbers.js, the line highlight plugin needs prism-line-highlight.css and prism-line-highlight.js, and the command line plugin needs prism-command-line.css and prism-command-line.js, the last one being for showing a prompt and the output of the commands.

Once the files are in place, the plugins are switched on from the template rather than from configuration, using the lineNumbers and lineHighlight properties, and the additional input properties start and lineOffset control the offset of the first displayed line and the starting line of the code the snippet represents. The example binds them together:

```html
<markdown
  lineNumbers
  [start]="5"
  [src]="path/to/file.js">
</markdown>
```

So the cost of the optional highlighting is a configuration file edit per feature, and the benefit is that a code block in your documentation can carry line numbers and highlighted ranges without a custom component.

## The renderer hook is where the risk lives

The documentation's table of contents lists sections for installation, configuration, usage, the renderer, syntax highlight, the demo application, AoT compilation, a road map, contribution and supporting development. The renderer section is the one to read with the most attention, and the reason is structural.

Markdown permits raw HTML. If the parser is allowed to pass HTML through, then any markup in the source document becomes markup in the page, and a document fetched from a remote path or supplied by a user becomes a script injection vector. The library exposes a renderer hook, which is the point where a marked renderer can be configured, and the safe configuration is one that escapes or strips dangerous content rather than one that passes it through.

That is a documented decision rather than an accident, and it is worth stating plainly for anyone evaluating the library: the safety of rendering remote markdown depends on how the renderer is configured in your application, not on the library default being safe by assumption. A team that renders only its own bundled content has little to worry about. A team that renders whatever a user submits has to configure this deliberately and test it.

The same reasoning applies to the src mode. A path bound to a remote document is fetched and rendered, so where the document comes from, who can write to it and whether it is trusted are the questions that decide whether the feature is a documentation viewer or a stored cross site scripting problem.

The AoT compilation section is the other one to check, because an Angular library that renders content at runtime has to survive ahead of time compilation, and the project carries a dedicated section on it plus a demo build that uses AOT with a base href for publishing to GitHub Pages.

## The repository is a library and a demo that link together

The repository layout shows a project that takes its own dog fooding seriously.

There is a lib/ directory holding the library itself and a demo/ directory holding the demo application, plus a root angular.json, a tsconfig.json, an eslint.config.js, a.circleci/ directory for continuous integration, and a.prettierignore and.editorconfig.

The package scripts are the clearest description of the workflow. There are separate build scripts for the library and for the demo, a link:lib script that runs npm link inside the demo directory so the demo consumes the local build rather than the published one, and a start script that links the library and then serves the demo. The lint and type-check scripts each come in a library variant and a demo variant, and a separate lint:ci script emits checkstyle format for the CI.

The test scripts are worth a look too. There is a plain test script running the Angular test runner, a test:ci variant with coverage and no progress output, and a separate coveralls script that pipes the lcov report into the coveralls binary. There is also a test:vite script that runs a standalone spec file, node lib/test/vite-optional-import.spec.mjs, which is a targeted check on an optional import path, the kind of test that catches a bundler specific breakage in consumers who use a different build tool than the one the project uses.

The release scripts show how the package is published. A postbuild step copies the README and the LICENSE into the distribution, and the GitHub Pages build produces the demo with AOT and a base href, with a postbuild step that copies the third party licences into the output, which is the kind of detail a package that bundles other people's libraries needs to get right.

## Frequent releases, a stable licence and a version number to watch

The release cadence is quick and the versioning is worth understanding. The recent tags are v22.0.1 and v22.0.2 both on 2026-08-29, and v22.1.0 on 2026-09-26, with the package version in the manifest at 22.1.0. The last push was on 2026-10-15 and the repository is not archived, so the work is current.

A major version in the twenties for a component library is unusual, and the reason is the platform underneath it. An Angular library is coupled to the Angular major version it is compiled against, so the library's major number tends to move with Angular's, and a version like 22.x is a signal about the Angular generation it targets rather than about twenty two breaking changes of its own. The practical consequence for a consumer is that you upgrade the library when you upgrade Angular, and you read the release notes for the major, not just for the patch.

The minor releases carry the features, as v22.1.0 does, and the release candidate and patch pattern of the v22.0.x line shows the usual discipline of shipping fixes without moving the major.

The licence is MIT, and the repository carries the LICENSE file, which is copied into the distribution by the postbuild script so it travels with the package. The npm package is the distribution channel, with a monthly download badge, and the project is built and tested on CircleCI with coverage reported to Coveralls.

Two smaller things are worth knowing if you are evaluating the project rather than using it. The road map section means the feature set is still moving, and the StackBlitz and the live demo exist so you can try the current behaviour without installing anything, which is the fastest way to find out whether the rendering matches what you need.

## Conclusion

ngx-markdown suits an Angular application that needs to display user authored or remote markdown with code highlighting, maths and diagrams without writing a rendering pipeline, and it suits a team that wants the parser and the extras kept in separate dependencies so it can update them independently. It is the wrong choice if you want a self contained component with everything bundled, because marked and Prism are installed and configured by the application, and a poor match if your markdown source is untrusted, since the documentation describes a custom renderer hook and the sanitisation story is the part you have to read most carefully. Before adopting, install marked at the version the documentation names, add the Prism core file, a theme and the language files you need to angular.json, and read the renderer section before you render any markdown that came from a user.

## FAQ

### How do I install ngx-markdown in an Angular project?

Run npm install ngx-markdown marked@^18.0.0 --save. The marked library is installed separately because the package does not bundle it.

### How do I enable syntax highlighting in ngx-markdown?

Prism is optional. Install prismjs@^1.30.0, then add the Prism core file, a theme from the themes directory and the language files you need to the styles and scripts arrays in angular.json, and use the lineNumbers and lineHighlight properties on the markdown component.

### Can ngx-markdown render markdown loaded from a file or a URL?

Yes. The component accepts data for variable binding, src for remote content, and transclusion for static markdown written in the template. The start, line, lineOffset and lineNumbers inputs control the code block presentation.

### What licence is ngx-markdown published under?

The MIT Licence, with the LICENSE file in the repository root and copied into the published package by the postbuild script. The package is published on npm as ngx-markdown and the current version is 22.1.0.

## Sources

- [jfcere/ngx-markdown on GitHub](https://github.com/jfcere/ngx-markdown)
- [License: MIT](https://github.com/jfcere/ngx-markdown/blob/master/LICENSE)
- [Project website](https://jfcere.github.io/ngx-markdown)
- [README](https://github.com/jfcere/ngx-markdown/blob/master/README.md)
- [Releases](https://github.com/jfcere/ngx-markdown/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jfcere-ngx-markdown
