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

xq-lsp

v1.6.0

Published

XQuery Language Server Protocol implementation

Readme

xq-lsp

Language Server Protocol implementation for XQuery, providing autocompletion, hover documentation, signature help, go-to-definition, and diagnostics.

Features

  • Syntax highlighting — keywords, types, variables, operators, comments, and XQuery 4.0 tokens (VS Code extension)
  • Completion — functions declared in the current file, imported modules, and variables in scope
  • Hover — function signatures on hover
  • Signature help — active parameter hints inside function calls
  • Go to definition — jump to function or variable declarations, including across imported files
  • Document symbols — file outline of all declared functions and variables
  • Diagnostics — syntax errors, undeclared namespace prefixes, type mismatches, and unused symbols

Configuration

Summary: Fonto development

Place an lsp-config.xq file in the Fonto root folder (the one that holds the manifest.json) with the following content:

map {
	'lib': 'fonto',
	'glob': 'packages/**/*.xqm',
	'import': map {
		'generateLocationHints': false()
	}
}

General configuration

Place an lsp-config.xq file in your project root to enable glob-based import resolution. The server walks up from the current file's directory to find it.

The file contains an XPath 3.1 map expression with a glob key:

map {"glob": "src/**/*.xq"}

Multiple patterns are written as an XPath sequence:

map {"glob": ("src/**/*.xq", "lib/**/*.xq")}

The server expands the globs, analyzes each matched file, and indexes library modules by their declared namespace URI. Imports written without an at clause are then resolved by matching the namespace URI:

(: no "at" path needed — the server finds the file via the glob index :)
import module namespace util="http://example.com/util";

Imports written as import module namespace prefix="uri" at "./other-file.xq" are followed automatically; symbols from imported files are included in completions.

For files with syntax errors (common while editing), the server falls back to regex-based extraction so completions keep working.

Runtime built-ins

Use the lib key to load built-in definitions for a specific runtime:

| Value | Runtime | | ----------- | ------------------------------------------------------------------------- | | "fonto" | Fonto XML editorfonto:* functions | | "existdb" | eXist-db — all extension module functions |

map {"glob": "src/**/*.xq", "lib": "existdb"}

Multiple libs use an XPath sequence:

map {"glob": "src/**/*.xq", "lib": ("fonto", "other")}

eXist-db runtime

The "existdb" runtime bundles stub definitions for every eXist-db extension module (util, xmldb, request, sm, ft, compression, …).

eXist-db automatically pre-declares a large set of namespace prefixes — you can call util:log(…), xmldb:store(…), process:execute(…), etc. without any import module namespace statement. When the existdb runtime is active the server knows about these pre-declared prefixes and:

  • suppresses false XQST0081 ("namespace prefix not declared") diagnostics for all pre-declared namespaces
  • provides completions, hover, and go-to-definition for those modules without requiring an explicit import module namespace in your source

If you do choose to write explicit imports (e.g. for editor portability), the server handles those correctly too:

(: explicit import — also fine :)
import module namespace util = "http://exist-db.org/xquery/util";
util:uuid()

Modules that require explicit import even in eXist-db (e.g. datetime, httpclient, console, crypto, kwic) still need a import module namespace declaration; the server offers quick-fix code actions to insert it.

(: lsp-config.xq in your project root :)
map {
    "glob": "src/**/*.xq",
    "lib": "existdb",
    "import": map {
        "generateLocationHints": false()
    }
}

The generateLocationHints: false() setting prevents the server from appending at "…" paths to generated imports, which eXist-db does not need (it resolves modules by namespace URI).

Fonto runtime

Then import the namespace in your XQuery files as usual — the server resolves completions, hover, and go-to-definition against the bundled definitions:

import module namespace fonto="http://www.fontoxml.com/functions";

Location hints

Some runtimes do not like location hints (import namespace prefix="uri" at "Location hint";), turn them off to prevent them from being generated:

map {
	'import': map {
		'generateLocationHints': false()
	}
}

Roadmap

  • Completion of keywords — like function, declare and ancestor-or-self, which saves you some keystrokes
  • Context-depending completion — which prevent syntactical errors
  • Treesitter parser — should improve performance and scalability for huge files
  • XQuery 4 — the parser already supports this. Just make it work
  • Arity checks — report when one calls fn:document('too', 'many', 'arguments')
  • Register or discover known prefix/namespace combinations — if you have the tei namespace declared in another file, you might mean that when you type tei:TEI in another file
  • Context items — doing declare function xx () { bla }; is an error: there is no context item. Check if there is a context item available when you use the context item expression (.) or a step expression.
  • Unused functions and variables — no one likes those. Except when prefixed with _, then they make sense
  • More of the (static) errors in the spec at The spec at section F Error Conditions, whichever are easy to implement

Emacs

With eglot (built-in since Emacs 29)

Install xquery-mode from MELPA:

M-x package-install RET xquery-mode RET

Add to your init.el:

(with-eval-after-load 'eglot
  (add-to-list 'eglot-server-programs
               '(xquery-mode . ("npx" "xq-lsp" "--stdio"))))

(add-hook 'xquery-mode-hook #'eglot-ensure)

Open any .xq file and eglot starts the server automatically. Run M-x eglot to start it manually.

Key bindings:

| Action | Key | | ---------------- | ------------------------------------- | | Completion | C-M-i | | Hover / docs | C-c C-d | | Signature help | automatic in minibuffer | | Go to definition | M-. | | Go back | M-, | | Document symbols | M-x imenu | | Diagnostics | M-x flymake-show-buffer-diagnostics |

With lsp-mode

(with-eval-after-load 'lsp-mode
  (add-to-list 'lsp-language-id-configuration '(xquery-mode . "xquery"))

  (lsp-register-client
   (make-lsp-client
    :new-connection (lsp-stdio-connection '("npx" "xq-lsp" "--stdio"))
    :major-modes '(xquery-mode)
    :language-id "xquery"
    :server-id 'xquery-lsp)))

(add-hook 'xquery-mode-hook #'lsp)

VS Code

A minimal VS Code extension lives in editors/vscode/.

Install from marketplace

Launch VS Code Quick Open (Ctrl+P or Cmd+P), paste the following command, and press enter.

ext install elliat.xquery-lsp-vscode

Install by hand

cd editors/vscode
npm install

Open the editors/vscode folder in VS Code and press F5 to launch a development host with the extension active. To install it permanently, package it with vsce:

npx vsce package
code --install-extension xquery-lsp-vscode-*.vsix

The extension registers .xq, .xql, .xqm, .xqy, and .xquery files as XQuery, provides syntax highlighting via a bundled TextMate grammar, and starts xq-lsp automatically when you open one.

Claude Code

A plugin lives in editors/claude-code/ that registers xq-lsp as a native LSP server for Claude Code, giving diagnostics, go-to-definition, find-references, and hover for XQuery files.

Make sure the xq-lsp binary is on PATH:

npm install -g xq-lsp

Then, from within Claude Code:

/plugin marketplace add DrRataplan/xq-lsp
/plugin install xquery-lsp@xq-lsp

See editors/claude-code/README.md for local-development setup and details on what the plugin configures.