tree-sitter-eskip
Tree-sitter grammar for eskip — the routing configuration language used by Skipper.
Language overview
Eskip is a DSL for defining HTTP routing rules. Each rule is a route definition: a named predicate expression, an optional chain of filters, and a backend target.
// Route with predicates, filters, and a network backend
api: Method("GET") && Host(/^api\.example\.org$/) && Path("/api/:id")
-> setRequestHeader("X-Foo", "bar")
-> ratelimit(10, "1m")
-> "https://backend.example.org";
// Catch-all that shunts (terminates) the request
catchall: * -> inlineContent("not found") -> status(404) -> <shunt>;
// Load-balanced backend with explicit algorithm
lb: Path("/lb")
-> <roundRobin, "https://a.example.org", "https://b.example.org">;
Supported constructs
| Construct | Example |
|---|---|
| Route definition | name: predicates -> backend ; |
| Predicate | Path("/foo"), Method("GET") |
| Multiple predicates | Method("GET") && Path("/foo") |
| Wildcard predicate | * |
| Filter chain | -> setRequestHeader("X-A", "b") -> ratelimit(10, "1m") |
| String backend | -> "https://example.org" |
| Shunt backend | -> <shunt> |
| Loopback backend | -> <loopback> |
| Dynamic backend | -> <dynamic> |
| Load-balanced backend | -> <roundRobin, "https://a.org", "https://b.org"> |
| String arguments | "double-quoted", `backtick raw` |
| Regexp arguments | /^pattern$/ |
| Number arguments | 404, 3.14, -1 |
| Comments | // line comment |
Load-balancing algorithms: roundRobin, random, consistentHash, powerOfRandomNChoices
Syntax highlighting
The queries/highlights.scm file maps grammar nodes to standard Tree-sitter capture names:
| Capture | Node |
|---|---|
@function |
route identifier |
@function.method |
predicate / filter name |
@keyword |
lb algorithm |
@constant.builtin |
shunt, loopback, dynamic |
@operator |
->, &&, * |
@string / @string.regexp / @string.escape |
string / regexp / escape |
@number |
number |
@comment |
line comment |
@punctuation.delimiter |
:, ;, , |
@punctuation.bracket |
(, ), <, > |
Installation
Node.js
npm install tree-sitter-eskip
import Parser from "tree-sitter";
import Eskip from "tree-sitter-eskip";
const parser = new Parser();
parser.setLanguage(Eskip);
const tree = parser.parse(`hello: Path("/hello") -> "https://example.org";`);
Rust
[dependencies]
tree-sitter-eskip = "0.1"
let language = tree_sitter_eskip::LANGUAGE;
Python
pip install tree-sitter-eskip
import tree_sitter_eskip
from tree_sitter import Language, Parser
lang = Language(tree_sitter_eskip.language())
parser = Parser(lang)
Go
go get github.com/carloluis/tree-sitter-eskip
import (
"github.com/tree-sitter/go-tree-sitter"
tree_sitter_eskip "github.com/carloluis/tree-sitter-eskip/bindings/go"
)
language := tree_sitter.NewLanguage(tree_sitter_eskip.Language())
C
#include "tree_sitter/parser.h"
const TSLanguage *tree_sitter_eskip(void);
Build with make or cmake.
Neovim
This repo ships as a Neovim plugin. Install it with your plugin manager, then call setup() to register the parser and enable highlighting.
vim.pack (built-in, no plugin manager required)
-- in your init.lua:
vim.pack.add({ "https://github.com/carloluis/tree-sitter-eskip" })
require("tree-sitter-eskip").setup()
vim.pack.add downloads and installs the plugin on first run, then calls :packadd so it is available immediately in the same session.
lazy.nvim
{
"carloluis/tree-sitter-eskip",
ft = "eskip",
config = function()
require("tree-sitter-eskip").setup()
-- then install the parser the first time:
-- :TSInstall eskip
end,
}
lazy.nvim / vim-plug / packer
-- in your init.lua, after the plugin is on the runtimepath:
require("tree-sitter-eskip").setup()
setup() does three things:
- Registers the parser source with nvim-treesitter so
:TSInstall eskipworks. - Calls
vim.treesitter.language.registerto bind theeskiplanguage to theeskipfiletype. - Creates a
FileType eskipautocommand that starts tree-sitter highlighting for every eskip buffer.
Filetype detection for *.eskip files is handled automatically via ftdetect/eskip.lua, which is sourced by Neovim's runtimepath on startup — no extra configuration needed.
After installing the plugin, run :TSInstall eskip once to compile the parser. Verify with:
:checkhealth nvim-treesitter
:InspectTree " parse tree for the current buffer
:Inspect " highlight captures under cursor
Development
# Regenerate parser from grammar.js
tree-sitter generate
# Run corpus tests
tree-sitter test
# Parse example files
tree-sitter parse examples/*.eskip --quiet --stat
# Launch the playground (builds WASM first)
npm start
License
MIT
Metadata
Release files for tree-sitter-eskip 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tree_sitter_eskip-0.1.1.tar.gz | 19.2 kB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tree_sitter_eskip-0.1.1-cp310-abi3-musllinux_1_2_x86_64.whl | CPython 3.10 | abi3 | Linux musl 1.2+ x86-64 | Details |
| tree_sitter_eskip-0.1.1-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ x86-64, Linux glibc 2.5+ x86-64 | Details |
Total release size: 65.6 kB
Release files / tree_sitter_eskip-0.1.1.tar.gz
| Download URL | tree_sitter_eskip-0.1.1.tar.gz |
|---|---|
| Size | 19.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
76e47a36ac1ffacca0dc17eec0e502ed9e1fe09976d6119344ef93317d8d51cf
|
|
BLAKE2b-256 checksum How to use checksums |
4a7366de2b04de3627a790fb64eaa64ef2f3a926b469a07fee488b15e3abc391
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency logRelease files / tree_sitter_eskip-0.1.1-cp310-abi3-musllinux_1_2_x86_64.whl
| Download URL | tree_sitter_eskip-0.1.1-cp310-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 23.1 kB |
| Tags | CPython 3.10 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
cc7a16a26e68b5f5c1365cf602b970bb7d08f4474e21b04b368a4ebae8b9c9a4
|
|
BLAKE2b-256 checksum How to use checksums |
6038c591e20751e90f41e9223acdbd9ee521a3518ef74706a144baac31c4f2c1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency logRelease files / tree_sitter_eskip-0.1.1-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
| Download URL | tree_sitter_eskip-0.1.1-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl |
|---|---|
| Size | 23.3 kB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 Linux glibc 2.5+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
729a58cdbfe737ae27f14ff706dc90fc9724d6d3319eea176489f0bd91e8cd12
|
|
BLAKE2b-256 checksum How to use checksums |
02016230edddc440af4ebedef5918cd514a67d222351b24e9de87b25c23580cd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency log