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.
# 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# 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@latestGOEXPERIMENT=simd go install github.com/Gaurav-Gosain/golars/cmd/golars@latestEnables 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.
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)
}The golars binary wraps an interactive REPL plus scriptable
subcommands. golars help lists every one.
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.mdgolars 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 rowsgolars browse trades.csvVim-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.
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.
golars diff --key ts trades.csv trades-v2.csvgolars convert trades.csv trades.parquet
golars convert trades.parquet trades.ndjsonCSV, TSV, Parquet, Arrow/IPC, JSON, NDJSON. All pairs work.
# 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.gogolars explain --profile my-pipeline.glr
golars explain --trace trace.json my-pipeline.glr # chrome://tracinggolars-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 | bashPin 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.
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.
Two ways into the notebook:
golars-kernel install # registers a .glr kernel; pick "golars (.glr)" in JupyterLabgolars-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.
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 5The 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.
- 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.
| 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 |
| 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 |
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 harnessEvery test uses a testutil.CheckedAllocator so buffer leaks fail
the suite.
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- 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.
MIT. See LICENSE.











