npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hosanna/chordpro

v1.6.2

Published

ChordPro parser, renderer, and editor for Hosanna

Readme

@hosanna/chordpro

A modular ChordPro parser, transformation pipeline, formatter, instrument registry, React renderer, and Ace editor for JavaScript and TypeScript.

Features

  • ChordPro AST parsing with metadata, sections, tabs, grids, comments, repeats, and named variants.
  • Immutable, chainable song transformations: transpose, capo, chord simplification, chord removal, variant selection, and instrument selection.
  • Extensible formatting and linting utilities.
  • Registry-based instrument diagrams for guitar, piano, ukulele, and consumer-defined instruments.
  • React rendering from an already transformed SongAST.
  • Lazy Ace editor with ChordPro syntax support, snippets, linting, formatting, and transpose commands.

Installation

npm install @hosanna/chordpro

React consumers also need the peer dependencies:

npm install react react-dom ace-builds react-ace

Modular entry points

| Entry point | Contents | | ------------------------------- | ----------------------------------------------------------------------------- | | @hosanna/chordpro | All public APIs | | @hosanna/chordpro/parser | Parser, AST types, transformations, transposition, dictionary, and converters | | @hosanna/chordpro/renderer | ChordProRenderer, ChordRoll, and diagram components | | @hosanna/chordpro/editor | Editor, ChordFinder, Ace modes, snippets, and editor integrations | | @hosanna/chordpro/formatter | ChordPro formatter and formatter types | | @hosanna/chordpro/instruments | Instrument profiles and the instrument registry |

Parse and transform a song

parseChordPro returns a SongAST. Every transformation returns a new song, so pipelines can be reused safely without mutating the parsed source:

import { parseChordPro } from "@hosanna/chordpro/parser";

const source = `
{title: Hallelujah}
{key: C}
{start_of_version: Acoustic}
[C]Halle---lu---jha
{end_of_version}
`;

const song = parseChordPro(source)
  .transpose(2)
  .withCapo(3)
  .simplifyChords(1)
  .removeChords(true)
  .selectVariant("acoustic")
  .instrument("guitar");

Transformation operations

| Operation | Description | | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | .transpose(semitones) | Transposes every chord, key, and bass note by the requested interval. | | .withCapo(position) | Stores the capo and moves chord shapes into capo-relative notation. 0 disables it. | | .simplifyChords(level) | Simplifies chord qualities. 0 original, 1 slightly simplified, 2 beginner, 3 basic triads only. | | .removeChords(cleanText) | Removes chord annotations from every variant. With true, also joins display-only hyphenation such as Halle---lu---jha. | | .selectVariant(id) | Selects a named variant (null, undefined, or "default" selects the default) and returns a song containing only that version. | | .instrument(id) | Stores the instrument used by downstream renderers. Pass null to clear it. |

The functional equivalent is available for consumers that prefer an explicit pipeline entry point:

import { transformSong } from "@hosanna/chordpro/parser";

const transformed = transformSong(parseChordPro(source))
  .transpose(2)
  .withCapo(3);

The pipeline is extensible: custom transformations can clone a SongAST, update its sections or metadata, and return the result for the next operation.

Analyze a song

analyze() returns structural and harmonic information without changing the song:

const analysis = parseChordPro(source).analyze();
// {
//   key: "G",
//   detectedKey: "G",
//   tempo: 72,
//   chordCount: 14,
//   uniqueChords: ["G", "C", "Em", "D"],
//   sections: 8,
//   lyricsLength: 1240,
//   hasTabs: false,
//   hasAnnotations: true,
//   hasVariants: true
// }

detectedKey is inferred from chord roots, chord qualities, and diatonic major/minor scale membership. It is independent from the optional declared key, so consumers can compare source metadata with the detected harmonic center.

Render a transformed song

Pass the transformed AST to the renderer. The renderer does not parse source text or apply a second transformation:

import { ChordProRenderer } from "@hosanna/chordpro/renderer";

export function SongViewer({ source }: { source: string }) {
  const song = parseChordPro(source)
    .selectVariant("acoustic")
    .transpose(2)
    .withCapo(3)
    .instrument("guitar");

  return <ChordProRenderer song={song} showDiagrams />;
}

The renderer accepts only a transformed SongAST. It derives chord visibility from the AST and reads the selected instrument from song.metadata.instrument; call .removeChords(true) or .instrument("guitar") in the pipeline before rendering.

Variants

Use version blocks in ChordPro:

{title: Amazing Grace}
[G]Amazing grace

{start_of_version: Acoustic}
[C]Amazing grace
{end_of_version}

Variant IDs are generated as stable slugs ("Acoustic" becomes "acoustic"). Variant metadata inherits from the preceding version and can override individual fields.

Instruments

Instrument diagrams use a registry rather than renderer conditionals:

import { instrumentRegistry } from "@hosanna/chordpro/instruments";

instrumentRegistry.register({
  id: "mandolin",
  displayName: "Mandolin",
  category: "string",
  supportsCapo: true,
  getFingering: (chord) => resolveMandolinShape(chord),
  renderDiagram: (shape) => <MandolinDiagram shape={shape} />,
});

An InstrumentProfile resolves a chord into instrument-specific shape data and renders that data. Custom instruments work with ChordRoll and ChordProRenderer without changing either component.

Formatting and editor

import { formatChordPro } from "@hosanna/chordpro/formatter";

const result = formatChordPro(source, {
  normalizeNotationAliases: true,
  expandDirectiveAliases: true,
});
import { Editor } from "@hosanna/chordpro/editor";

<Editor
  value={source}
  onChange={setSource}
  onSave={(nextSource) => save(nextSource)}
  settings={{ theme: "textmate", fontSize: 14, wordWrap: true }}
/>;

The editor includes ChordPro completion, diagnostics, section shortcuts (Alt+V, Alt+R, Alt+B), transpose (Alt+T), and formatting (Ctrl/Cmd+Shift+F).

Supported directives

Metadata includes title, subtitle, artist, composer, album, copyright, key, original_key, capo, tempo, time, duration, ccli, and youtube. Sections include verses, choruses, bridges, tabs, grids, comments, repeats, and named versions.

License

Licensed under the Apache License 2.0.