Your project. Only what matters.
ProjectZipper

Your project, readyto share.

Selective packaging of code and assets, ready to send or to keep.

A Windows app that packages your projects: the code goes, the heavy stays out, and the report says what.Packs your projects: the code goes, the heavy stuff stays out.

Desktop appProject backupIn-house tool

  • Tauri 2
  • Rust
  • React 18.3
  • TypeScript 5.9
  • Vite 5.4
  • Tailwind CSS 3.4
  • Framer Motion 11
  • Crates zip 2 · walkdir 2
Your project. Only what matters.
ProjectZipper

Your project, readyto share.

Selective packaging of code and assets, ready to send or to keep.

A Windows app that packages your projects: the code goes, the heavy stays out, and the report says what.Packs your projects: the code goes, the heavy stuff stays out.

Desktop appProject backupIn-house tool

  • Tauri 2
  • Rust
  • React 18.3
  • TypeScript 5.9
  • Vite 5.4
  • Tailwind CSS 3.4
  • Framer Motion 11
  • Crates zip 2 · walkdir 2

The weight

The heavy stays out. The code goes.

Before compressing, the app shows the project the way it weighs on disk: every folder with its size and file count. Here, the largest folders of a real Tauri project, as the app's preview showed them.

A real Tauri projectChecked: 682 of 750 filesLeft out: 55 items

src-tauri/56.26 MB · 108 files
7-noites-na-cabana/55.6 MB · 67 filesUnchecked by the owner: stays out
src/11.12 MB · 432 files
src-tauri/target/Not walkedRegenerable, not needed in the backup. The app doesn't even enter the folder; its size is measured only if you ask.
  • Checked
  • Unchecked
  • Not walked
  1. 01The whole tree, with the size of every folder.
  2. 02The target/ folder isn't even walked: it's one of the 35 heavy folders the app knows.
  3. 03The unchecked folder zips shut and stays out.
  4. 04What stays checked is what goes into the package.

The tool's own output folders stay out too: in one project, 57,162 of 57,790 paths (98.91%) were old backups. The actual project had 628.

The preview

Check, uncheck. See the weight first.

Every folder and every file has its own box. The parent folder turns partial (—) when only some of its children go, and the package estimate updates on every click. Click to try it.

Package estimate

14.98 MB491 files

Out of 65.94 MB · 508 files

With the folders from the app's preview. In the app, the count walks the whole project without compressing anything.

  • Three statesChecked, unchecked or partial: the folder shows what its children decided.
  • An estimate without compressingThe app walks the project with the same filters as the backup and returns size and count, writing nothing.
  • No pile-upsThe count runs 700 ms after the last click, and any older answer is thrown away.
  • What's new shows upAnything that wasn't there at the last saved settings gets a NEW badge in the tree.
ProjectZipper with the backup progress window open and the console listing the files

You decide what goes in the ZIP.

Code, assets and heavy files, organized with judgment.

Selection by file and folderSummary of regenerable foldersAssets in separate packagesAlerts for sensitive files.

To send a large project, the app splits it: the code in one ZIP and the assets in packages of the size you choose (1 to 500 MB; the default is 29), or the whole project in parts. The split is a First-Fit-Decreasing: it sorts from largest to smallest and drops each file into the first box it fits.

The code goes to -code.zip; the assets in public/ go to -assets-01.zip, -assets-02.zip… stored without compression, because images and video come compressed already.

Queue sorted, largest first

    1. { }
      projeto-code.zip
    2. Limit − 1%
      .mp4
      projeto-assets-01.zipLarger than the limit: goes alone, with a warning
    3. Limit − 1%
      .mp4.psd
      projeto-assets-02.zip
    4. Limit − 1%
      .png.glb.png
      projeto-assets-03.zip
    5. Limit − 1%
      .jpg.webp.svg
      projeto-assets-04.zip
    • A box fills up to 99% of the limit: 1% is left as headroom.
    • A file larger than the limit gets a package of its own, with a warning.
    • Every part opens on its own: they're independent ZIPs, not a sliced ZIP (.z01, .z02).

    The sensitive ones

    Keys, .env, credentials: the app points out each one.

    Before the ZIP leaves the machine, the rule runs over every name. Anything that looks like a credential is listed at the end of the backup and counted in the report, and whether it goes is your call, with a switch.

    • package.json
    • src/App.tsx
    • .env.localGoes in
    • tailwind.config.js
    • id_rsaGoes in
    • README.md
    • vite.config.ts
    • credentials.jsonGoes in
    • Cargo.toml
    • src-tauri/tauri.conf.json
    • certificado.pemGoes in
    • index.html
    • .npmrcGoes in
    • public/logo.png
    • .aws/configGoes in
    • src-tauri/src/main.rs
    • .env.productionGoes in
    • tsconfig.json
    • 17Exact names.npmrc · .netrc · id_rsa · credentials.json · secrets.json · terraform.tfvars…
    • 9Extensions.pem · .key · .p12 · .pfx · .jks · .keystore · .ppk · .asc · .gpg
    • 5Credential folders.aws · .ssh · .gnupg · .docker · .kube
    • .env*Every name that starts with .env.env · .env.local · .env.production…
      Sensíveis .....: 7 arquivo(s) (.env, chaves, credenciais), ESTÃO no backup

    The match ignores case and looks at the whole path: a file inside .ssh/ counts, whatever its name.

    The report

    Inside every ZIP, a map of what's there.

    Every backup carries an ESTRUTURA.txt (structure) at its root: the project's whole tree, with size and date on each line, and a mark on what was left out and why. Whoever opens the package knows what's missing before looking for it.

    ROBLOX-APP-ASSETS-ESTRUTURA.txt
    ══════════════════════════════════════════════════════════
    ESTRUTURA COMPLETA · ROBLOX-APP-ASSETS
    ══════════════════════════════════════════════════════════
    Caminho .......: D:\Projetos\ROBLOX-APP-ASSETS
    Gerado em .....: 19/09/2026 às 12:58
    Arquivos ......: …
    Modo ..........: pastas regeneráveis RESUMIDAS
    Fora do pacote : … item(ns), marcados com [FORA] abaixo
    ══════════════════════════════════════════════════════════
    POR EXTENSÃO (as 20 que mais pesam)
    …
    ══════════════════════════════════════════════════════════
    LEGENDA
    [FORA: motivo] o arquivo existe no disco mas não entrou no backup
    [RESUMIDA] pasta regenerável mostrada só com o total
    ══════════════════════════════════════════════════════════
     
    ROBLOX-APP-ASSETS/
    ├── src-tauri/ 56.26 MB 03/09/2026 12:16
    │ ├── binaries/ 50.96 MB 08/07/2026 15:37
    │ ├── icons/ 2.44 MB 03/09/2026 12:16
    │ ├── target/ … arq · … [RESUMIDA]
    │ └── Cargo.lock 142 KB 03/09/2026 12:16
    ├── 7-noites-na-cabana/ 55.6 MB 03/06/2026 09:44
    │ └── BIBLIA_VISUAL/ 55.6 MB 02/06/2026 23:22
    └── src/ 11.12 MB 19/09/2026 11:06
    ├── data/ 6.14 MB 18/09/2026 20:20
    └── components/ 2.62 MB 19/09/2026 12:35
    1. 1The headerPath, date, file count, the mode and how many items were left out: the summary before the tree.
    2. 2By extensionThe 20 heaviest extensions, with count and size. Every .env.local or .env.production counts as .env, so you see at a glance how many there are.
    3. 3The legendTwo marks: [FORA: motivo] (out: reason), for what exists on disk and didn't go in, and [RESUMIDA] (summarized), for a regenerable folder.
    4. 4Size and date on every lineThe column has a fixed width: a summarized folder, which carries its count, doesn't push the date sideways.
    5. 5Regenerable on a single lineFolders like target, node_modules, .venv and 17 more names become one line with the total of files and bytes.

    The same file is also saved at the project root on every backup, and the Export Structure button writes just that. An excerpt in the app's format (the app writes it in Portuguese), with the preview's folders; the ellipses mark what was cut.

    Under the hood

    Rust where it's heavy, measured where it matters.

    The heavy work runs in Rust, off the UI thread; the React interface only asks and shows. The measurements below sit in the code comments, next to the change each one justified.

    The decision

    One rule for all three paths

    119 MBEstimated on screen

    500 MBIn the actual ZIP

    The rule for what goes into the package lived in three copies: in the full backup, in the split backup and in the estimate. The copies drifted apart. Today all three call the same two functions, and changing a filter changes it in all three.

    passa_pre_filtros() · motivo_para_ficar_de_fora()

    12commands

    Between the UI and Rust

    The 7 heaviest run on a separate thread (spawn_blocking): the window never freezes.

    64KiB

    Block by block

    Each file goes into the ZIP in 64 KiB blocks, never loaded whole into memory. Deflate level 3; 30 already-compressed formats go in without recompression.

    868,500calls

    To the disk, saved

    On a tree of 6,081 folders: sorting by the type the system already returns, instead of asking the disk on every comparison.

    127ms

    To write the structure

    It took 1,208 ms on the same tree (51,709 files): the tool's own output is now summarized, with the same count.

    The technologies

    What it is made of, piece by piece

    A Windows program that picks what goes into the package and what stays out. The window is built like a website; Rust walks the folders and builds the .zip. Pick a piece to see what it does here and which file it is in.

    14technologies, in 3 layers

    Screen

    Core

    Windows

    The screens

    The app, from project to package.

    From the project list to the finished backup, with the settings saved inside the project itself.