Git-style version control for design files. DIT downloads your Figma designs as native .fig files, converts them to deterministic JSON for text-based diffs, and stores everything in a normal Git repository — enabling branching, merging, diffing, and full history for design work.
MVP scope: Figma integration only.
crates/
dit-core/ Rust core library (types, canonical JSON, assets, git, fig2json)
dit-cli/ CLI tool ("dit")
dit-gui/ Desktop GUI (Tauri 2 + React)
scripts/
download-fig.mjs Playwright-based .fig file downloader
- Rust (1.75+): https://rustup.rs
- Node.js (20+): for the GUI frontend and Playwright downloader
- Playwright Chromium: installed automatically via
npx playwright install chromium - Figma account: with either:
- Browser auth cookie (
__Host-figma.authn), or - Email and password (2FA supported — DIT will prompt for the code)
- Browser auth cookie (
# Build all Rust crates (core, CLI, GUI backend)
cargo build --workspace
# Run tests
cargo test --workspace
# Build the CLI in release mode
cargo build -p dit-cli --release
# Binary at: target/release/dit
# Install Playwright dependencies
cd scripts && npm install && npx playwright install chromium && cd ..cd crates/dit-gui/frontend
npm install
cd ../../..
cargo build -p dit-guiTo run the GUI in development mode (requires Tauri CLI):
cargo install tauri-cli
cd crates/dit-gui
cargo tauri dev# Start fresh
mkdir my-design && cd my-design
dit init
# Or clone an existing DIT/git repo
dit clone git@github.com:team/design-repo.git
dit clone https://github.com/team/design-repo.gitFor dit init, DIT will prompt you to:
- Select your design platform (Figma)
- Choose auth method: browser cookie or email/password
- Enter the file key (from the Figma file URL:
figma.com/design/<FILE_KEY>/...)
For dit clone, if the URL is SSH, DIT will let you pick an SSH key from ~/.ssh/. If the cloned repo is already a DIT repo, it opens directly (prompting for Figma credentials if missing). If it's a plain git repo, DIT runs the init flow.
Your credentials are saved to .env (git-ignored).
dit commit -m "Initial design snapshot"This uses Playwright to download the .fig file from Figma, converts it to deterministic JSON via fig2json, and commits both the JSON and the .fig file to Git. The .fig file is stored in dit.fig/ so that cloning the repo gives you full restore capability.
dit branch feature/new-header # Create a branch
dit checkout feature/new-header # Switch to it
# Make changes in Figma, then:
dit commit -m "Redesigned header"
dit checkout main # Switch back
~~dit merge feature/new-header # Merge the branch~~dit log # Show commit history
dit status # Show current branch and changes
dit branch # List all branchesdit log # Find the commit hash
dit restore <commit-hash> # Restore that versionDIT will show you the path to the .fig file for that commit. Open it in Figma to restore the design — that's it.
# Add a remote (standard git)
git remote add origin <url>
dit push # Push to remote
dit pull # Pull from remoteBoth the canonical JSON and .fig snapshot files are pushed and pulled. After cloning or pulling, you can restore any commit's .fig file directly — no re-download needed.
| Command | Description |
|---|---|
dit clone <url> [path] |
Clone a git repo (initializes DIT if needed) |
dit init |
Initialize a new DIT repository |
dit status |
Show branch and change status |
dit commit -m "msg" |
Download .fig, convert to JSON, commit |
dit log [-n N] |
Show commit history |
dit branch [name] |
List branches or create a new one |
dit checkout <ref> |
Switch to a branch or commit |
dit merge <branch> |
|
dit restore <commit> |
Get .fig file path for a commit |
dit push [remote] |
Push to remote repository |
dit pull [remote] |
Pull from remote repository |
dit diff <c1> <c2> |
Compare two commits |
my-design/
dit.json Project metadata
dit.pages/ One JSON file per page (from fig2json)
0_1.json
0_2.json
dit.styles.json Shared style definitions
dit.components.json Component & component set metadata
dit.assets/ Content-addressed binary assets
sha256_<hash>
dit.fig/ .fig file snapshots (committed to git)
latest.fig Current commit's .fig file
<hash>.fig Previous commits' .fig files
dit.previews/ Preview screenshots (committed to git)
latest.png Current commit's preview
<hash>.png Previous commits' previews
.dit/ Internal metadata (git-ignored)
config.json DIT configuration (bootstrapped from dit.json on clone)
fig_snapshots/ Local .fig cache for fast restore
<hash>.fig
.env Figma credentials (git-ignored)
.gitignore
All dit.* files are deterministic canonical JSON — sorted keys, stable float precision, 2-space indent. This means git diff produces clean, meaningful diffs of design changes.
-
Commit: DIT uses Playwright to download the native
.figfile from Figma, then usesfig2jsonto convert it to canonical JSON. Both the JSON and the.figfile are committed to Git, so every commit carries a full lossless snapshot that can be restored from any clone. -
Restore: DIT locates the
.figfile for the target commit and presents it to the user. Open the.figfile in Figma to restore the design in two clicks. -
Merge: Merging happens on the JSON text layer using standard Git merge. After merge, DIT shows available(Merge is not available in MVP due to complexity.).figfiles from both branches as starting points. The user opens one in Figma, adjusts to match the merged state, and commits. See docs/merge-strategy.md for details. -
Lossless guarantee: The
.figfile is Figma's native format — it contains the complete design state with zero loss. The JSON layer provides human-readable diffs and Git-compatible merging.
DIT uses Playwright to automate .fig file downloads from Figma. Two auth methods are supported:
Cookie-based (recommended):
- Log in to Figma in your browser
- Open DevTools → Application → Cookies →
www.figma.com - Copy the value of
__Host-figma.authn - Provide it during
dit initor setFIGMA_AUTH_COOKIEin.env
Email/password:
- Provide during
dit init - Stored in
.envasFIGMA_EMAILandFIGMA_PASSWORD - 2FA is supported — DIT will prompt for the authentication code in the CLI or show an input dialog in the GUI
- fig2json — Rust crate for converting
.figfiles to JSON, which makes DIT's deterministic design diffing possible.
MIT
