Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ categories = ["database", "gui"]
# component catalog all come from the same pinned revision. Mixing the
# crates.io release with the Git one would put two incompatible copies of
# `gpui-base` in the build.
gpui-kit = { git = "https://github.com/longbridge/gpui-kit", rev = "13c716b687b47f96a677aaf46c8fa341fa7208da" }
# `tree-sitter-sql`: the SQL editor and the SQL in `.dash` heredocs are the only
# code DuckLocal highlights, so it links that one grammar rather than the set.
gpui-kit = { git = "https://github.com/longbridge/gpui-kit", rev = "13c716b687b47f96a677aaf46c8fa341fa7208da", features = ["tree-sitter-sql"] }
gpui-shell = { git = "https://github.com/longbridge/gpui-kit", rev = "13c716b687b47f96a677aaf46c8fa341fa7208da" }
gpui-component-shell = { git = "https://github.com/longbridge/gpui-kit", rev = "13c716b687b47f96a677aaf46c8fa341fa7208da" }
duckdb = { version = "1", features = ["bundled", "json", "parquet"] }
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Your data stays on your machine: nothing is uploaded, and there is no account.
- Results grid with filtering, cell copy, CSV/Parquet export and built-in charts
- Query history with one-click refill into the editor
- Optional S3 support via httpfs; credentials are session-only
- Light and dark themes, English and 简体中文
- Light and dark themes, four interface sizes (⌘+ / ⌘− / ⌘0), English and 简体中文

## AI CLI and official skill

Expand Down Expand Up @@ -72,7 +72,7 @@ Inspect existing destinations before overwriting. No global configuration is cha

## Documentation

Guides live in [`docs/`](docs/index.md): [getting started](docs/getting-started.md), [data sources](docs/data-sources.md), [S3 and httpfs](docs/s3.md), [SQL editor](docs/sql-editor.md), [schema browser and history](docs/schema-and-history.md), [results and charts](docs/results-and-charts.md), [settings and app data](docs/settings-and-data.md), and [development](docs/development.md).
Guides live in [`docs/`](docs/index.md): [getting started](docs/getting-started.md), a [10-minute tutorial](docs/tutorial.md) with sample data, [troubleshooting](docs/troubleshooting.md), [data sources](docs/data-sources.md), [S3 and httpfs](docs/s3.md), [SQL editor](docs/sql-editor.md), [schema browser and history](docs/schema-and-history.md), [results and charts](docs/results-and-charts.md), [settings and app data](docs/settings-and-data.md), and [development](docs/development.md).

The same pages are published with VitePress. With Node.js 22 or later (24 LTS recommended), run `npm --prefix docs ci`, then `npm --prefix docs run build` to generate `target/docs-site`, or `npm --prefix docs run dev` for local development. CI deploys the site to GitHub Pages whenever `docs/` changes on `main`. See [development](docs/development.md#the-documentation-site) for preview commands and configuration.

Expand Down
4 changes: 2 additions & 2 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ ducklocal warehouse.duckdb # 或已有的 DuckDB 数据库
- 结果表格支持筛选、单元格复制、CSV/Parquet 导出和内置图表
- 查询历史,单击回填编辑器
- 可选 S3 支持(httpfs),凭据仅当前会话有效
- 明暗主题切换,中英文界面
- 明暗主题切换,四档界面大小(⌘+ / ⌘− / ⌘0),中英文界面

## AI CLI 与官方 skill

Expand Down Expand Up @@ -72,7 +72,7 @@ cp -R skills/ducklocal /path/to/your-project/.claude/skills/

## 文档

完整指南在 [`docs/`](docs/zh/index.md):[快速上手](docs/zh/getting-started.md)、[数据源](docs/zh/data-sources.md)、[S3 与 httpfs](docs/zh/s3.md)、[SQL 编辑器](docs/zh/sql-editor.md)、[Schema 浏览与历史](docs/zh/schema-and-history.md)、[结果与图表](docs/zh/results-and-charts.md)、[设置与应用数据](docs/zh/settings-and-data.md)、[开发](docs/zh/development.md)。
完整指南在 [`docs/`](docs/zh/index.md):[快速上手](docs/zh/getting-started.md)、带样例数据的 [10 分钟上手教程](docs/zh/tutorial.md)、[常见问题排查](docs/zh/troubleshooting.md)、[数据源](docs/zh/data-sources.md)、[S3 与 httpfs](docs/zh/s3.md)、[SQL 编辑器](docs/zh/sql-editor.md)、[Schema 浏览与历史](docs/zh/schema-and-history.md)、[结果与图表](docs/zh/results-and-charts.md)、[设置与应用数据](docs/zh/settings-and-data.md)、[开发](docs/zh/development.md)。

这些页面同时会以 VitePress 站点形式发布。需要 Node.js 22 及以上(推荐 24 LTS):`npm --prefix docs ci` 安装依赖,`npm --prefix docs run build` 生成到 `target/docs-site`,`npm --prefix docs run dev` 本地开发。CI 在 `main` 分支的 `docs/` 有改动时自动部署到 GitHub Pages。详见[开发](docs/zh/development.md#文档站)。

Expand Down
27 changes: 18 additions & 9 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ function sidebar(zh = false): DefaultTheme.SidebarItem[] {
return [
{
text: zh ? '入门' : 'Getting started',
items: [item('getting-started', 'Quick start', '快速上手')],
items: [
item('getting-started', 'Install and first query', '安装与第一条查询'),
item('tutorial', 'Your first 10 minutes', '10 分钟上手教程'),
item('troubleshooting', 'Troubleshooting', '常见问题排查'),
],
},
{
text: zh ? '使用指南' : 'Guides',
Expand All @@ -39,13 +43,16 @@ function sidebar(zh = false): DefaultTheme.SidebarItem[] {
],
},
{
text: zh ? '开发' : 'Development',
text: zh ? '自动化与扩展' : 'Automate and extend',
items: [
item('cli', 'AI CLI and official skill', 'AI CLI 与官方 skill'),
item('analysis-app', 'Analysis apps', '分析应用'),
item('development', 'Development guide', '开发指南'),
item('cli', 'CLI and agent skill', 'CLI 与 agent skill'),
item('analysis-app', 'Apps and dashboards', '分析应用与 Dashboard'),
],
},
{
text: zh ? '参与开发' : 'Contributing',
items: [item('development', 'Development guide', '开发指南')],
},
]
}

Expand All @@ -63,8 +70,9 @@ export default defineConfig({
lang: 'en',
themeConfig: {
nav: [
{ text: 'Guide', link: '/getting-started' },
{ text: 'Development', link: '/development' },
{ text: 'Get started', link: '/getting-started' },
{ text: 'Tutorial', link: '/tutorial' },
{ text: 'CLI', link: '/cli' },
{ text: 'Download', link: `${repository}/releases/latest` },
],
sidebar: sidebar(),
Expand All @@ -76,8 +84,9 @@ export default defineConfig({
description: '本地优先的数据查询与分析工作台,原生基于 DuckDB。',
themeConfig: {
nav: [
{ text: '指南', link: '/zh/getting-started' },
{ text: '开发', link: '/zh/development' },
{ text: '快速上手', link: '/zh/getting-started' },
{ text: '教程', link: '/zh/tutorial' },
{ text: 'CLI', link: '/zh/cli' },
{ text: '下载', link: `${repository}/releases/latest` },
],
sidebar: sidebar(true),
Expand Down
4 changes: 2 additions & 2 deletions docs/analysis-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,9 @@ Because it is the loading state, a statement an app only runs on a click is not

A `.dash` file is a dashboard declared as data — query and plot blocks, no JavaScript — for the common case of standard plots over saved queries. The file format and `ducklocal check` validation are in [the CLI guide](cli.md#check-a-dashboard-spec).

Open one like an app: name it on the command line (`ducklocal dashboard.dash`) or drag the file onto the window, and it opens as a dashboard tab beside your queries and apps. The tab runs the spec's queries on the window's own connection — so a dashboard sees connection-local state such as `TEMP` tables, and queues with the editor's queries — and renders each plot as one panel of a vertical stack whose dividers drag to resize. Only read-only statements run: a query that could write (DDL, DML, `COPY`, `ATTACH`, …) is refused before it reaches the connection, so opening a `.dash` file someone sent you cannot change your data. A plot whose query fails shows the reason in its own panel; the rest of the dashboard still draws. The toolbar's reload re-reads the file and re-runs everything, and a reload that fails validation never replaces a working dashboard — the reason appears above it instead. Open dashboards are remembered between launches, exactly like apps.
Open one like an app: choose **Open dashboard…** from the tab strip's `+` menu, name it on the command line (`ducklocal dashboard.dash`), or drag the file onto the window, and it opens as a dashboard tab beside your queries and apps. The tab runs the spec's queries on the window's own connection — so a dashboard sees connection-local state such as `TEMP` tables, and queues with the editor's queries — and renders each plot as one panel of a vertical stack whose dividers drag to resize. Only read-only statements run: a query that could write (DDL, DML, `COPY`, `ATTACH`, …) is refused before it reaches the connection, so opening a `.dash` file someone sent you cannot change your data. A plot whose query fails shows the reason in its own panel; the rest of the dashboard still draws. The toolbar's reload re-reads the file and re-runs everything, and a reload that fails validation never replaces a working dashboard — the reason appears above it instead. Open dashboards are remembered between launches, exactly like apps.

The tab is also an editor: its source view edits the file with completion and diagnostics, and writes back with the save button or ⌘S — a save whose spec no longer validates keeps the last working dashboard up and says why. Outside the GUI, `ducklocal lsp` serves the same completion, diagnostics, hover and go-to-definition to any LSP-capable editor (see [the CLI guide](cli.md#edit-a-dashboard-spec-with-lsp)).
The tab is also an editor: its source view edits the file with syntax highlighting — the SQL in heredocs coloured as it is in the SQL editor — completion and diagnostics, and writes back with the save button or ⌘S — a save whose spec no longer validates keeps the last working dashboard up and says why. Outside the GUI, `ducklocal lsp` serves the same completion, diagnostics, hover and go-to-definition to any LSP-capable editor (see [the CLI guide](cli.md#edit-a-dashboard-spec-with-lsp)).

## Known limits

Expand Down
113 changes: 71 additions & 42 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,27 @@

**[中文](zh/getting-started.md)** · [Docs](index.md)

## Requirements
DuckLocal is a desktop app for asking questions of the data files on your
machine with SQL. There is no server to run, no connection to configure, and
no account — you point it at files and start querying. This page takes you
from download to your first result in about five minutes.

The released build runs on **macOS 12.0 or later, Apple silicon only**. The
distributed disk image is signed and notarized, so it opens without a
Gatekeeper workaround.
## 1. Install {#install}

To build from source you need Rust stable, **1.85.1 or newer**, and a C++
toolchain — DuckDB is compiled from vendored sources. The first build takes a
while and needs a few gigabytes of disk.
You need **macOS 12 or later on Apple silicon** (M1 or newer).

## Install
1. Download [`ducklocal-macos-arm64.dmg`](https://github.com/JetSquirrel/DuckLocal/releases/latest)
from the latest release.
2. Open it and drag **DuckLocal** into **Applications**.
3. Launch DuckLocal from Applications or Spotlight.

**From the disk image.** Download `ducklocal-macos-arm64.dmg`, open it, and
drag `DuckLocal.app` to Applications.
The disk image is signed and notarized by Apple, so it opens without any
Gatekeeper workaround.

**From source.**
::: details Building from source instead
You need Rust stable 1.85.1 or newer and a C++ toolchain (Xcode Command Line
Tools). DuckDB is compiled from vendored sources, so the first build takes
several minutes and a few gigabytes of disk.

```bash
git clone https://github.com/JetSquirrel/DuckLocal
Expand All @@ -26,53 +31,77 @@ cargo build --release
./target/release/ducklocal
```

`cargo run` works too, and is quicker to iterate on. Builds are slow the first
time because of DuckDB; afterwards only DuckLocal itself recompiles.
The binary is `./target/release/ducklocal`; use it wherever this guide says
`ducklocal`. See [Development](development.md) for bundling a `.app`.
:::

## Open your data
## 2. Add the `ducklocal` command (optional) {#add-command}

DuckLocal will open whatever you name on the command line:
Everything in the app works without a terminal. If you also want to open data
from the command line — or let an AI agent run queries with the
[CLI](cli.md) — link the binary inside the app onto your `PATH`:

```bash
ducklocal ./logs/ # every data file under a folder, recursively
ducklocal ./billing.parquet # one file
ducklocal './data/*.csv' # a pattern (quote it, so the shell does not expand it)
ducklocal warehouse.duckdb # or an existing DuckDB database
sudo mkdir -p /usr/local/bin
sudo ln -sf /Applications/DuckLocal.app/Contents/MacOS/ducklocal /usr/local/bin/ducklocal
ducklocal --version
```

You can name several paths at once, and mix them freely.
The link follows the app, so updating DuckLocal in Applications updates the
command too. To remove it: `sudo rm /usr/local/bin/ducklocal`.

## 3. Open some data

There are two more ways in, both equivalent:
The first launch opens on a screen titled **Drop your data in**. From here,
any of these gets data in:

- **Open data…** in the title bar opens a dialog where you type or browse for
paths. An **In-memory** button in that dialog switches to a plain in-memory
workspace with nothing attached.
- **Drag files or folders onto the window.**
- **Drag** CSV, TSV, Parquet, JSON or Excel files — or a whole folder — onto
the window.
- Click **Open files…** or **Open folder…**.
- From a terminal, name the paths:

Every CSV, TSV, Parquet, JSON, or Excel file becomes a queryable relation, and every file is
registered — the next launch starts with the same workspace. See
[Data sources](data-sources.md) for the details.
```bash
ducklocal ./sales.csv # one file
ducklocal ./logs/ # every data file under a folder, recursively
ducklocal './data/*.parquet' # a pattern — quote it so the shell leaves it alone
ducklocal warehouse.duckdb # an existing DuckDB database
```

## Run a query
Each file becomes a view named after the file — `sales.csv` becomes `sales` —
and shows up under **Local files** in the sidebar with its columns and row
count. DuckLocal reads the files where they are; nothing is copied or
uploaded.

The workspace opens with one query tab. Type SQL and press **⌘↵** (Cmd+Enter)
to run it. `Run`, `Format`, and `EXPLAIN` sit in the toolbar above the editor.
Files you open are remembered, so the next launch starts with the same
workspace. [Data sources](data-sources.md) has the details on formats,
folders, patterns and databases.

Results appear in the panel below, as a grid or a chart.
::: tip No data handy?
The [first-10-minutes tutorial](tutorial.md) walks through a small sample
file step by step.
:::

## The first-run screen
## 4. Run a query

Click **New query** (or open some data — the editor appears on its own). Type
SQL and press **⌘↵** (Cmd+Enter):

```sql
SELECT * FROM sales LIMIT 20;
```

When nothing is attached and nothing has been registered yet, the workspace
shows three buttons instead of the editor: **Open file…**, **Open folder…**,
and **New query**. Pick one of the first two to attach data, or **New query**
to get an editor anyway.
The result appears in the panel under the editor. Switch it to **Chart** for a
quick picture, or export it as CSV or Parquet. The toolbar above the editor
has **Run**, **Format** and **EXPLAIN**.

One quirk worth knowing: on this screen **⌘↵** reveals the editor rather than
running anything.
A shortcut worth knowing: in the sidebar, click the play button beside a
table to get a ready-made `SELECT * … LIMIT 100`, or a column name to select
just that column.

## Where to go next

- [Your first 10 minutes](tutorial.md) — a guided tour with sample data
- [Data sources](data-sources.md) — formats, folders, patterns, databases
- [SQL editor](sql-editor.md) — tabs, shortcuts, EXPLAIN
- [Results and charts](results-and-charts.md) — what you can do with a result
- [Settings and app data](settings-and-data.md) — where everything is stored
- [SQL editor](sql-editor.md) — tabs, shortcuts, autocompletion, EXPLAIN
- [Results and charts](results-and-charts.md) — filtering, export, charts
- [Troubleshooting](troubleshooting.md) — when something does not behave
Loading
Loading