Open-source project
l1xnan/duckling avatar
l1xnan/duckling

Duckling is a desktop viewer for the data you actually have lying around

A fast viewer for CSV/Parquet files and databases such as DuckDB, SQLite, PostgreSQL, MySQL, Clickhouse, etc., base on Tauri

582 stars32 forksTypeScriptMIT

At a glance

What is it?
Duckling is a Tauri desktop application for browsing parquet, CSV and JSON files and for connecting to DuckDB, SQLite, PostgreSQL, MySQL and ClickHouse, with a canvas rendered grid, a SQL editor with template variables, pivot tables, column profiling and export. The repository itself warns that it is unstable and in active development.
Who is it for?
Duckling earns its place for someone who has a parquet file or a local DuckDB database and wants to look at it now, without a Python environment, a notebook or a web upload, and for anyone poking at a Postgres or MySQL instance who wants a lightweight client rather than a full administration tool.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A local viewer, and it says what it is not

Duckling is a lightweight desktop application built with Tauri, designed for quickly browsing parquet, CSV and JSON file data and various databases, and the project description adds that beyond browsing it ships a SQL editor, pivot tables, column profiling, value inspection and data export so you can explore and analyse data without leaving the app. What is more useful is the sentence that follows in the readme, that the current objective of the project is not to develop a fully functional database management tool but rather to facilitate quick browsing and lightweight analysis of various types of data. That is a scope statement, and it is the one to hold on to, because a lightweight viewer and a database client diverge quickly in the features that matter for a production server, and in the risk of touching one. The top of the readme leads with a warning that the project is actively in development and currently unstable, and the package version is a three-part 0.59.3, which says the same thing. For a tool whose whole appeal is being quick and disposable, that combination is honest rather than alarming.

The grid is canvas rendered and meant for wide tables

The data browsing feature is a canvas rendered result grid with pagination, column hiding, computed SQL columns, transpose, result filtering and per-cell value inspection, and the dependency list explains why it is built that way. The grid comes from a canvas table library, and the virtualisation and table packages for React sit alongside it, which is the combination you would expect for a component that has to scroll a hundred thousand rows without dropping frames. Canvas rendering also explains the copy formats, because the clipboard contents are not text nodes you can select, so the app offers an explicit set of conversions: plain text, CSV or TSV with or without a header, a Markdown table, an HTML table and JSON. That is a longer list than most applications need, and it is a sensible response to a canvas grid, since the user cannot do what they would normally do by dragging across a selection. The pivot table feature is the other heavy piece, with row and column dimensions and measures that include count, sum, average, minimum and maximum, high cardinality warnings when a dimension will produce too many groups, copy-SQL support so you can take the generated query back to the editor, percentage display in the front end and sorting on a column header.

SQL templates are the feature that makes the editor worth using

The SQL editor is a Monaco based component with schema aware autocomplete, run, format and EXPLAIN actions, SQL bookmarks and an optional split mode that runs a statement per selection, off by default and toggled from the toolbar. On top of that sits the template system, which is the most interesting design decision in the application. You write Jinja2 style placeholders in your SQL, declare the values in a YAML block comment above the statement, and the backend expands every combination and opens a result tab for each one.

sql
/*
@vars
schema: public
table:
  - orders
  - order_items
  - payments
*/

SELECT COUNT(*) FROM {{ schema }}.{{ table }}

The workflow it supports is the one that usually defeats people. You write a query once against a set of tables, and instead of copying the statement three times you run it three times. If a placeholder has no value yet, a dialog asks for one value per line, and there is a checkbox to write the filled values back into the SQL as a variables comment so the next run needs no dialog. A toolbar button generates a scaffold for all the placeholders in a selection, and a second example shows the cartesian case, with a schema and a region producing one result per combination. The parser for the SQL is a tree-sitter grammar for SQL, which is why the autocomplete knows the shape of a statement rather than guessing from keywords.

Profiling and value inspection fill the gaps a grid leaves

The column profile gives per-column statistics, namely the total, the null ratio, the distinct count and the minimum and maximum, plus the distribution of values with a count and a percentage of matching rows, shown as a table and a bar chart, and right-clicking a value filters the parent view by it. The value viewer inspects a single cell in raw and JSON form, with a calculate tab for statistics over the current selection, minimum, maximum, mean and so on, exported as Markdown. That combination, profiling for the shape of a column and inspection for one value, is the pair of features that a spreadsheet or a notebook would give you, and having them in the same window as the query that produced the data is what saves the round trip. The export feature covers the current result and writes CSV, TSV, JSON, Parquet and XLSX with options for delimiter, header and compression, which is the format set a data engineer actually needs rather than a single default.

DuckDB and SQLite are native, the rest are experimental

The connector list is where the scoping shows. Implemented are DuckDB, by opening a database file with an optional working path, DuckDB over a Quack connection using a URI and a token, a data folder you pick to browse parquet and CSV files, SQLite by opening a database file, MySQL and PostgreSQL with host, port, database, user and password, the latter with an SSL mode, and ClickHouse over its HTTP interface. Experimental and not heavily tested are PostgreSQL, MySQL and ClickHouse, plus Doris and StarRocks over the MySQL protocol on the usual port. Beyond the connections there are two entry points that matter in practice. Opening a .duckdb or .parquet file launches Duckling directly through a file association, so the application is what a double click opens, and an SSH tunnel is available for MySQL and PostgreSQL using reusable profiles or manual configuration. Connection details can be exported and imported as JSON, with an option to encrypt the secrets under a master password, which is the sort of feature that separates a personal tool from one you can hand to a colleague.

A Rust core in a Cargo workspace, a TypeScript front end

The repository is a pnpm workspace with a Vite front end and a Cargo workspace beside it, and the Cargo file has two members, the Tauri application and a separate connector crate, which is the sensible split since the database connections are the part that wants to be a library. The TypeScript side carries the Tauri API and plugins, the Monaco editor, the canvas table, the tree-sitter SQL grammar, the form and state libraries, and the internationalisation packages with a Lingui configuration and extract and compile scripts, which is a sign that the interface is translated rather than English only, and the readme links a Chinese version of the readme as well. Linting is split between the TypeScript compiler and oxlint, with a separate formatter configuration, and the tests run on vitest. There is also a website directory with its own scripts for a documentation site, an AGENTS.md file, a changelog, and a components manifest, which together suggest a project that is being developed with an assistant in the loop and keeps its own component inventory in the repository.

Unsigned on macOS, self updating elsewhere

Two operational details are worth knowing before you install. The macOS build is unsigned and not notarized, so Gatekeeper blocks the first launch, and the documented workaround is to clear the quarantine attribute once.

bash
sudo xattr -rd com.apple.quarantine /Applications/Duckling.app

The second is the install location. The readme says to choose an empty folder or create a new one, not to put data files in the installation path, and to avoid selecting a non-empty folder, because during uninstallation, if you choose to clear data files, the entire folder is deleted, including files that do not belong to the software. That is a sharp edge in an installer and worth reading twice. Updates work two ways, with an automatic check on startup that downloads, installs and relaunches, which can be turned off in the settings, and a manual check in the same panel. Both use a signed release manifest, and the update source is configurable between the official GitHub releases and a mirror described as better for connectivity in mainland China, with an optional proxy for the updater requests. The release cadence is fast, with 0.59.1, 0.59.2 and 0.59.3 in the last six weeks.

Editorial conclusion

Duckling earns its place for someone who has a parquet file or a local DuckDB database and wants to look at it now, without a Python environment, a notebook or a web upload, and for anyone poking at a Postgres or MySQL instance who wants a lightweight client rather than a full administration tool. It is the wrong choice for a database administration workflow, because the project states its objective is not to develop a fully functional database management tool, and it is the wrong choice for a team that needs a signed, notarised build, since the macOS app is unsigned and the readme tells you to strip the quarantine attribute manually. Verify three things before you rely on it: whether the database you need is on the supported list or the experimental one, since PostgreSQL, MySQL and ClickHouse are described as not heavily tested, that the update channel you use is one you trust, because the app can self update from either the official releases or a mirror, and that you install it into an empty folder, since the readme warns that choosing to clear data files on uninstall deletes the whole folder. The licence is MIT, the newest release is v0.59.3 from 2026-10-20, and the last push was on the same day.

Frequently asked questions

Which data sources does Duckling support?

Implemented connectors cover DuckDB files, DuckDB over a Quack URI with a token, a data folder of parquet and CSV files, SQLite files, MySQL, PostgreSQL with an SSL mode, and ClickHouse over HTTP. Doris and StarRocks are listed as experimental, and PostgreSQL, MySQL and ClickHouse are described as not heavily tested.

What are SQL templates in Duckling?

You write Jinja2 style placeholders in your SQL and declare the values in a YAML block comment above the statement. The backend expands every combination and opens a result tab for each one, and a toolbar button can generate the variables scaffold for a selection.

What can Duckling export and copy?

The current result can be exported as CSV, TSV, JSON, Parquet or XLSX with options for delimiter, header and compression, and a selection can be copied as plain text, CSV or TSV with or without a header, a Markdown table, an HTML table or JSON.

Why does Duckling not start on macOS?

The macOS build is unsigned and not notarized, so Gatekeeper blocks the first launch. The documented workaround is to clear the quarantine attribute once with the xattr command, and the install instructions also warn to install into an empty folder because clearing data files on uninstall deletes the whole folder.

Official sources

  1. l1xnan/duckling on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/l1xnan-duckling.svg)](https://hysenlabs.com/projects/l1xnan-duckling)

Was this useful?