Hybrid-Engine Data Analysis
code-yeongyu/oh-my-openagent
Analyzes CSV, Parquet and JSON data with DuckDB, Polars, numpy and matplotlib, preferring a persistent kernel over repeated one-shot processes.
Effectively use Narwhals to write dataframe-agnostic code that works seamlessly across multiple Python dataframe libraries.
$ npx skills add anam-org/metaxy --skill narwhals -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install anam-org/metaxy narwhals --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/anam-org/metaxy.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/narwhals .claude/skills/narwhals && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "narwhals" agent skill from https://github.com/anam-org/metaxy/tree/main/.claude/skills/narwhals into .claude/skills/narwhals/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "narwhals", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/anam-org/metaxy/tree/main/.claude/skills/narwhalsType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add anam-org/metaxy --skill narwhals -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install anam-org/metaxy narwhals --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/anam-org/metaxy.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/narwhals .agents/skills/narwhals && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "narwhals" agent skill from https://github.com/anam-org/metaxy/tree/main/.claude/skills/narwhals into .agents/skills/narwhals/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "narwhals", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add anam-org/metaxy --skill narwhals -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install anam-org/metaxy narwhals --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/anam-org/metaxy.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/narwhals .cursor/skills/narwhals && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "narwhals" agent skill from https://github.com/anam-org/metaxy/tree/main/.claude/skills/narwhals into .cursor/skills/narwhals/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "narwhals", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/anam-org/metaxy.git --path .claude/skills/narwhals--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add anam-org/metaxy --skill narwhals -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install anam-org/metaxy narwhals --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/anam-org/metaxy.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/narwhals .gemini/skills/narwhals && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "narwhals" agent skill from https://github.com/anam-org/metaxy/tree/main/.claude/skills/narwhals into .gemini/skills/narwhals/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "narwhals", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install anam-org/metaxy narwhalsInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add anam-org/metaxy --skill narwhals -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/anam-org/metaxy.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/narwhals .github/skills/narwhals && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "narwhals" agent skill from https://github.com/anam-org/metaxy/tree/main/.claude/skills/narwhals into .github/skills/narwhals/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "narwhals", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add anam-org/metaxy --skill narwhals -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install anam-org/metaxy narwhals --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/anam-org/metaxy.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/narwhals .opencode/skills/narwhals && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "narwhals" agent skill from https://github.com/anam-org/metaxy/tree/main/.claude/skills/narwhals into .opencode/skills/narwhals/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "narwhals", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
narwhalsEffectively use Narwhals to write dataframe-agnostic code that works seamlessly across multiple Python dataframe libraries.
Narwhals is an agent skill from anam-org/metaxy. Effectively use Narwhals to write dataframe-agnostic code that works seamlessly across multiple Python dataframe libraries. Write correct type annotations for code using Narwhals.
Its SKILL.md is about 3.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Data & Analytics, covering DataFrames. It works with Python and Polars. The repository describes itself as: Pluggable metadata management framework for versioned incremental multimodal data/ML pipelines. The licence is Apache-2.0.
6 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 8337842. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are python).
From the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
narwhals-dev.github.ioFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Narwhals loads about 3.3k tokens when it runs. Until then it costs about 47 tokens; SKILL.md has 1,074 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from anam-org/metaxy at commit 8337842, republished under its Apache-2.0 licence (© anam-org). 1,074 words, ~3,328 tokens.
.claude/skills/narwhals/SKILL.md (or your agent's skills folder).Narwhals is a lightweight, zero-dependency compatibility layer for dataframe libraries in Python that provides a unified interface across different backends.
Docs: https://narwhals-dev.github.io/narwhals/
Narwhals enables writing dataframe-agnostic code that works seamlessly across multiple Python dataframe libraries:
Full API Support:
Lazy-Only Support:
Why Narwhals?
Target Use Case: Anyone building libraries, applications, or services that consume dataframes and need complete backend independence.
import narwhals as nw
# 1. Convert to Narwhals
df_nw = nw.from_native(df) # Works with pandas, Polars, PyArrow, etc.
# 2. Perform operations using Polars-like API
result = df_nw.select(a_sum=nw.col("a").sum(), a_mean=nw.col("a").mean(), b_std=nw.col("b").std())
# 3. Convert back to original library
result_native = result.to_native()Simplifies function definitions for automatic conversion:
@nw.narwhalify
def my_func(df: IntoDataFrameT):
return df.select(nw.col("a").sum(), nw.col("b").mean()).filter(nw.col("a") > 0)
# Automatically handles conversion to/from Narwhals
result = my_func(pandas_df) # Works!
result = my_func(polars_df) # Also works!from_native(df, ...): Convert native DataFrame/Series to Narwhals objectpass_through, backend, eager_only, allow_seriesto_native(nw_obj): Convert Narwhals object back to native library typenarwhalify(): Decorator for automatic dataframe-agnostic functionsnew_series(name, values, dtype): Create a new Seriesfrom_dict(data): Create DataFrame from dictionaryfrom_dicts(data): Create DataFrame from sequence of dictionariesEager Loading:
read_csv(source, **kwargs): Read CSV file into DataFrameread_parquet(source, **kwargs): Read Parquet file into DataFrameLazy Loading:
scan_csv(source, **kwargs): Lazily scan CSV filescan_parquet(source, **kwargs): Lazily scan Parquet filesum(), mean(), min(), max(), median()sum_horizontal(), mean_horizontal(), etc.col(name): Reference column by namelit(value): Create literal expressionwhen(condition): Create conditional expressionformat(template, *args): Format expression as stringgenerate_temporary_column_name(): Generate unique column namesget_native_namespace(obj): Get the native library of an objectshow_versions(): Print debugging informationcolumns: List of column namesschema: Ordered mapping of column names to dtypesshape: Tuple of (rows, columns)implementation: Name of native implementationselect(*exprs): Select columns using expressionswith_columns(*exprs): Add or modify columnsdrop(*columns): Remove specified columnsrename(mapping): Rename columnsfilter(predicate): Filter rows based on conditionshead(n): Get first n rowstail(n): Get last n rowssample(n): Randomly sample n rowsdrop_nulls(): Drop rows with null valuesunique(): Remove duplicate rowsis_empty(): Check if DataFrame has no rowsis_duplicated(): Identify duplicated rowsis_unique(): Identify unique rowsnull_count(): Count null values per columnestimated_size(): Estimate memory usagesort(*by): Sort by one or more columnsgroup_by(*by): Group by columns for aggregationjoin(other, on, how): Perform SQL-style joinspivot(on, index, values): Create pivot tableexplode(*columns): Expand list columns to long formatlazy(): Convert to LazyFrameto_native(): Convert to original library typeto_numpy(): Convert to NumPy arrayto_pandas(): Convert to pandas DataFrameto_polars(): Convert to Polars DataFrameclone(): Create a copyLazyFrame provides the same API as DataFrame but with lazy evaluation:
collect(): Materialize the LazyFrame into a DataFramecollect_schema(): Get schema without collecting datasink_parquet(path): Write results directly to ParquetAll DataFrame methods are available on LazyFrame:
select(), filter(), with_columns(), drop()group_by(), join(), sort(), unique()head(), tail(), top_k()gather_every(): Select rows at regular intervalsunpivot(): Convert from wide to long formatwith_row_index(): Add row index columnpipe(): Apply function to LazyFrameExpressions are the building blocks for column operations.
nw.col("column_name") # Reference column
nw.lit(42) # Literal valuefilter(predicate): Filter elementsis_in(values): Check membershipis_between(lower, upper): Check rangedrop_nulls(): Remove nullscount(): Count non-null elementsnull_count(): Count null valuesn_unique(): Count unique valuessum(), mean(), median(): Statistical aggregationsmin(), max(): Extremesstd(), var(): Spread measuresquantile(q): Quantile valuesMathematical:
abs(): Absolute valueround(), floor(), ceil(): Roundingsqrt(), log(), exp(): Mathematical functionsType/Value Operations:
cast(dtype): Change data typefill_null(value): Replace null valuesreplace_strict(old, new): Replace specific valuesWindow Operations:
rolling_mean(window_size): Moving averagerolling_sum(window_size): Moving sumrolling_std(window_size): Moving standard deviationshift(n): Shift values by n positionsover(*by): Compute expression over groupsRanking/Uniqueness:
rank(): Assign ranksunique(): Get unique valuesis_duplicated(): Identify duplicatesis_first_distinct(): Mark first distinct occurrencesExpressions have specialized namespaces for specific data types:
String Operations (Expr.str)
DateTime Operations (Expr.dt)
List Operations (Expr.list)
Categorical Operations (Expr.cat)
Struct Operations (Expr.struct)
Name Operations (Expr.name)
Series represents a single column:
shape, dtype, namestr, dt, list, cat, structFull docs: narwhals.typing
TLDR:
DataFrameT module-attribute
DataFrameT = TypeVar('DataFrameT', bound='DataFrame[Any]') TypeVar bound to Narwhals DataFrame.
Use this if your function can accept a Narwhals DataFrame and returns a Narwhals DataFrame backed by the same backend.
Examples:
>>> import narwhals as nw
>>> from narwhals.typing import DataFrameT
>>> @nw.narwhalify
>>> def func(df: DataFrameT) -> DataFrameT:
... return df.with_columns(c=df["a"] + 1)
Frame module-attributeFrame: TypeAlias = Union["DataFrame[Any]", "LazyFrame[Any]"] Narwhals DataFrame or Narwhals LazyFrame.
Use this if your function can work with either and your function doesn't care about its backend.
Examples:
>>> import narwhals as nw
>>> from narwhals.typing import Frame
>>> @nw.narwhalify
... def agnostic_columns(df: Frame) -> list[str]:
... return df.columns
FrameT module-attributeFrameT = TypeVar( "FrameT", "DataFrame[Any]", "LazyFrame[Any]" ) TypeVar bound to Narwhals DataFrame or Narwhals LazyFrame.
Use this if your function accepts either nw.DataFrame or nw.LazyFrame and returns an object of the same kind.
Examples:
>>> import narwhals as nw
>>> from narwhals.typing import FrameT
>>> @nw.narwhalify
... def agnostic_func(df: FrameT) -> FrameT:
... return df.with_columns(c=nw.col("a") + 1)IntoDataFrame module-attribute
IntoDataFrame: TypeAlias = NativeDataFrame Anything which can be converted to a Narwhals DataFrame.
Use this if your function accepts a narwhalifiable object but doesn't care about its backend.
Examples:
>>> import narwhals as nw
>>> from narwhals.typing import IntoDataFrame
>>> def agnostic_shape(df_native: IntoDataFrame) -> tuple[int, int]:
... df = nw.from_native(df_native, eager_only=True)
... return df.shapeIntoDataFrameT module-attribute
IntoDataFrameT = TypeVar( "IntoDataFrameT", bound=IntoDataFrame ) TypeVar bound to object convertible to Narwhals DataFrame.
Use this if your function accepts an object which can be converted to nw.DataFrame and returns an object of the same class.
Examples:
>>> import narwhals as nw
>>> from narwhals.typing import IntoDataFrameT
>>> def agnostic_func(df_native: IntoDataFrameT) -> IntoDataFrameT:
... df = nw.from_native(df_native, eager_only=True)
... return df.with_columns(c=df["a"] + 1).to_native()result = df.group_by("category").agg(
count=nw.col("id").count(),
total=nw.col("amount").sum(),
average=nw.col("amount").mean(),
)result = df.with_columns(category=nw.when(nw.col("value") > 100).then(nw.lit("high")).otherwise(nw.lit("low")))result = df1.join(
df2,
on="key_column",
how="left", # inner, left, outer, cross
)result = (
df.filter(nw.col("status") == "active")
.select("user_id", "amount")
.group_by("user_id")
.agg(total=nw.col("amount").sum())
.sort("total", descending=True)
.head(10)
)Use @nw.narwhalify for library functions: Simplifies API and handles conversion automatically
Prefer expressions over method chaining: More flexible and composable
# Good
df.select(nw.col("a").sum(), nw.col("b").mean())
# Also fine, but less composable
df.select("a", "b")Use lazy evaluation when possible: Better performance for complex pipelines
result = df.lazy().select(...).filter(...).collect()Always convert back to native: Remember to call .to_native() when returning from library functions (unless using @narwhalify)
Type hint your functions: Use IntoDataFrame and FrameT for better IDE support
Check supported backends: Some operations may not be available on all backends
Zero Dependencies: Narwhals has no dependencies, keeping it lightweight
Polars API Subset: Uses Polars-style API but may not support all Polars features
Backend Limitations: Some backends (lazy-only) have restricted functionality
Checking whether a Narwhals frame is a Polars frame:
import polars as pl
import narwhals as nw
df_native = pl.DataFrame({"a": [1, 2, 3]})
df = nw.from_native(df_native)
df.implementation.is_polars()Asserting series equality:
import pandas as pd
import narwhals as nw
from narwhals.testing import assert_series_equal
s1 = nw.from_native(pd.Series([1, 2, 3]), series_only=True)
s2 = nw.from_native(pd.Series([1, 5, 3]), series_only=True)
assert_series_equal(s1, s2)
Traceback (most recent call last):
...
AssertionError: Series are different (exact value mismatch)
[left]:
┌───────────────┐
|Narwhals Series|
|---------------|
| 0 1 |
| 1 2 |
| 2 3 |
| dtype: int64 |
└───────────────┘
[right]:
┌───────────────┐
|Narwhals Series|
|---------------|
| 0 1 |
| 1 5 |
| 2 3 |
| dtype: int64 |
└───────────────┘© anam-org, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/narwhals of anam-org/metaxy.
Open the folder on GitHubat commit 8337842
Narwhals next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Narwhals this skillanam-org/metaxy | 124 | — | ~3.3k | Automated safety check: Pass | Apache-2.0 | |
| Hybrid-Engine Data Analysiscode-yeongyu/oh-my-openagent | 70k | — | ~1.4k | Automated safety check: Pass | Custom licence | |
| Optimuskgmims-harvard/OptimusKG | 147 | — | ~1.9k | Automated safety check: Pass | MIT | |
| PolarsK-Dense-AI/scientific-agent-skills | 48k | 1 repos | ~3.3k | Automated safety check: Pass | MIT | |
| Ingesting Dataancoleman/ai-design-components | 525 | — | ~1.9k | Automated safety check: Pass | MIT | |
| Transforming Dataancoleman/ai-design-components | 525 | — | ~3k | Automated safety check: Pass | MIT |
code-yeongyu/oh-my-openagent
Analyzes CSV, Parquet and JSON data with DuckDB, Polars, numpy and matplotlib, preferring a persistent kernel over repeated one-shot processes.
mims-harvard/OptimusKG
Guide for using OptimusKG, the biomedical knowledge graph, through the optimuskg Python client.
K-Dense-AI/scientific-agent-skills
High-performance DataFrame library for Python ETL, analytics, and pandas migration.
ancoleman/ai-design-components
Data ingestion patterns for loading data from cloud storage, APIs, files, and streaming sources into databases.
ancoleman/ai-design-components
Transform raw data into analytical assets using ETL/ELT patterns, SQL (dbt), Python (pandas/polars/PySpark), and orchestration (Airflow).
Edwardvaneechoud/Flowfile
Deep dive into flowfileframe — the Polars-LazyFrame-shaped Python API that builds an in-process flowfilecore FlowGraph as a side effect of every method call — covering the FlowFrame/Expr internals…
anam-org/metaxy
This skill should be used when the user asks to "define a feature", "create a BaseFeature class", "track feature versions", "set up metadata store", "field-level lineage", "FieldSpec", "FeatureDep"…
anam-org/metaxy
This skill should be used when the user asks to "add a tach module", "configure tach layers", "define module boundaries", "set up interfaces", "run tach check", "check module boundaries", "tach…
anam-org/metaxy
Self-reflect on the current session to identify mistakes and propose improvements to .claude configuration (CLAUDE.md, hooks, skills).
anam-org/metaxy
Write YAML front matter for documentation pages with appropriate titles and descriptions for social cards.
anam-org/metaxy
Use Hypothesis for property-based testing to automatically generate comprehensive test cases, find edge cases, and write more robust tests with minimal example shrinking.
anam-org/metaxy
Use Sybil for testing code examples in documentation and docstrings.
Categories
Effectively use Narwhals to write dataframe-agnostic code that works seamlessly across multiple Python dataframe libraries. Narwhals is an agent skill from anam-org/metaxy. Effectively use Narwhals to write dataframe-agnostic code that works seamlessly across multiple Python dataframe libraries.
Narwhals fits situations like: tasks that involve DataFrames.
Run `npx skills add anam-org/metaxy --skill narwhals -a claude-code`. Or copy the skill folder (.claude/skills/narwhals in anam-org/metaxy) into .claude/skills/narwhals in your project. Claude Code loads it when a task matches its description.
Run `npx skills add anam-org/metaxy --skill narwhals -a codex`. Or copy the skill folder (.claude/skills/narwhals in anam-org/metaxy) into .agents/skills/narwhals in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add anam-org/metaxy --skill narwhals -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/narwhals, .gemini/skills/narwhals, .github/skills/narwhals and .opencode/skills/narwhals in your project.
SKILL.md names no scripts, command-line tools or credentials: Narwhals is instructions for the agent only. Our summary lists: Python 3.
SKILL.md names 1 domain. As links in the text: narwhals-dev.github.io. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Narwhals is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.3k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Narwhals: Hybrid-Engine Data Analysis (code-yeongyu/oh-my-openagent, 70k stars), Optimuskg (mims-harvard/OptimusKG, 147 stars), Polars (K-Dense-AI/scientific-agent-skills, 48k stars) and Ingesting Data (ancoleman/ai-design-components, 525 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
anam-org (a GitHub organization) maintains it in anam-org/metaxy, which has 124 GitHub stars. The repository holds 8 skills in this directory. The repository was last updated on September 30, 2026.
Source: anam-org/metaxy on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.