- Go 76.5%
- C 10%
- TypeScript 3.9%
- MDX 3%
- Assembly 2.5%
- Other 3.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Minimal JupyterLab 4 labextension that registers a CodeMirror 6
StreamLanguage for `.glr` cells. Tokenises the dispatcher's command
set (load / filter / groupby / show / ...) as keywords, structural
modifiers (as / on / asc / inner / left / cross / is_null / like) as
modifiers, atoms (true / false / null) and `col:op:alias` agg specs
as their own token classes so the active JupyterLab theme paints them
distinctly.
Bonus: the language registers the `text/x-glr` mime + `glr` file
extension on the IEditorLanguageRegistry, which gives jupyter-lsp the
hook it needs to route `textDocument/*` requests through to
golars-lsp - so diagnostics, hover, and completion in glr cells now
work alongside the highlighting.
Build: pure prebuilt extension (no server-side hooks). hatch-jupyter-builder
runs `bun run build:prod` which compiles TypeScript and bundles via
@jupyterlab/builder. Distributed as a Python wheel that drops the
prebuilt JS bundle under `share/jupyter/labextensions/`.
Install (current local-checkout flow):
cd editors/jupyterlab-golars
bun install && bun run build:prod
uv tool install jupyterlab \\
--with jupyterlab-lsp --with jupyter-lsp \\
--with catppuccin-jupyterlab --with jupyterlab-night \\
--with-editable editors/jupyterlab-golars
Then `jupyter-lab` (from ~/.local/bin) launches a kit with the
extension, two themes, and LSP wiring.
Also: docs-site/README.md was still describing tuios. Repointed to
golars + regenerated bun.lock so the project name matches package.json.
|
||
| .github/workflows | ||
| bench | ||
| browse | ||
| cmd | ||
| compute | ||
| dataframe | ||
| docs | ||
| docs-site | ||
| dtype | ||
| editors | ||
| eval | ||
| examples | ||
| expr | ||
| internal | ||
| io | ||
| jupyter/render | ||
| lazy | ||
| repl | ||
| schema | ||
| script | ||
| selector | ||
| series | ||
| sql | ||
| stream | ||
| vhs | ||
| .gitignore | ||
| .goreleaser.yaml | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| go.work | ||
| go.work.sum | ||
| golars.go | ||
| golars.png | ||
| golars_banner.png | ||
| golars_lsp.png | ||
| golars_test.go | ||
| install-zed-extension.sh | ||
| install.sh | ||
| LICENSE | ||
| Makefile | ||
| NOTICE | ||
| README.md | ||
| selectexpr_test.go | ||
| SKILLS.md | ||
| staticcheck.conf | ||
Eager and lazy execution with a plan-rewriting optimiser, a streaming
engine, and AVX2/AVX-512 kernels on amd64 and NEON on arm64. A single
go build cross-compiles to Linux, macOS, Windows.
Matches or beats polars 1.39 on most polars-compare workloads,
Arrow-native end to end (no conversion cost talking to polars,
PyArrow, DuckDB), and ships a full terminal stack:
REPL, LSP, formatter, linter, TUI data browser, SQL frontend, an MCP
server for Claude Desktop / Cursor / Windsurf, and a pipe-friendly
.glr scripting language.
Installation
# Homebrew (macOS / Linux)
brew install Gaurav-Gosain/tap/golars
# Arch Linux (AUR)
yay -S golars-bin
# One-shot curl installer (macOS / Linux, amd64 + arm64)
curl -fsSL https://raw.githubusercontent.com/Gaurav-Gosain/golars/main/install.sh | bash
From source
# library + all four CLIs
go install github.com/Gaurav-Gosain/golars/cmd/golars@latest
go install github.com/Gaurav-Gosain/golars/cmd/golars-lsp@latest
go install github.com/Gaurav-Gosain/golars/cmd/golars-mcp@latest
go install github.com/Gaurav-Gosain/golars/cmd/golars-kernel@latest
# or as a dependency in your Go module
go get github.com/Gaurav-Gosain/golars@latest
SIMD build (amd64)
GOEXPERIMENT=simd go install github.com/Gaurav-Gosain/golars/cmd/golars@latest
Enables AVX2/AVX-512 fast paths in the reduce, compare, blend, and arith-lit kernels. The scalar path is a correct fallback on any CPU that lacks SIMD.
Quickstart
package main
import (
"context"
"fmt"
"log"
"github.com/Gaurav-Gosain/golars/dataframe"
"github.com/Gaurav-Gosain/golars/expr"
"github.com/Gaurav-Gosain/golars/lazy"
"github.com/Gaurav-Gosain/golars/series"
)
func main() {
ctx := context.Background()
dept, _ := series.FromString("dept", []string{"eng", "eng", "sales", "ops"}, nil)
salary, _ := series.FromInt64("salary", []int64{100, 120, 80, 70}, nil)
df, _ := dataframe.New(dept, salary)
defer df.Release()
out, err := lazy.FromDataFrame(df).
Filter(expr.Col("salary").Gt(expr.Lit(int64(75)))).
GroupBy("dept").
Agg(expr.Col("salary").Sum().Alias("total")).
Sort("total", true).
Collect(ctx)
if err != nil {
log.Fatal(err)
}
defer out.Release()
fmt.Println(out)
}
CLI
The golars binary wraps an interactive REPL plus scriptable
subcommands. golars help lists every one.
SQL against a file

golars sql 'SELECT symbol, SUM(qty) AS vol FROM trades
GROUP BY symbol ORDER BY vol DESC' trades.csv
# pipe-friendly output formats
golars sql --ndjson '...' trades.csv | jq ...
golars sql --csv '...' trades.csv | awk ...
golars sql --markdown '...' trades.csv >> report.md
Inspecting a file

golars schema trades.csv # columns + dtypes
golars peek trades.csv # schema + head + shape
golars stats trades.csv # describe()-style summary
golars head trades.csv 20 # first 20 rows
Interactive TUI browser

golars browse trades.csv
Vim-style modal grid (NORMAL / VISUAL / COMMAND / FILTER), layout
cloned from maaslalani/sheets.
/ filters, s toggles sort, f freezes a
column, : opens the command prompt (:sort col desc,
:hide col, :goto 12345), ? shows the full legend.
Navigate with h j k l or the
arrow keys; gg / G jump to first / last
row; Ctrl+d / Ctrl+u half-
page scroll; q quits. Cells are pulled lazily from the Arrow
backing store so it scales to tens of millions of rows without copying.
Composing with other tools

Every command speaks -o table|csv|tsv|json|ndjson|markdown|parquet|arrow,
so golars drops straight into a Unix pipeline. --json, --csv, and
friends are shorthand flags.
Diff two files

golars diff --key ts trades.csv trades-v2.csv
Format conversion

golars convert trades.csv trades.parquet
golars convert trades.parquet trades.ndjson
CSV, TSV, Parquet, Arrow/IPC, JSON, NDJSON. All pairs work.
.glr scripting + explain + profile

# vhs/fixtures/pipeline.glr
load vhs/fixtures/people.csv
with monthly = salary / 12 # derive columns via `with`
filter salary > 100000
groupby dept salary:sum:total salary:mean:avg tenure_years:max:max_tenure
sort total desc
head 5
with NAME = EXPR supports arithmetic, comparisons, string methods
(col.str.upper(), contains_regex, like, ...), aggregates,
rolling/EWM windows, casts, and coalesce. See docs/scripting.md
for the full expression grammar.
Convert a .glr script to a standalone Go program:
golars transpile my-pipeline.glr -o main.go --package main
go run main.go

golars explain --profile my-pipeline.glr
golars explain --trace trace.json my-pipeline.glr # chrome://tracing
Editor support

golars-lsp is a stdio Language Server for .glr files. Inlay hints
display the frame shape after every statement, completion covers
commands / frames / column names, hover shows signatures + long-form
docs, and diagnostics flag unknown commands and missing files. Hover
on a # ^? probe line returns a GitHub-flavoured markdown table of
the frame at that point.
Neovim (lazy.nvim, remote):
{
url = "https://github.com/Gaurav-Gosain/golars",
name = "nvim-golars",
ft = "glr",
init = function() vim.filetype.add({ extension = { glr = "glr" } }) end,
config = function()
local root = vim.fn.stdpath("data") .. "/lazy/nvim-golars/editors/nvim-golars"
vim.opt.rtp:prepend(root)
vim.cmd("runtime! ftdetect/*.lua ftdetect/*.vim syntax/*.vim")
require("golars").setup({})
end,
}
See editors/nvim-golars for tree-sitter
integration, per-option config, and a local-checkout variant.
Zed: grammar + LSP client ship as a Zed extension. The installer
drops a prebuilt extension package (extension.wasm + tree-sitter
grammar wasm + language assets) into Zed's installed-extensions
directory, and auto-fetches golars-lsp from the same release if
it's not already on PATH:
curl -fsSL https://raw.githubusercontent.com/Gaurav-Gosain/golars/main/install-zed-extension.sh | bash
Pin a specific version with a positional arg
(... | bash -s -- v0.1.3). After the install completes, restart
Zed (or run zed: reload extensions) and open any .glr file.
VS Code: grammar + LSP client at
editors/vscode-golars.
Model Context Protocol server

golars-mcp is a stdio JSON-RPC server that exposes schema, head,
describe, sql, row_count, and null_counts as MCP tools any
Claude Desktop / Cursor / Windsurf session can call against local
files. See docs/mcp.md for the install walkthrough.
Jupyter
Two ways into the notebook:
golars-kernel install # registers a .glr kernel; pick "golars (.glr)" in JupyterLab
golars-kernel is a native Jupyter kernel for the .glr scripting
language. Frames render as HTML tables, state persists across cells,
tab completion + hover docs work. The kernel speaks the v5.3 wire
protocol over pure-Go ZeroMQ and delegates execution to a long-lived
golars kernel-host subprocess so behaviour matches the REPL exactly.
For Go notebooks via GoNB, the
jupyter/render package produces multi-mimetype output:
import jrender "github.com/Gaurav-Gosain/golars/jupyter/render"
import "github.com/janpfeifer/gonb/gonbui"
gonbui.DisplayHTML(jrender.HTML(df))
See docs/jupyter.md for the full walkthrough.
Performance
The polars-compare bench runs the same
workloads against polars-py, the polars-rs crate, golars-scalar,
and golars-simd in one pass. Categories covered include SumInt64,
MeanFloat64, MinFloat64, GroupBy (single and multi-agg), InnerJoin,
Filter, Take, WhenThenOtherwise, SumOverGroup, RollingSum, and
end-to-end pipelines (filter-groupby-sort).
cd bench/polars-compare
uv run python compare.py --runs 5
The harness prints per-workload throughput in MB/s, typical and conservative ratios vs both polars frontends, and a stability breakdown (solid / noise / loss) so you can see which workloads are reproducibly faster on your hardware.
Library API
- Eager + lazy:
df.Filter(...)for in-place,lazy.FromDataFrame(df).Filter(...).Collect(ctx)for plan-optimised. - Expressions:
Col,Lit,When/Then/Otherwise, binary ops,.Alias,.Cast,.Sum/Min/Max/Mean/Std/Var/Quantile/Skew/Kurtosis/Entropy,.RollingSum/Mean/...,.Over(keys...),.ForwardFill,.Coalesce,.IntRange. - Reshape:
df.Pivot / Unpivot / Transpose / Explode / Unnest / Upsample / PartitionBy / TopK / BottomK / Pipe. - Horizontal:
SumHorizontal / MeanHorizontal / MinHorizontal / MaxHorizontal / AllHorizontal / AnyHorizontal. - Stats:
Skew / Kurtosis / Entropy / PearsonCorr / Covariance / ApproxNUnique, plusdf.Corr / df.Covmatrices. - Optimiser: simplify, predicate pushdown, projection pushdown, slice pushdown, CSE.
- Profiler + tracer:
lazy.NewProfiler()+lazy.WithProfiler(p)for per-node timings;lazy.WithTracer(t)for OTel span integration.
// CSV, Parquet, Arrow/IPC, JSON, NDJSON - file or URL
df, _ := csv.ReadFile(ctx, "trades.csv")
df, _ := parquet.ReadURL(ctx, "https://example.com/trades.parquet")
// Lazy scans defer the open until Collect so the optimiser can push
// projections and filters through the reader
lf := golars.ScanCSV("huge.csv").
Filter(golars.Col("region").EqLit("us")).
Select(golars.Col("symbol"), golars.Col("price"))
out, _ := lf.Collect(ctx)
// Arrow IPC streaming: interop with polars / PyArrow / DuckDB over a
// socket or pipe
sw, _ := golars.NewIPCStreamWriter(conn, firstBatch)
for batch := range batches {
sw.Write(ctx, batch)
}
sw.Close()
// database/sql bridge (any pure-Go driver)
db, _ := sql.Open("sqlite", "data.db")
df, _ := iosql.ReadSQL(ctx, db, "SELECT id, price FROM trades WHERE volume > ?", 100)
See the cookbook for end-to-end recipes and the API surface map for the polars ↔ golars method-level status table.
Tools
| Binary / path | What it is |
|---|---|
cmd/golars |
REPL + run / sql / transpile / fmt / lint / browse / schema / stats / peek / diff / convert / cat / explain / doctor / completion / sample |
cmd/golars-lsp |
stdio Language Server for .glr files |
cmd/golars-mcp |
Model Context Protocol server |
cmd/bench |
polars-compare bench harness |
editors/tree-sitter-golars |
.glr grammar (Neovim, Helix) |
editors/vscode-golars |
VS Code extension (grammar + LSP client) |
editors/nvim-golars |
Neovim plugin |
editors/zed-golars |
Zed extension (grammar + LSP client) |
docs-site/ |
Fumadocs-based website, ships /llms.txt, /llms-full.txt, and /docs-md/<slug> raw-markdown routes for LLM ingestion |
Documentation
| File | What |
|---|---|
docs/cookbook.md |
End-to-end recipes for every major feature |
docs/scripting.md |
.glr language reference |
docs/mcp.md |
Install golars-mcp into Claude Desktop / Cursor / Windsurf |
docs/api-surface.md |
Polars -> golars method-level status table |
docs/api-design.md |
Naming + type philosophy |
docs/architecture.md |
Layered component map + data flow |
docs/parallelism.md |
Morsel engine + worker pool |
docs/memory-model.md |
Refcounts + allocator hooks |
docs/roadmap.md |
Phased delivery plan |
examples/README.md |
Index of runnable demos |
AGENTS.md, CLAUDE.md, SKILLS.md |
Guides for coding agents |
Tests
make test # go test ./...
make test-race # race detector on hot packages
make test-simd # GOEXPERIMENT=simd path
make test-all # the full release gate
make bench # polars-compare harness
Every test uses a testutil.CheckedAllocator so buffer leaks fail
the suite.
Regenerating the GIFs
The demos above are produced by VHS.
See vhs/ for the tape files. CI regenerates them on every
tape-file change.
make -C vhs # rebuild every gif
make -C vhs gif-sql # one at a time
Attribution
- polars by Ritchie Vink (MIT) - behavioural reference. golars mirrors its public API surface and parity-tests against a local clone.
- arrow-go (Apache 2.0) - the only runtime dependency in the core packages; every series is an arrow array.
- sheets by Maas Lalani (MIT) -
grid layout and modal keybindings for the TUI browser in
browse/. - bubble tea and lipgloss (MIT) - the whole Charm stack powers the REPL, browser, and LSP preview.
- VHS (MIT) - tape-driven GIF regeneration for every demo above.
- BurntSushi/toml (MIT) - config loader.
- Goroutine-pool patterns for the parallel radix and filter kernels were informed by DuckDB's and polars's own parallel-radix writeups.
Full per-file attributions live in NOTICE.
License
MIT. See LICENSE.