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

hledger-lsp

v0.4.8

Published

Language Server Protocol implementation for hledger plain text accounting

Readme

hledger Language Server

A Language Server Protocol implementation for hledger plain text accounting; bringing IDE-grade tooling to your journal files.

Completion, validation, formatting, navigation, semantic highlighting, inlay hints, and more — in any editor that supports LSP.

Editor plugins: VS Code · Neovim · Any LSP client

Installation

npm install -g hledger-lsp

This provides the hledger-lsp command globally. After installation, the language server can be used with any LSP-compatible editor.

Command Line Usage

The hledger-lsp command can be used in two modes:

LSP Server Mode (default)

hledger-lsp --stdio

This starts the language server for use with LSP-compatible editors.

Standalone Formatter

Format journal files directly from the command line without an IDE:

# Format a file and output to stdout
hledger-lsp --format myfile.journal

# Format a file and write to output file
hledger-lsp --format myfile.journal -o formatted.journal
hledger-lsp --format myfile.journal --output formatted.journal

# Format stdin and write to file
cat myfile.journal | hledger-lsp --format - -o formatted.journal

# Format in place (overwrite original file)
hledger-lsp --format myfile.journal -o myfile.journal

The formatter applies default formatting settings:

  • 4-space indentation for postings
  • Decimal point alignment at column 52
  • Normalized transaction header spacing

Other Options

hledger-lsp --help      # Show help message
hledger-lsp --version   # Show version

IDE Integration

This language server works with any LSP-compatible editor. First-party plugins are available for VS Code and Neovim:

| Editor | Plugin | Install | |---------|----------------|----------------------------------| | VS Code | hledger-vscode | VS Code Marketplace | | Neovim | hledger-nvim | Plugin manager (lazy.nvim, etc.) |

Both plugins provide all LSP features with zero configuration. The VS Code extension also includes a workspace graph tree view; the Neovim plugin includes a workspace graph floating window.

Other Editors

The server can be used with any LSP client. Example configuration:

{
  "command": "hledger-lsp",
  "args": ["--stdio"],
  "filetypes": ["hledger", "journal"],
  "rootPatterns": [".hledger-lsp.json", ".git"]
}

Features

Comprehensive IDE support for hledger journal files, including regular transactions, periodic transactions (~), and auto posting rules (=):

Code Completion

  • Account names - Auto-complete from accounts (configurable: declared only or all)
  • Payees - Complete transaction descriptions from payees (configurable: declared only or all)
  • Commodities - Auto-complete currency symbols (configurable: declared only or all)
  • Tags - Complete tag names in comments (configurable: declared only or all)
  • Directives - Complete hledger directives (account, commodity, payee, tag, include, alias)
  • Include paths - File path completion for include directives
  • Smart completions - Context-aware account suggestions based on payee history (learns from your transaction patterns)
  • Smart filtering - By default, only declared items appear in completions (can be configured to include all items)

Hover

  • Hover information - Lightweight hover support for accounts, payees and dates. Hover text is provided by the language server and can be extended to show declarations, balances and commodity formats.

Validation

  • Transaction balance - Verify transactions balance to zero per commodity
  • Missing amounts - Ensure at most one posting omits an amount
  • Undeclared items - Warn about undeclared accounts, payees, commodities, and tags
  • Date ordering - Detect out-of-order transactions
  • Balance assertions - Verify balance assertions match calculated balances
  • Empty transactions - Require at least 2 postings per transaction
  • Date validation - Check for invalid dates (e.g., Feb 30, month 13)
  • Future dates - Warn about future-dated transactions
  • Empty descriptions - Warn about transactions with no description
  • Include files - Detect missing include files
  • Circular includes - Detect circular include dependencies
  • Periodic transactions - Balance and missing-amount checks for ~ periodic transaction rules (same rules as regular transactions)
  • Auto postings - Undeclared account/commodity checks for = auto posting rules (balance checks are skipped since auto postings are partial by design)

Include Directive Support

  • Multi-file journals - Parse and merge multiple journal files via include directives
  • Relative and absolute paths - Support both path styles, including ../ parent directory references
  • Tilde expansion - Support for ~/ home directory paths
  • Paths with spaces - Properly handles file paths containing spaces and special characters (e.g., "Cloud Storage", "My Documents (2025)")
  • Circular detection - Prevent infinite loops from circular includes
  • Caching - Efficient parsing with include file caching
  • Dependency tracking - Auto-revalidate files when included files change
  • Source tracking - Track which file each entity originates from

Navigation

  • Document symbols - Outline view showing directives, transactions, periodic transactions (~), and auto posting rules (=) with their postings
  • Workspace symbols - Project-wide search across all accounts, payees, commodities, tags, and transactions
  • Go to definition - Jump to declarations for accounts, payees, commodities, and tags
  • Find references - Show all usages of accounts, payees, commodities, or tags across the document

Code Actions and Quick Fixes

  • Add declarations - Automatically add account, payee, commodity, or tag declarations for undeclared items
  • Smart insertion - Directives are inserted in appropriate locations, grouped with similar directive types
  • Rename refactoring - Rename accounts, payees, commodities, or tags across all their references in the document
  • Context-aware actions - Actions appear when cursor is positioned on renameable items

Formatting

  • Document formatting - Format entire journal files with consistent indentation and spacing
  • Range formatting - Format selected portions of your journal
  • On-type formatting - Auto-indent postings when pressing Enter after transaction headers
  • Decimal-point alignment - Automatically align amounts by their decimal point (or implied decimal position for whole numbers) within transactions, making it easy to visually compare amounts
  • Negative amount support - Properly aligns negative amounts regardless of minus sign position (e.g., -$100.00 or $-100.00)
  • Commodity format support - Reformats amounts according to declared commodity formats (symbol placement, decimal separators, thousands separators, precision)
  • Precision preservation - Maintains decimal precision even when commodity format specifies fewer decimal places
  • Configurable - Customize indentation width, alignment column, minimum spacing, trailing whitespace handling, and more

Semantic Highlighting

  • Context-aware syntax highlighting - Rich semantic highlighting based on token type and meaning
  • Token types - Distinct highlighting for dates, accounts, payees, commodities, tags, directives, amounts, comments, and status indicators
  • Token modifiers - Additional styling for declarations (directive definitions) and readonly items (dates, amounts)
  • Hierarchical accounts - Account names highlighted as namespaces to reflect their hierarchical nature
  • Tag detection - Automatic highlighting of tags within comments (key:value pairs)
  • Periodic & auto postings - ~ and = operators, period expressions, queries, and their postings are all semantically highlighted

Inlay Hints

  • Inferred amounts - Show calculated amounts for postings without explicit amounts (including periodic transaction postings)
  • Running balances - Display running balances per account and commodity after each posting
  • Cost conversions - Show total cost in target commodity for postings with cost notation (@ or @@)
  • Configurable - Enable/disable each hint type independently
  • Range-aware - Only show hints for visible portions of the document for better performance

Code Lens

  • Balance assertions - Show running balances on each posting line in balance assertion format (= $50.00)
  • Clickable - Click a balance assertion code lens to insert it into the posting
  • Transaction counts - Display how many transactions each account has been involved in on transaction headers
  • Configurable - Enable/disable each lens type independently

Editor Integration

  • Folding ranges - Collapse/expand transactions, periodic transactions, and auto posting rules to hide postings; fold multi-line comment blocks
  • Document links - Clickable include paths that open the referenced file (supports relative and absolute paths)
  • Selection range - Smart text selection expansion: Word → Account → Posting → Transaction (requires editor keybinding setup, see configuration below)

Configuration

All validations and completion behaviors can be individually configured per workspace or document:

  • Validation settings - Enable/disable individual validation rules and customize severity levels
  • Completion filtering - Control whether completions show only declared items or all items (declared + undeclared)

General Settings

  • maxNumberOfProblems (number, default: 1000): Maximum number of diagnostic problems to report per file
  • hledgerPath (string, default: "hledger"): Path to the hledger executable (reserved for future CLI integration)

Validation Settings

Most validation settings default to true and can be individually disabled:

  • validation.balance (default: true): Verify transactions balance to zero per commodity
  • validation.requireExplicitCosts (default: false): Require explicit @ or @@ cost notation for multi-commodity transactions. When disabled (default), the LSP auto-infers costs like hledger's autobalanced mode. When enabled, mirrors hledger's stricter balanced check.
  • validation.missingAmounts (default: true): Ensure at most one posting per transaction omits an amount
  • validation.undeclaredAccounts (default: true): Warn about accounts used but not declared
  • validation.undeclaredPayees (default: false): Warn about payees used but not declared
  • validation.undeclaredCommodities (default: true): Warn about commodities used but not declared
  • validation.undeclaredTags (default: false): Warn about tags used but not declared
  • validation.dateOrdering (default: true): Detect transactions with dates out of chronological order
  • validation.balanceAssertions (default: true): Verify balance assertions match calculated balances
  • validation.emptyTransactions (default: true): Require at least 2 postings per transaction
  • validation.invalidDates (default: true): Check for invalid dates (e.g., February 30, month 13)
  • validation.futureDates (default: true): Warn about future-dated transactions
  • validation.emptyDescriptions (default: true): Warn about transactions with no description
  • validation.formatMismatch (default: true): Validate that amounts match their commodity format directives
  • validation.includeFiles (default: true): Detect missing include files
  • validation.circularIncludes (default: true): Detect circular include dependencies
  • validation.markAllUndeclaredInstances (default: true): Mark all instances of undeclared resources with diagnostics, not just the first occurrence

Severity Settings

Customize the severity level for undeclared item warnings. Options: "error", "warning", "information", "hint"

  • severity.undeclaredAccounts (default: "warning")
  • severity.undeclaredPayees (default: "warning")
  • severity.undeclaredCommodities (default: "warning")
  • severity.undeclaredTags (default: "information")

Include Settings

  • include.followIncludes (boolean, default: true): Parse and merge included journal files
  • include.maxDepth (number, default: 10): Maximum include depth to prevent infinite recursion

Workspace Settings

Enable workspace-aware parsing for features that need global context (running balances, completion, validation):

  • workspace.enabled (boolean, default: true): Enable workspace-aware parsing. When enabled, the server discovers all journal files in your workspace, builds an include graph, and identifies a single root file. This allows features to access workspace-wide state even when working with "leaf" files that don't include other files.
  • workspace.eagerParsing (boolean, default: true): Parse all discovered files eagerly on startup. If disabled, files are parsed on-demand.
  • workspace.autoDetectRoot (boolean, default: true): Automatically detect the root file using heuristics (prefers files with no parents that include many others, with names like "main", "all", or "index"). If disabled, only an explicitly configured root file is used (see Configuration File Support below).

Configuration File Support:

You can create a .hledger-lsp.json file in your workspace to explicitly configure workspace behavior:

{
  "rootFile": "main.journal",
  "include": ["**/*.journal", "**/*.hledger"],
  "exclude": ["**/archive/**", "**/temp/**"],
  "workspace": {
    "enabled": true,
    "eagerParsing": true,
    "autoDetectRoot": false
  }
}

Settings:

  • rootFile (string): Explicit root file path (relative to config file location)
  • include (array of glob patterns): File discovery patterns (default: ["**/*.journal", "**/*.hledger"])
  • exclude (array of glob patterns): Files to exclude (default: ["**/node_modules/**", "**/.git/**", "**/.*"])
  • workspace (object): Same workspace settings as above

Important: The .hledger-lsp.json file is ONLY for workspace structure configuration (which files to discover, which are roots, etc.). LSP feature settings like inlay hints, code lens, validation rules, and formatting preferences should be configured in your editor/IDE settings (VS Code settings.json, Neovim LSP config, etc.).

The configuration file will be automatically discovered by walking up the directory tree from your journal files. Settings from VS Code/editor configuration override settings from the config file.

Performance Tips:

  • For large workspaces (>100 files), use exclude patterns to skip unnecessary files
  • Disable eagerParsing if initialization is slow
  • Check LSP server logs for performance warnings and metrics

Completion Settings

Control which items appear in auto-completion suggestions. All settings default to true (only show declared items):

  • completion.onlyDeclaredAccounts (boolean, default: true): Only show accounts declared with account directive in completions
  • completion.onlyDeclaredPayees (boolean, default: true): Only show payees declared with payee directive in completions
  • completion.onlyDeclaredCommodities (boolean, default: true): Only show commodities declared with commodity directive in completions
  • completion.onlyDeclaredTags (boolean, default: true): Only show tags declared with tag directive in completions

Set to false to include items that are used but not explicitly declared in completions.

Formatting Settings

Configure document formatting behavior:

  • formatting.indentation (number, default: 4): Number of spaces for posting indentation
  • formatting.maxCommodityWidth (number, default: 4): Maximum width allocated for commodity symbols
  • formatting.maxAmountIntegerWidth (number, default: 12): Maximum width allocated for the integer part of amount numbers
  • formatting.maxAmountDecimalWidth (number, default: 3): Maximum width allocated for the decimal part of amount numbers
  • formatting.minSpacing (number, default: 2): Minimum number of spaces between account names and amounts
  • formatting.decimalAlignColumn (number, default: 52): Target column position for aligning decimal points in amounts
  • formatting.assertionDecimalAlignColumn (number, default: 70): Target column position for aligning decimal points in balance assertions
  • formatting.signPosition (string, default: "after-symbol"): Where to place the negative sign for prefix commodities. Options: "after-symbol" (e.g., $-100.00) or "before-symbol" (e.g., -$100.00). This affects how amounts are displayed in hover information, inlay hints, and other LSP features. Does not affect postfix commodities (e.g., -100.00 EUR), which always show the sign before the number.
  • formatting.showPositivesSign (boolean, default: false): Whether to show a + sign for positive amounts

Inlay Hints Settings

Configure which inline hints to display (running balances is disabled by default as it can make the file busy):

  • inlayHints.showInferredAmounts (boolean, default: true): Show calculated amounts for postings that omit explicit amounts
  • inlayHints.showRunningBalances (boolean, default: false): Display running balance after each posting
  • inlayHints.showCostConversions (boolean, default: true): Show total cost in target commodity for postings with @ or @@ notation

Code Lens Settings

Configure which code lenses to display (disabled by default, largely a holding for future features):

  • codeLens.showTransactionCounts (boolean, default: false): Show transaction counts for each account on transaction headers

Development

Prerequisites

  • Node.js >= 16.0.0

Building from Source

# Clone the repository
git clone https://github.com/ptimoney/hledger-lsp.git
cd hledger-lsp

# Install dependencies
npm install

# Build the server
npm run build

# Run the server directly
node out/server.js --stdio

Project Structure

hledger-lsp/
├── src/
│   ├── server.ts           # Main LSP server implementation
│   ├── types.ts            # Type definitions for hledger structures
│   ├── parser/             # Journal file parser
│   ├── features/           # LSP feature implementations
│   ├── server/             # Server infrastructure
│   └── utils/              # Utility functions
├── tests/                  # Test suite (1380+ test cases)
├── out/                    # Compiled JavaScript output
└── package.json

Development Commands

# Build once
npm run build

# Watch mode (rebuild on changes)
npm run watch

# Lint code
npm run lint

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Generate coverage report
npm run test:coverage

# Run tests with verbose output
npm run test:verbose

# Run specific test file
npx jest tests/parser/index.test.ts

# Run tests matching a pattern
npx jest --testNamePattern="balance"

Developing with the VS Code extension

When working on the language server and the VS Code extension together you have two convenient workflows:

  • Preferred: sibling local build

    If you have the hledger-vscode extension checked out next to this repo (as siblings), the extension will prefer a local built server at ../hledger-lsp/out/server.js.

    Steps:

    # In this repo (language server)
    cd /path/to/hledger-lsp
    npm install
    npm run compile    # produces out/server.js
    
    # In the extension repo (open this folder in VS Code)
    cd /path/to/hledger-vscode
    npm install
    npm run compile

    Then open the hledger-vscode folder in VS Code and press F5 to launch the Extension Development Host. The extension will detect the local out/server.js and use it when starting the language client.

  • Alternative: npm link

    If you prefer to keep the projects separate or want the extension to pick up a locally-installed (linked) package, use npm link:

    # In language server repo
    cd /path/to/hledger-lsp
    npm link
    
    # In extension repo
    cd /path/to/hledger-vscode
    npm link hledger-lsp
    npm install
    npm run compile

    This makes require.resolve('hledger-lsp/out/server.js') resolve to your local linked package.

Notes and tips

  • After building the server and extension, use Developer: Reload Window in the extension host or the hledgerLanguageServer.reload command (provided by the extension) to restart the language client so changes propagate.

  • The server now logs the semantic token legend on initialize. Open View → Output and select the hledger Language Server output channel to see messages such as:

    Semantic tokens legend: {"tokenTypes":["namespace","keyword","class","variable","property","type","number","string","comment","operator"],"tokenModifiers":["declaration","readonly","deprecated"]}

  • Running tests:

    • Server tests (in hledger-lsp): npm test (or npx jest <path>)
    • Extension tests (in hledger-vscode): npm test — these use mocked vscode and vscode-languageclient modules so they don't require a real server binary.

If you want an explicit server path override, set up a quick environment variable in your debug launch configuration or use npm link as described above.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

For bug reports and feature requests, open an issue.

Related Projects

| Project | Description | |---------|-------------| | hledger-vscode | VS Code extension — install from the Marketplace | | hledger-nvim | Neovim plugin with LSP integration and workspace graph | | hledger | The plain text accounting tool this server supports | | LSP Specification | The protocol this server implements |

License

MIT