Skip to content

Repository files navigation

DataLith

Datasets, structured. An open-source, local-first, single-application workspace for importing, exploring, cleaning, labeling, versioning, augmenting, and exporting AI datasets — without stitching together Roboflow, CVAT, Label Studio, FiftyOne, pandas, DVC, and a dozen bash scripts.

Built by ArminNX. Licensed under MIT — see LICENSE.

DataLith-image


Table of contents

  1. The problem
  2. What DataLith actually is
  3. Status at a glance
  4. Getting started
  5. Architecture
  6. The 15 modules
  7. Dataset Sourcing (Module 15)
  8. BYOK AI
  9. Desktop app (Tauri)
  10. PWA / offline
  11. Accessibility
  12. Roadmap: building the modules that need real infrastructure
  13. Contributing
  14. License

The problem

Training AI today means fighting a different tool at every stage:

Roboflow · CVAT · Label Studio · FiftyOne · pandas · Python scripts
FFmpeg · Hugging Face · DVC · Git · Bash scripts · Custom augmentation code

Every stage has its own tool, its own file formats, its own mental model. DataLith's goal is to unify the entire dataset workflow into one application — the Figma / Photoshop / VS Code of AI datasets — supporting every data type a real project touches: images, video, audio, text, PDFs, CSV, JSON, medical, 3D, point clouds, time series, and synthetic data.

The long-term goal is not to replace Label Studio or CVAT. The goal is to become the default operating system for AI data — the same way VS Code became the default editor for software.

What DataLith actually is

DataLith ships in two honest halves, and this README doesn't blur them:

  • What's real and running today — every module marked Available or BYOK AI below does exactly what it says, with no simulated output. Import really unzips your archive in-browser. Clean really runs a SHA-256 hash over every sample. Augment really pushes pixels through a live Canvas 2D pipeline. Nothing here is a mockup wired to fake data.
  • What's architected but not implemented — Training, Synthetic Data Generation, Model Evaluation, and the Marketplace need a real backend (compute, storage, moderation) that a browser tab fundamentally can't provide. Rather than fake those with placeholder buttons, they're left off — and the last major section below is a real technical guide to building them properly.

That distinction is the whole design philosophy. A dataset tool that lies about what it just did to your data is worse than no tool at all.

Status at a glance

# Module Status Notes
1 Universal Importer ✅ Available Drag/drop, folder picker, full client-side .zip extraction
2 Visual Dataset Explorer ✅ Available Search, filter, inspector panel
3 AI Dataset Understanding 🔷 BYOK AI Rule-based free; open-ended → your connected model
4 Automatic Cleaning ✅ Available Real SHA-256 dedupe, corrupt/empty detection, renaming
5 Dataset Version Control ✅ Available Linear commits, diffs, rollback (in-session)
6 AI-Assisted Labeling 🔷 BYOK AI Manual labeling free; AI-suggest needs a vision provider
7 Dataset Analytics ✅ Available Live stat cards + Chart.js visualizations
8 Visual Data Augmentation ✅ Available Real Canvas 2D pipeline: rotate, flip, brightness, contrast, blur, noise
9 Synthetic Data Generation 🛣️ Roadmap Needs a generative model backend
10 Training Integration 🛣️ Roadmap Needs a real compute backend / GPUs
11 Model Evaluation 🛣️ Roadmap Depends on #10 existing first
12 Dataset Marketplace 🛣️ Roadmap Needs hosted infrastructure + moderation
13 AI Dataset Agent 🔷 BYOK AI Same engine as #3
14 Visual Workflow Builder ✅ Available Chains the real steps above into a runnable pipeline
15 Dataset Sourcing 🔷 BYOK AI Real Wikipedia + Hugging Face fetches (web build); real arbitrary-URL scraping (desktop build); every candidate gated by review before it reaches the dataset

The in-app Roadmap page (/studio/roadmap) mirrors this table and will never drift from it — both are generated from the same src/lib/roadmap.ts.

Getting started

npm install
npm run dev       # http://localhost:3000
npm run build      # static export → out/
npm run lint

No environment variables, no server, no database. DataLith is 100% client-side — everything lives in memory for the tab's lifetime. Reload and you start fresh, on purpose (see Roadmap → persistence for how that changes going forward).

Architecture

src/
├── app/
│   ├── page.tsx                 # Landing page (vision, module grid, stack)
│   └── studio/
│       ├── layout.tsx           # Sidebar + Topbar shell
│       └── <module>/page.tsx    # One route per module
├── components/                  # Sidebar, Topbar, Mark, EmptyState, ToastHost…
└── lib/
    ├── types.ts                 # Sample, Commit, ScanResult, RoadmapEntry
    ├── store/
    │   ├── dataset.ts           # Zustand — THE single source of truth for samples
    │   ├── version.ts           # Zustand — commit history
    │   └── toast.ts             # Zustand — notifications
    ├── importer.ts              # Module 1 logic (JSZip)
    ├── clean.ts                 # Module 4 logic (SHA-256, decode checks)
    ├── exporter.ts               # Mirror of importer.ts
    ├── agent.ts                  # Module 3/13 rule engine + BYOK prompt builder
    ├── ai/providers.ts          # Module 3/6/13's BYOK layer (8 providers)
    ├── workflow.ts               # Module 14's runnable step registry
    └── roadmap.ts                 # Canonical module list (drives 2 UIs)

One discipline holds the whole app together: every module talks to the dataset only through useDatasetStore (Zustand). No module reaches into another module's state directly. That's what lets Explorer, Clean, Analytics, and the Agent all agree on "what a sample is" without knowing anything about each other — and it's exactly the seam a future persistence layer (see Roadmap) will slot into.

Stack, as actually built (per the original vision's "suggested stack"):

Layer Vision suggested What's here
Frontend React, Next.js, Tailwind CSS React 19, Next.js 16 (App Router), Tailwind CSS v4
Desktop Tauri Tauri 2 config scaffolded (src-tauri/)
State Zustand
Processing OpenCV, FFmpeg, Polars, Arrow Canvas 2D (Augment), JSZip (Import/Export), Chart.js (Analytics)
Plugin SDK Rust, Python, TypeScript Not yet — see Roadmap
Backend / ML workers Rust, Python, PyTorch, ONNX Not yet — see Roadmap
Vector DB Qdrant, LanceDB Not yet — see Roadmap

The 15 modules

Full per-module descriptions live in src/lib/roadmap.ts and render on both the landing page and /studio/roadmap. Short version:

  1. Import — drop files or a .zip; parsed entirely client-side.
  2. Explore — searchable/filterable grid with a live inspector.
  3. Understand — ask questions in plain English; rules answer instantly, an LLM answers the rest.
  4. Clean — real dedupe (SHA-256), corrupt/empty detection, filename normalization.
  5. Version — commit snapshots, see diffs, roll back.
  6. Label — manual classification, plus AI-suggest via your own vision model.
  7. Analytics — live stat cards and charts computed off the real dataset.
  8. Augment — a real Canvas 2D transform pipeline with a live preview.
  9. Syntheticroadmap, needs a generative backend.
  10. Trainroadmap, needs real compute.
  11. Evaluateroadmap, depends on Train.
  12. Marketplaceroadmap, needs hosting + moderation.
  13. Agent — the same rule/LLM engine as Understand, as a chat.
  14. Workflow — chain the real steps above and run them as a pipeline.
  15. Source — pull candidate content from a URL, Wikipedia, or a Hugging Face dataset; screen and (optionally) AI-curate every candidate; commit only what's approved. See Dataset Sourcing below.

Dataset Sourcing (Module 15)

Turning "research the internet" into a dataset without a human ever touching raw scraped junk is a two-part problem — getting the content, and deciding what's worth keeping — and this module keeps that split honest instead of blurring it into one "AI does everything" button.

Getting the content — three real, working sources:

  • Hugging Face (datasets-server.huggingface.co) — search the public dataset hub, pick a dataset, pull a page of rows. CORS-open, works directly from the web build.
  • Wikipedia (REST page/summary + article API) — search, fetch an article's full text. Also CORS-open, also works on the web build.
  • Any URL — the browser tries a direct fetch first (works for the minority of sites with permissive CORS), and on the desktop app, falls back to a native fetch via a #[tauri::command] in src-tauri/src/main.rs — a real Rust HTTP client has no CORS restriction, because CORS is a browser policy, not a network one. On the web build, if a site blocks direct requests, DataLith says so plainly and points you at the desktop app or the Paste text/HTML tab, rather than routing through a third-party CORS-relay that would just move the trust problem to someone else's server.

Deciding what's worth keeping — the AI review gate, before anything touches your dataset:

  1. Every fetched candidate lands in a separate review queue (src/lib/store/source.ts), not the dataset store. There's no code path that lets a fetch skip review.
  2. A free heuristic screen runs first — word count, boilerplate-line ratio, repetition — and rejects obvious junk (nav dumps, cookie notices, near-empty pages) at zero cost, same instinct as Clean's SHA-256 pass running before anything else touches a sample.
  3. With a BYOK provider connected, an optional AI review pass (src/lib/source/curate.ts) reads the raw text and returns approve/reject plus a cleaned version and a stated reason — capped at 15 candidates per click, same discipline as Label's AI-suggest.
  4. Every candidate — its raw text, curated text, verdict, and the AI's reason — stays visible and editable in the Source page. You can manually approve or reject anything regardless of what the AI said.
  5. Only clicking "Commit approved to dataset" calls useDatasetStore.add(). Nothing is silent, nothing is automatic.

This module has no server component of its own — Wikipedia/Hugging Face calls go straight from your tab to their APIs, and the desktop-only URL fetch goes straight from the Tauri process to the target site, the same local-first shape as everything else in DataLith.

BYOK AI

DataLith is local-first: there is no DataLith server, so there's nothing for a dataset — or an API key — to leak to. When you connect a provider in AI Settings, the key is written to your browser's localStorage only, and every request goes straight from your tab to that provider's own API.

Supported today: OpenAI, Anthropic, Google Gemini, Groq, OpenRouter, Mistral, DeepSeek, xAI (Grok). Vision-capable ones (used by Label's AI-suggest) are flagged in the AI Settings UI.

One honest caveat: a few providers don't send CORS headers permitting direct browser calls, precisely because a key sitting in browser JS is less protected than one behind your own server. Where that happens, DataLith surfaces the real error instead of hiding it — see fetchWithReason in src/lib/ai/providers.ts.

Desktop app (Tauri)

cd src-tauri
cargo tauri dev     # requires the Rust toolchain + Tauri CLI locally
cargo tauri build

next.config.ts is set to output: "export", so npm run build produces a static out/ directory that tauri.conf.json points to directly (frontendDist: "../out"). The Rust side (src-tauri/src/main.rs) stays minimal on purpose — almost all app logic lives in the frontend, exactly as it does on the web — but it's no longer a pure passthrough: it exposes one real native command, fetch_url, that Module 15 (Source) uses to fetch arbitrary URLs without the CORS restriction a browser tab is bound by (see Dataset Sourcing). That's the pattern for adding more native-only capability here — real filesystem access instead of the browser file picker, or a local SQLite-backed Version Control store, are natural next additions, each as its own #[tauri::command] function called from the frontend via @tauri-apps/api, same as fetch_url.

This repo doesn't include a compiled binary — building one requires the Rust toolchain, which isn't assumed to be on your machine. The config is real and will build as-is once you have cargo + the Tauri CLI installed.

PWA / offline

Install it like any PWA: open the deployed app, use your browser's "Install app" prompt. Once installed, the shell keeps opening (and the UI keeps working) even offline — your in-memory dataset for that session still won't survive a full reload, by the same design as the rest of the app (see Roadmap for persistence).

Accessibility

  • Skip-to-content link on every page.
  • Semantic landmarks: <nav aria-label="Studio modules">, aria-current="page" on the active route.
  • Toggle buttons expose aria-pressed (kind filters, class chips, flip controls).
  • The Agent's conversation is an aria-live="polite" log; the global toast is role="status".
  • All icon-only buttons and canvas previews carry aria-label; all inputs have associated <label> elements (visually hidden where the placeholder already communicates purpose).
  • Respects prefers-reduced-motion.
  • Not yet audited with a screen reader end-to-end — treat this as a strong baseline, not a certification.

Roadmap: building the modules that need real infrastructure

This is the part of the vision that a static, client-only app genuinely cannot deliver honestly. Here's what each one actually needs, concretely, if you want to build it next.

9 — Synthetic Data Generation

Needs: a generation backend (hosted diffusion/LLM API, or a self-hosted model server). How to slot it in: add a new file under src/lib/ (e.g. synthetic.ts) that calls out to a generation API the same way ai/providers.ts calls chat APIs — BYOK works here too (Stability, Replicate, fal.ai, or a local ComfyUI/Automatic1111 instance with CORS enabled). Output comes back as blobs → wrap them as Sample objects → useDatasetStore.add(). No architecture change needed; this is a new module using the existing seam.

10 — Training Integration

Needs: real compute — GPUs, a job runner, and a place for checkpoints to live. This is the one module that can't be BYOK'd from a static site the way chat APIs can, because training jobs run for minutes-to-hours, not milliseconds. How to build it:

  1. Stand up a minimal backend (FastAPI/Python is the natural fit given the vision's own suggested stack — PyTorch, HF Transformers, YOLO, Detectron2).
  2. Expose a job API: POST /train (dataset export + hyperparameters) → GET /train/:id (status/logs) → GET /train/:id/artifact (checkpoint).
  3. From DataLith, Export already produces a clean .zip + manifest.json — that's your training payload format for free.
  4. Poll job status into a new src/lib/training.ts + store/training.ts (same Zustand pattern as store/version.ts), and a /studio/train page that mirrors the DesignLanguage of /studio/workflow.
  5. For local-only training without a hosted backend, llama.cpp/MLX-style local inference servers with an HTTP API are a lighter-weight starting point than full training — worth doing before full training if you want an incremental win.

11 — Model Evaluation

Needs: #10 to exist first, since evaluation reads a trained model's outputs. Once you have a checkpoint, this becomes: run inference over a held -out split of the current dataset, diff predictions against sample.label, and surface per-class precision/recall the same way analytics/page.tsx already surfaces per-class counts — this module is mostly UI once the inference call exists.

12 — Dataset Marketplace

Needs: real backend infrastructure (auth, storage, a database, and — non-negotiably — moderation before anything about hosting user-uploaded datasets publicly). This is the module furthest from "just add a file" — treat it as its own project (a Next.js API layer + Postgres + object storage like S3/R2, likely deployed separately from the local-first studio) rather than something to bolt onto this client-only app.

Persistence, generally

Every module above — and honestly the whole app — currently resets on reload because there's no backend. The single highest-leverage next step, before any of #9–#12, is probably: give Version Control (Module 5) a real on-disk store. Two reasonable paths:

  • Browser-only: swap the in-memory Zustand store for IndexedDB (e.g. via idb or Dexie) so a reload doesn't lose your dataset. No backend needed, works on the web build as-is.
  • Desktop-only: now that Tauri is scaffolded, add #[tauri::command] functions backed by SQLite (rusqlite) for a real content-addressed commit store — the closest thing to "Git for datasets" the vision describes.

Contributing

Issues and PRs welcome. If you're picking up one of the roadmap modules above, please keep the project's one hard rule: never simulate output. If a feature needs infrastructure that isn't there yet, it stays off the roadmap-as-Available list until it's real.

License

MIT — see LICENSE. Copyright © ArminNX.

About

The open-source operating system for AI datasets — import, explore, clean, label, version, augment, and export all in one place.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages