Skip to content

Compodoc is a documentation tool for Angular applications. When used with Storybook, Compodoc can automatically generate documentation for your Angular components by analyzing their TypeScript code, decorators, and JSDoc comments.

Compodoc automatically generates documentation by:

  • Analyzing TypeScript interfaces and classes
  • Reading Angular decorators (@Input, @Output, etc.)
  • Parsing JSDoc comments
  • Generating argTypes for Storybook controls

You need to have Storybook already configured for your Angular project. If you haven't set up Storybook yet, follow the Angular Storybook setup guide.

Install Compodoc as a dev dependency:

npm install --save-dev @compodoc/compodoc

Add Compodoc configuration to your Storybook's main.ts file:

.storybook/main.ts
import type { StorybookConfig } from '@storybook/angular';
const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/angular',
options: {},
},
typescript: {
check: false,
checkOptions: {},
reactDocgen: 'react-docgen-typescript',
reactDocgenTypescriptOptions: {
shouldExtractLiteralValuesFromEnum: true,
propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
compilerOptions: {
allowSyntheticDefaultImports: false,
esModuleInterop: false,
},
},
},
docs: {
autodocs: true,
},
};
export default config;

Add a script to your package.json to generate Compodoc documentation:

package.json
{
"scripts": {
"docs:json": "compodoc -p tsconfig.json -e json -d .",
"storybook": "npm run docs:json && nx storybook your-project"
}
}

Configure your Angular component for better documentation

Section titled “Configure your Angular component for better documentation”

Add JSDoc comments and use TypeScript interfaces for better documentation generation:

button.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';
export interface ButtonProps {
/** The button label */
label: string;
/** Primary or secondary styling */
primary?: boolean;
/** Disabled state */
disabled?: boolean;
/** Button size */
size?: 'small' | 'medium' | 'large';
}
/**
* A customizable button component
*/
@Component({
selector: 'app-button',
template: `
<button
[class]="classes"
[disabled]="disabled"
(click)="onClick.emit($event)">
{{ label }}
</button>
`,
styleUrls: ['./button.component.css']
})
export class ButtonComponent implements ButtonProps {
/** The button label */
@Input() label: string = '';
/** Primary or secondary styling */
@Input() primary: boolean = false;
/** Disabled state */
@Input() disabled: boolean = false;
/** Button size */
@Input() size: 'small' | 'medium' | 'large' = 'medium';
/** Click event handler */
@Output() onClick = new EventEmitter<Event>();
get classes(): string {
return [
'btn',
this.primary ? 'btn-primary' : 'btn-secondary',
`btn-${this.size}`,
].join(' ');
}
}

Create a story that leverages the Compodoc-generated documentation:

button.stories.ts
import type { Meta, StoryObj } from '@storybook/angular';
import { ButtonComponent } from './button.component';
const meta: Meta<ButtonComponent> = {
title: 'Components/Button',
component: ButtonComponent,
parameters: {
docs: {
description: {
component: 'A customizable button component with multiple variants and sizes.',
},
},
},
argTypes: {
size: {
control: { type: 'select' },
options: ['small', 'medium', 'large'],
},
onClick: { action: 'clicked' },
},
};
export default meta;
type Story = StoryObj<ButtonComponent>;
export const Primary: Story = {
args: {
primary: true,
label: 'Primary Button',
size: 'medium',
},
};
export const Secondary: Story = {
args: {
primary: false,
label: 'Secondary Button',
size: 'medium',
},
};
export const Large: Story = {
args: {
label: 'Large Button',
size: 'large',
},
};
export const Small: Story = {
args: {
label: 'Small Button',
size: 'small',
},
};
export const Disabled: Story = {
args: {
label: 'Disabled Button',
disabled: true,
},
};
  1. Automatic Documentation: Compodoc generates component documentation automatically from your TypeScript code
  2. Better Controls: Enhanced Storybook controls based on your component's @Input properties
  3. Type Safety: Leverages TypeScript types for accurate documentation
  4. JSDoc Integration: Uses JSDoc comments for rich descriptions
  5. Less Maintenance: Documentation stays in sync with your code

With the setup complete, run your Storybook:

npm run storybook

This will generate the Compodoc documentation and then start Storybook with enhanced documentation for your Angular components.