Pure-Go DataFrames modeled on polars, built on Apache Arrow. No cgo.
  • Go 76.5%
  • C 10%
  • TypeScript 3.9%
  • MDX 3%
  • Assembly 2.5%
  • Other 3.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Gaurav Gosain 98fa9e84a0 jupyterlab-golars: prebuilt labextension for .glr highlighting
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.
2026-04-25 13:58:02 +04:00
.github/workflows ci(release): skip cargo install, fetch wasm-tools + tree-sitter prebuilts 2026-04-25 12:36:35 +04:00
bench initial commit 2026-04-24 19:32:40 +04:00
browse initial commit 2026-04-24 19:32:40 +04:00
cmd jupyter: ANSI-aware trailing-table strip 2026-04-25 13:25:15 +04:00
compute initial commit 2026-04-24 19:32:40 +04:00
dataframe initial commit 2026-04-24 19:32:40 +04:00
docs docs(jupyter): add LSP integration + theme + highlighting sections 2026-04-25 13:44:57 +04:00
docs-site jupyterlab-golars: prebuilt labextension for .glr highlighting 2026-04-25 13:58:02 +04:00
dtype initial commit 2026-04-24 19:32:40 +04:00
editors jupyterlab-golars: prebuilt labextension for .glr highlighting 2026-04-25 13:58:02 +04:00
eval initial commit 2026-04-24 19:32:40 +04:00
examples script/transpile: chain pipelines, dedupe display boilerplate, group imports 2026-04-25 10:12:05 +04:00
expr godoc: polars-style hover docs for the public API surface 2026-04-25 00:58:04 +04:00
internal initial commit 2026-04-24 19:32:40 +04:00
io initial commit 2026-04-24 19:32:40 +04:00
jupyter/render jupyter: render HTML on every cell, theme-aware CSS, skip stale focus 2026-04-25 12:47:31 +04:00
lazy godoc: polars-style hover docs for the public API surface 2026-04-25 00:58:04 +04:00
repl initial commit 2026-04-24 19:32:40 +04:00
schema initial commit 2026-04-24 19:32:40 +04:00
script docs: minor punctuation tidy in jupyter integration prose 2026-04-25 12:24:56 +04:00
selector initial commit 2026-04-24 19:32:40 +04:00
series initial commit 2026-04-24 19:32:40 +04:00
sql initial commit 2026-04-24 19:32:40 +04:00
stream initial commit 2026-04-24 19:32:40 +04:00
vhs initial commit 2026-04-24 19:32:40 +04:00
.gitignore initial commit 2026-04-24 19:32:40 +04:00
.goreleaser.yaml jupyter: native .glr kernel + GoNB-friendly DataFrame renderers 2026-04-25 11:20:59 +04:00
AGENTS.md initial commit 2026-04-24 19:32:40 +04:00
CLAUDE.md initial commit 2026-04-24 19:32:40 +04:00
Dockerfile initial commit 2026-04-24 19:32:40 +04:00
go.mod jupyter: native .glr kernel + GoNB-friendly DataFrame renderers 2026-04-25 11:20:59 +04:00
go.sum jupyter: native .glr kernel + GoNB-friendly DataFrame renderers 2026-04-25 11:20:59 +04:00
go.work initial commit 2026-04-24 19:32:40 +04:00
go.work.sum initial commit 2026-04-24 19:32:40 +04:00
golars.go godoc: polars-style hover docs for the public API surface 2026-04-25 00:58:04 +04:00
golars.png initial commit 2026-04-24 19:32:40 +04:00
golars_banner.png cmd/golars: --preview-format markdown for LSP hover tooltips 2026-04-24 22:34:31 +04:00
golars_lsp.png initial commit 2026-04-24 19:32:40 +04:00
golars_test.go initial commit 2026-04-24 19:32:40 +04:00
install-zed-extension.sh zed-golars: ship prebuilt extension package + curl install that just works 2026-04-25 09:11:14 +04:00
install.sh jupyter: native .glr kernel + GoNB-friendly DataFrame renderers 2026-04-25 11:20:59 +04:00
LICENSE initial commit 2026-04-24 19:32:40 +04:00
Makefile initial commit 2026-04-24 19:32:40 +04:00
NOTICE initial commit 2026-04-24 19:32:40 +04:00
README.md jupyter: native .glr kernel + GoNB-friendly DataFrame renderers 2026-04-25 11:20:59 +04:00
selectexpr_test.go initial commit 2026-04-24 19:32:40 +04:00
SKILLS.md docs: document with expression DSL + golars transpile 2026-04-25 00:35:32 +04:00
staticcheck.conf ci: drop trivy, skip staticcheck style noise, fix Windows docDir 2026-04-24 19:47:27 +04:00

golars

golars

Latest Release GoDoc CI Ask DeepWiki

Pure-Go DataFrames modeled on polars, built on Apache Arrow. No cgo.

golars in action: SQL query, output format switching, TUI browser

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

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 / peek / stats

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

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

golars | jq | awk | round-trip

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

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

Format conversion

golars convert

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

.glr script run

# 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

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

Editor support

golars-lsp in Neovim: inlay hints showing frame shape after every .glr statement

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

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, plus df.Corr / df.Cov matrices.
  • 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.