Angular 22 · Shiki v4 · markdown-it 14 & 15

shikidown

An Angular Markdown renderer with Shiki syntax highlighting, Angular components embedded by selector, and incremental block rendering.

npm install shikidown shiki markdown-it @angular/elements

Shiki v4 highlighting

IDE-quality syntax colours, with a dark and a light theme rendered at once and switched through CSS variables — no re-highlighting when the user toggles the theme.

Angular components in Markdown

Register a component and drop its selector straight into the document. Under the hood each one becomes a standard Custom Element through @angular/elements.

Incremental block rendering

Only the blocks whose source text changed are re-parsed. Unchanged DOM nodes are kept, so embedded component state survives every keystroke.

The whole setup, in one file

import {  ApplicationConfig, ChangeDetectionStrategy, Component, input, linkedSignal,} from '@angular/core';import { provideMarkdown, MarkdownComponent } from 'shikidown';@Component({  selector: 'my-counter',  changeDetection: ChangeDetectionStrategy.OnPush,  template: `    <div>Count: {{ count() }}</div>    <button (click)="increment()">+1</button>  `,})export class CounterComponent {  readonly initialCount = input(0);  readonly count = linkedSignal(() => this.initialCount());  increment(): void {    this.count.update((n) => n + 1);  }}export const appConfig: ApplicationConfig = {  providers: [    provideMarkdown({      theme: { dark: 'github-dark', light: 'catppuccin-latte' },      components: { 'my-counter': CounterComponent },      incrementalRendering: true,    }),  ],};@Component({  imports: [MarkdownComponent],  template: `<shikidown [content]="md" class="prose dark:prose-invert" />`,})export class DocsPage {  readonly md = '# Hello\n\n<my-counter initial-count="5"></my-counter>';}